001 /*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016 package org.opengion.fukurou.process;
017
018 import org.opengion.fukurou.util.Argument;
019 import org.opengion.fukurou.util.HybsEntry ;
020 import org.opengion.fukurou.xml.XSLT;
021 import org.opengion.fukurou.util.LogWriter;
022
023 import java.util.Map ;
024 import java.util.LinkedHashMap ;
025 import java.io.File;
026
027 /**
028 * XSLT変換結果を指定ã?ファイルに出力しますã?
029 *
030 * Process_XSLT は、AbstractProcess を継承した、ChainProcess インターフェース
031 * の実è£?‚¯ラスですã?
032 * 上æµ?プロセスチェインのãƒ??タは上流から渡されますã?)からのLineModel の
033 * ファイルオブジェクトに対して、指定ã? XSL ファイルを適用して、XSL変換を行いますã?
034 * 出力結果は、ファイル、またã? 標準å?力に出力できますã?
035 *
036 * 上流ã?ロセスでは、Name 属æ?として、ã?File』を持ち、å?は、Fileオブジェクãƒ?
037 * である、Process_FileSearch を使用するのがã?便利ですã?それ以外ã?クラスã‚?
038 * 使用する場合でもã?Name属æ?と、File オブジェクトを持つ LineModel を受け渡ã�?
039 * できれば、使用可能ですã?
040 *
041 * -param_XXXX=固定å? を使用して、XSLTにパラメータを設定できますã?
042 *
043 * それ以外では、org.opengion.fukurou.xml.XSLT で、å?力ファイルæƒ??の設定が可能に
044 * なってã�?‚‹為、å?部æƒ??を使用するかどã�?�‹ -useFileInfo を指定できますã?
045 * -useFileInfo=true とセãƒ?ƒˆすると、以下ã??”é?目がå?部çš?�«セãƒ?ƒˆされますã?
046 *
047 * 入力ファイル(inXMLのフルパス) : FILEPATH (ä¾? G:\webapps\gf\jsp\DOC10\query.jsp)
048 * 入力親フォルãƒ?inXMLの親フォルãƒ? : ADDRESS (ä¾? DOC10)
049 * 入力ファイル(inXMLのファイルå�? : FILENAME (ä¾? query.jsp)
050 * 入力ファイル(inXMLの更新日ä»? ) : MODIFIED (ä¾? yyyyMMddHHmmss形å¼?
051 *
052 * xsl ファイルでは、xsl:param で宣è¨?�—、xsl:value-of で取り出しますã?
053 * <xsl:param name="ADDRESS" select="" /> と宣è¨?�—ておき、å¿?¦�なç®?‰€で
054 * <xsl:value-of select="$ADDRESS" /> とすれば、取得できますã?
055 *
056 * 引数æ–?—å?中にスペã?スを含ã‚??合ã?、ダブルコーãƒ??ション("") で括って下さã�??
057 * 引数æ–?—å?の ã€?』ã?前後には、スペã?スは挟めません。å¿?�šã€?key=value の様に
058 * 繋げてくださいã€?
059 *
060 * @og.formSample
061 * Process_XSLT -xslfile=xslファイル -outfile=OUTFILE -append=true
062 *
063 * -xslfile=xslファイル ?š変換を行う XSLファイル
064 * [-outfile=出力ファイルå�? ] ?š変換結果の出力ファイルå�?
065 * [-append=[false/true] ] ?šå?力ファイルをã?追記すã‚?true)か新規作æ?する(false)ã�?
066 * [-useFileInfo=[false/true] ] ?šå?力ファイルæƒ??をã?XSLTのパラメータにセãƒ?ƒˆする(true)かしなã�?�‹(false)ã�?
067 * [-addROWSET=ãƒ??ブルå�? ] ?šã?ãƒ?ƒ€ー/フッターに ROWSET を追記しますã?
068 * [-headerXX=ヘッãƒ??æ–?—å? ] ?šå?力ファイルに、ã?ãƒ?ƒ€ーæ–?—å?を追記しますã?
069 * 添えå?XX)が異なれã?è¤?•°のヘッãƒ??が指定できますã?
070 * [-footerXX=フッターæ–?—å? ] ?šå?力ファイルに、フãƒ?‚¿ーæ–?—å?を追記しますã?
071 * 添えå?XX)が異なれã?è¤?•°のフッターが指定できますã?
072 * [-param_XXXX=固定å? ] ??param_SYSTEM_ID=GE
073 * XSLパã?サーに対して、paramater を設定しますã?
074 * キーが異なれã?、è¤?•°のパラメータを指定できますã?
075 * [ -errAbend=[true/false] ] ?š異常発生時に、å?ç�?‚’中断(true)するかã?継ç¶?false)するかをæŒ?®šすã‚?初期値:true[中断する])
076 * [ -errXmlIn=[false/true] ] ?š異常発生時に、å?力ファイルに、XML形式でエラーを追記するかを指定すã‚?初期値:false[使用しない])
077 * [ -jspInclude=[true/false] ] ?šjsp:directive.include 発見時に、そのファイルã‚?INCLUDE するかをæŒ?®šすã‚?初期値:true[使用する])
078 * [ -realPath=実際の実行環å¢?] ?šjspInclude="true" 時にã€?jsp/common/以下ã?ファイルの取得å?を指定しまã�?初期値:null)
079 * [ -display=[false/true] ] ?š結果を標準å?力に表示する(true)かしなã�?false)ã�?初期値:false[表示しない])
080 * [ -debug=[false/true] ] ?šデバッグæƒ??を標準å?力に表示する(true)かしなã�?false)ã�?初期値:false[表示しない])
081 *
082 * @version 4.0
083 * @author Kazuhiko Hasegawa
084 * @since JDK5.0,
085 */
086 public class Process_XSLT extends AbstractProcess implements ChainProcess {
087 private static final String PARAM_KEY = "param_" ;
088 private static final String HEADER_KEY = "header" ;
089 private static final String FOOTER_KEY = "footer" ;
090 private static final String FILE_KEY = "File";
091
092 private static final String HEADER_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" ;
093 private static final String HEADER_ROWSET = "<ROWSET tableName=\"TABLENAME\">" ;
094 private static final String FOOTER_ROWSET = "</ROWSET>" ;
095
096 private XSLT xslt = null ;
097 private HybsEntry[] footerEntry = null;
098 private String xslfile = null ;
099 private String outfile = null ;
100 private boolean errAbend = true; // 中断する
101 private boolean errXmlIn = false; // エラーXML形å¼?
102 private boolean jspInclude = true; // 4.2.3.0 (2008/05/26)
103 private String realPath = null ; // 5.7.6.2 (2014/05/16) 追åŠ?
104 private boolean display = false; // 表示しなã�?
105 private boolean debug = false; // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
106
107 private int clmNo = -1;
108 private int inCount = 0;
109 private int errCount = 0;
110 private String tableName = null;
111
112 private static final Map<String,String> mustProparty ; // ?»プロパティ?½å¿??チェãƒ?‚¯用 Map
113 private static final Map<String,String> usableProparty ; // ?»プロパティ?½整合æ?チェãƒ?‚¯ Map
114
115 static {
116 mustProparty = new LinkedHashMap<String,String>();
117 mustProparty.put( "xslfile", "変換を行う XSLファイル(å¿??)" );
118
119 usableProparty = new LinkedHashMap<String,String>();
120 usableProparty.put( "outfile", "変換結果の出力ファイルå�? );
121 usableProparty.put( "append", "出力ファイルをã?追記すã‚?true)か新規作æ?する(false)ã�? );
122 usableProparty.put( "useFileInfo", "入力ファイルæƒ??をã?XSLTのパラメータにセãƒ?ƒˆする(true)かしなã�?�‹(false)ã�? );
123 usableProparty.put( "addROWSET" , "ヘッãƒ??/フッターに ROWSET を追記しますã?");
124 usableProparty.put( "header", "出力ファイルに、ã?ãƒ?ƒ€ーæ–?—å?を追記しますã?" +
125 CR + "添えå?XX)が異なれã?è¤?•°のヘッãƒ??が指定できますã?" );
126 usableProparty.put( "footer", "出力ファイルに、フãƒ?‚¿ーæ–?—å?を追記しますã?" +
127 CR + "添えå?XX)が異なれã?è¤?•°のヘッãƒ??が指定できますã?" );
128 usableProparty.put( "param_", "XSLパã?サーに対して、paramater を設定しますã?" +
129 CR + "キーが異なれã?、è¤?•°のパラメータを指定できますã?" +
130 CR + "ä¾? -param_SYSTEM_ID=GE" );
131 usableProparty.put( "errAbend", "異常発生時に、å?ç�?‚’中断(true)するかã?継ç¶?false)するã�? +
132 CR + "(初期値:true:中断する)" );
133 usableProparty.put( "errXmlIn", "異常発生時に、å?力ファイルに、XML形式でエラーを追記するかを指定すã‚? +
134 CR + "(初期値:false:使用しなã�?" );
135 usableProparty.put( "jspInclude","jsp:directive.include 発見時に、そのファイルã‚?INCLUDE するかをæŒ?®šすã‚? +
136 CR + "(初期値:true:使用する)" );
137 usableProparty.put( "realPath","jspInclude=\"true\" 時にã€?jsp/common/以下ã?ファイルの取得å?を指定しますã?" +
138 CR + "(初期値:null)" ); // 5.7.6.2 (2014/05/16) 追åŠ?
139 usableProparty.put( "display", "結果を標準å?力に表示する(true)かしなã�?false)ã�? +
140 CR + "(初期値:false:表示しなã�?" );
141 usableProparty.put( "debug", "ãƒ?ƒ�ãƒ?‚°æƒ??を標準å?力に表示する(true)かしなã�?false)ã�? +
142 CR + "(初期値:false:表示しなã�?" ); // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
143 }
144
145 /**
146 * ãƒ?ƒ•ォルトコンストラクターã€?
147 * こã?クラスは、動çš?½œæ?されますã?ãƒ?ƒ•ォルトコンストラクターでã€?
148 * super クラスに対して、å¿?¦�な初期化を行っておきますã?
149 *
150 */
151 public Process_XSLT() {
152 super( "org.opengion.fukurou.process.Process_XSLT",mustProparty,usableProparty );
153 }
154
155 /**
156 * プロセスの初期化を行いますã?初めにä¸?º¦ã�?�‘、呼び出されますã?
157 * 初期処ç�?ファイルオープンã€?¼¤?¢オープンç?に使用しますã?
158 *
159 * @og.rev 4.2.3.0 (2008/05/26) jsp:directive.include 処ç�??実施可否を引数æŒ?®šしますã?
160 * @og.rev 5.7.6.2 (2014/05/16) realPath 引数を追åŠ?�—ますã?
161 *
162 * @param paramProcess ãƒ??タベã?スの接続å?æƒ??などを持ってã�?‚‹オブジェクãƒ?
163 */
164 public void init( final ParamProcess paramProcess ) {
165 Argument arg = getArgument();
166
167 xslfile = arg.getProparty( "xslfile" );
168 outfile = arg.getProparty( "outfile" );
169 tableName = arg.getProparty( "addROWSET" );
170 boolean isAppend = arg.getProparty( "append",false );
171 boolean useFileInfo = arg.getProparty( "useFileInfo",false );
172 HybsEntry[] paramEntry = arg.getEntrys( PARAM_KEY ); // 配å?
173 HybsEntry[] headerEntry = arg.getEntrys( HEADER_KEY ); // 配å?
174 footerEntry = arg.getEntrys( FOOTER_KEY ); // 配å?
175 errAbend = arg.getProparty("errAbend",errAbend);
176 errXmlIn = arg.getProparty("errXmlIn",errXmlIn);
177 jspInclude = arg.getProparty("jspInclude",jspInclude); // 4.2.3.0 (2008/05/26) 追åŠ?
178 realPath = arg.getProparty("realPath" ,realPath); // 5.7.6.2 (2014/05/16) 追åŠ?
179 display = arg.getProparty("display",display);
180 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
181
182 if( outfile != null ) {
183 File file = new File( outfile ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
184 File dir = file.getParentFile() ;
185
186 // 親ãƒ?‚£レクトリを示さなã�??合ã? null 。ディレクトリが存在しなã�??かつ、ディレクトリが作æ?できなã�??合ã?処ç�?
187 if( dir != null && ! dir.exists() && ! dir.mkdirs() ) {
188 String errMsg = "ãƒ?‚£レクトリが作æ?できませんでしたã€?" + dir + "]" ;
189 throw new RuntimeException( errMsg );
190 }
191 }
192 else {
193 // 出力å?ファイル名が、指定されてã�?�ªã�??å�?
194 String errMsg = "outfile が指定されてã�?�¾せんã€?;
195 throw new RuntimeException( errMsg );
196 }
197
198 xslt = new XSLT();
199
200 xslt.setOutFile( outfile,isAppend );
201 xslt.setXslFile( xslfile );
202 xslt.setParamEntry( paramEntry );
203 xslt.useFileInfo( useFileInfo );
204 xslt.errClose( errAbend ); // エラー時に出力ファイルを閉じるかどã�?�‹ã€?
205 xslt.useErrXmlIn( errXmlIn ); // エラー時にXML形式で出力ファイルに追記するかどã�?�‹ã€?
206 xslt.jspInclude( jspInclude ); // 4.2.3.0 (2008/05/26) jsp:directive.include するかどã�?�‹
207 xslt.setRealPath( realPath ); // 5.7.6.2 (2014/05/16) realPath 引数を追åŠ?�—ますã?
208
209 if( tableName != null ) {
210 xslt.setOutData( HEADER_XML );
211 xslt.setOutData( HEADER_ROWSET.replace( "TABLENAME",tableName ) );
212 }
213
214 int size = headerEntry.length;
215 for( int i=0; i<size; i++ ) {
216 xslt.setOutData( headerEntry[i].getValue() );
217 }
218 }
219
220 /**
221 * 引数の LineModel をå?ç�?�™るメソãƒ?ƒ‰ですã?
222 * 変換処ç�?¾Œã? LineModel を返しますã?
223 * 後続å?ç�?‚’行わなã�??å�?ãƒ??タのフィルタリングを行う場å�?はã€?
224 * null ãƒ??タを返しますã?つまりã?null ãƒ??タは、後続å?ç�?‚’行わなã�?
225 * フラグの代わりにも使用してã�?�¾すã?
226 * なおã?変換処ç�?¾Œã? LineModel と、オリジナルの LineModel がã?
227 * 同ä¸?�‹、コピã?(クローン)かã?、各処ç�?ƒ¡ソãƒ?ƒ‰å†?�§決めてã�?�¾すã?
228 * ドキュメントに明記されてã�?�ªã�??合ã?、副作用が問題になるå?合ã?ã€?
229 * å�??ç�?�”とに自åˆ?�§コピã?(クローン)して下さã�??
230 *
231 * @param data オリジナルのLineModel
232 *
233 * @return 処ç�?¤‰換後ã?LineModel
234 */
235 public LineModel action( final LineModel data ) {
236 inCount++ ;
237 if( display ) { println( data.dataLine() ); }
238 if( clmNo < 0 ) { clmNo = data.getColumnNo( FILE_KEY ); }
239 File file = (File)data.getValue( clmNo );
240
241 if( ! file.isFile() ) { return data; }
242
243 String filePath = file.getPath();
244
245 try {
246 if( debug ) { println( filePath ); } // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
247 xslt.transform( filePath );
248 }
249 catch( RuntimeException ex ) {
250 errCount++ ;
251 if( errAbend ) { throw ex; }
252 else {
253 logging( ex.getMessage() );
254 logging( "xslfile = " + xslfile );
255 logging( "outfile = " + outfile );
256 logging( "xmlFile = " + filePath );
257 }
258 }
259
260 return data ;
261 }
262
263 /**
264 * プロセスの終äº?‚’行いますã?æœ?¾Œにä¸?º¦ã�?�‘、呼び出されますã?
265 * 終äº??ç�?ファイルクローズã€?¼¤?¢クローズç?に使用しますã?
266 *
267 * @param isOK トã?タルで、OKã�?�£たかどã�?�‹[true:成功/false:失敗]
268 */
269 public void end( final boolean isOK ) {
270 if( xslt != null ) {
271 if( isOK ) {
272 int size = footerEntry.length;
273 for( int i=0; i<size; i++ ) {
274 xslt.setOutData( footerEntry[i].getValue() );
275 }
276 if( tableName != null ) {
277 xslt.setOutData( FOOTER_ROWSET );
278 }
279 }
280 xslt.close();
281 }
282 }
283
284 /**
285 * プロセスの処ç�?µ�果のレポã?ト表現を返しますã?
286 * 処ç�??ログラãƒ?��、å?力件数、å?力件数などのæƒ??ですã?
287 * こã?æ–?—å?をそのまま、標準å?力に出すことで、結果レポã?トと出来るよã�?�ª
288 * 形式で出してくださいã€?
289 *
290 * @return 処ç�?µ�果のレポã?ãƒ?
291 */
292 public String report() {
293 String report = "[" + getClass().getName() + "]" + CR
294 + TAB + "XSL File : " + xslfile + CR
295 + TAB + "OUT File : " + outfile + CR
296 + TAB + "Table Name : " + tableName + CR
297 + TAB + "File Count : " + inCount + CR
298 + TAB + "Err Count : " + errCount ;
299
300 return report ;
301 }
302
303 /**
304 * こã?クラスの使用方法を返しますã?
305 *
306 * @return こã?クラスの使用方æ³?
307 */
308 public String usage() {
309 StringBuilder buf = new StringBuilder();
310
311 buf.append( "XSLT変換結果を指定ã?ファイルに出力しますã?" ).append( CR );
312 buf.append( CR );
313 buf.append( "Process_XSLT は、AbstractProcess を継承した、ChainProcess インターフェース" ).append( CR );
314 buf.append( "の実è£?‚¯ラスですã?" ).append( CR );
315 buf.append( "上æµ?プロセスチェインのãƒ??タは上流から渡されますã?)からのLineModel の" ).append( CR );
316 buf.append( "ファイルオブジェクトに対して、指定ã? XSL ファイルを適用して、XSL変換ã‚? ).append( CR );
317 buf.append( "行いますã?出力結果は、ファイル、またã? 標準å?力に出力できますã?" ).append( CR );
318 buf.append( CR );
319 buf.append( "上流ã?ロセスでは、Name 属æ?として、ã?File』を持ち、å?は、Fileオブジェクãƒ? ).append( CR );
320 buf.append( "である、Process_FileSearch を使用するのがã?便利ですã?それ以外ã?クラスã‚? ).append( CR );
321 buf.append( "使用する場合でもã?Name属æ?と、File オブジェクトを持つ LineModel を受け渡ã�? ).append( CR );
322 buf.append( "できれば、使用可能ですã?" ).append( CR );
323 buf.append( CR );
324 buf.append( "-param_XXXX=固定å? を使用して、XSLTにパラメータを設定できますã?" ).append( CR );
325 buf.append( CR );
326 buf.append( "それ以外では、org.opengion.fukurou.xml.XSLT で、å?力ファイルæƒ??の設定が可能に" ).append( CR );
327 buf.append( "なってã�?‚‹為、å?部æƒ??を使用するかどã�?�‹ -useFileInfo を指定できますã?" ).append( CR );
328 buf.append( "-useFileInfo=true とセãƒ?ƒˆすると、以下ã??”é?目がå?部çš?�«セãƒ?ƒˆされますã?" ).append( CR );
329 buf.append( CR );
330 buf.append( "入力ファイル(inXMLのフルパス) : FILEPATH (ä¾? G:/temp/DOC10/query.jsp)" ).append( CR );
331 buf.append( "入力親フォルãƒ?inXMLの親フォルãƒ? : ADDRESS (ä¾? DOC10)" ).append( CR );
332 buf.append( "入力ファイル(inXMLのファイルå�? : FILENAME (ä¾? query.jsp)" ).append( CR );
333 buf.append( "入力ファイル(inXMLの更新日ä»? ) : MODIFIED (ä¾? yyyyMMddHHmmss形å¼?" ).append( CR );
334 buf.append( CR );
335 buf.append( "xsl ファイルでは、xsl:param で宣è¨?�—、xsl:value-of で取り出しますã?" ).append( CR );
336 buf.append( "<xsl:param name=\"ADDRESS\" select=\"\" /> と宣è¨?�—ておき、å¿?¦�なç®?‰€で" ).append( CR );
337 buf.append( "<xsl:value-of select=\"$ADDRESS\" /> とすれば、取得できますã?" ).append( CR );
338 buf.append( CR );
339 buf.append( "引数æ–?—å?中に空白を含ã‚??合ã?、ダブルコーãƒ??ション(\"\") で括って下さã�??" ).append( CR );
340 buf.append( "引数æ–?—å?の ã€?』ã?前後には、空白は挟めません。å¿?�šã€?key=value の様に" ).append( CR );
341 buf.append( "繋げてくださいã€? ).append( CR );
342 buf.append( CR ).append( CR );
343
344 buf.append( getArgument().usage() ).append( CR );
345
346 return buf.toString();
347 }
348
349 /**
350 * こã?クラスは、main メソãƒ?ƒ‰から実行できませんã€?
351 *
352 * @param args コマンド引数配å?
353 */
354 public static void main( final String[] args ) {
355 LogWriter.log( new Process_XSLT().usage() );
356 }
357 }