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 * [ -display=false|true ] ?š結果を標準å?力に表示する(true)かしなã�?false)ã�?初期値:false[表示しない])
079 *
080 * @version 4.0
081 * @author Kazuhiko Hasegawa
082 * @since JDK5.0,
083 */
084 public class Process_XSLT extends AbstractProcess implements ChainProcess {
085 private static final String PARAM_KEY = "param_" ;
086 private static final String HEADER_KEY = "header" ;
087 private static final String FOOTER_KEY = "footer" ;
088 private static final String FILE_KEY = "File";
089
090 private static final String HEADER_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" ;
091 private static final String HEADER_ROWSET = "<ROWSET tableName=\"TABLENAME\">" ;
092 private static final String FOOTER_ROWSET = "</ROWSET>" ;
093
094 private XSLT xslt = null ;
095 private HybsEntry[] footerEntry = null;
096 private String xslfile = null ;
097 private String outfile = null ;
098 private boolean errAbend = true; // 中断する
099 private boolean errXmlIn = false; // エラーXML形å¼?
100 private boolean jspInclude = true; // 4.2.3.0 (2008/05/26)
101 private boolean display = false; // 表示しなã�?
102
103 private int clmNo = -1;
104 private int inCount = 0;
105 private int errCount = 0;
106 private String tableName = null;
107
108 private static final Map<String,String> mustProparty ; // ?»プロパティ?½å¿??チェãƒ?‚¯用 Map
109 private static final Map<String,String> usableProparty ; // ?»プロパティ?½整合æ?チェãƒ?‚¯ Map
110
111 static {
112 mustProparty = new LinkedHashMap<String,String>();
113 mustProparty.put( "xslfile", "変換を行う XSLファイル(å¿??)" );
114
115 usableProparty = new LinkedHashMap<String,String>();
116 usableProparty.put( "outfile", "変換結果の出力ファイルå�? );
117 usableProparty.put( "append", "出力ファイルをã?追記すã‚?true)か新規作æ?する(false)ã�? );
118 usableProparty.put( "useFileInfo", "入力ファイルæƒ??をã?XSLTのパラメータにセãƒ?ƒˆする(true)かしなã�?�‹(false)ã�? );
119 usableProparty.put( "addROWSET" , "ヘッãƒ??/フッターに ROWSET を追記しますã?");
120 usableProparty.put( "header", "出力ファイルに、ã?ãƒ?ƒ€ーæ–?—å?を追記しますã?" +
121 CR + "添えå?XX)が異なれã?è¤?•°のヘッãƒ??が指定できますã?" );
122 usableProparty.put( "footer", "出力ファイルに、フãƒ?‚¿ーæ–?—å?を追記しますã?" +
123 CR + "添えå?XX)が異なれã?è¤?•°のヘッãƒ??が指定できますã?" );
124 usableProparty.put( "param_", "XSLパã?サーに対して、paramater を設定しますã?" +
125 CR + "キーが異なれã?、è¤?•°のパラメータを指定できますã?" +
126 CR + "ä¾? -param_SYSTEM_ID=GE" );
127 usableProparty.put( "errAbend", "異常発生時に、å?ç�?‚’中断(true)するかã?継ç¶?false)するã�? +
128 CR + "(初期値:true:中断する)" );
129 usableProparty.put( "errXmlIn", "異常発生時に、å?力ファイルに、XML形式でエラーを追記するかを指定すã‚? +
130 CR + "(初期値:false:使用しなã�?" );
131 usableProparty.put( "jspInclude","jsp:directive.include 発見時に、そのファイルã‚?INCLUDE するかをæŒ?®šすã‚? +
132 CR + "(初期値:true:使用する)" );
133 usableProparty.put( "display", "結果を標準å?力に表示する(true)かしなã�?false)ã�? +
134 CR + "(初期値:false:表示しなã�?" );
135 }
136
137 /**
138 * ãƒ?ƒ•ォルトコンストラクターã€?
139 * こã?クラスは、動çš?½œæ?されますã?ãƒ?ƒ•ォルトコンストラクターでã€?
140 * super クラスに対して、å¿?¦�な初期化を行っておきますã?
141 *
142 */
143 public Process_XSLT() {
144 super( "org.opengion.fukurou.process.Process_XSLT",mustProparty,usableProparty );
145 }
146
147 /**
148 * プロセスの初期化を行いますã?初めにä¸?º¦ã�?�‘、呼び出されますã?
149 * 初期処ç�?ファイルオープンã€?¼¤?¢オープンç?に使用しますã?
150 *
151 * @og.rev 4.2.3.0 (2008/05/26) jsp:directive.include 処ç�??実施可否を引数æŒ?®šしますã?
152 *
153 * @param paramProcess ãƒ??タベã?スの接続å?æƒ??などを持ってã�?‚‹オブジェクãƒ?
154 */
155 public void init( final ParamProcess paramProcess ) {
156 Argument arg = getArgument();
157
158 xslfile = arg.getProparty( "xslfile" );
159 outfile = arg.getProparty( "outfile" );
160 tableName = arg.getProparty( "addROWSET" );
161 boolean isAppend = arg.getProparty( "append",false );
162 boolean useFileInfo = arg.getProparty( "useFileInfo",false );
163 HybsEntry[] paramEntry = arg.getEntrys( PARAM_KEY ); // 配å?
164 HybsEntry[] headerEntry = arg.getEntrys( HEADER_KEY ); // 配å?
165 footerEntry = arg.getEntrys( FOOTER_KEY ); // 配å?
166 errAbend =arg.getProparty("errAbend",errAbend);
167 errXmlIn =arg.getProparty("errXmlIn",errXmlIn);
168 jspInclude =arg.getProparty("jspInclude",jspInclude); // 4.2.3.0 (2008/05/26)
169 display =arg.getProparty("display",display);
170
171 // File file = new File( outfile );
172 if( outfile != null ) {
173 File file = new File( outfile ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
174 File dir = file.getParentFile() ;
175
176 // 親ãƒ?‚£レクトリを示さなã�??合ã? null 。ディレクトリが存在しなã�??かつ、ディレクトリが作æ?できなã�??合ã?処ç�?
177 if( dir != null && ! dir.exists() && ! dir.mkdirs() ) {
178 String errMsg = "ãƒ?‚£レクトリが作æ?できませんでしたã€?" + dir + "]" ;
179 throw new RuntimeException( errMsg );
180 }
181 }
182 else {
183 // 出力å?ファイル名が、指定されてã�?�ªã�??å�?
184 String errMsg = "outfile が指定されてã�?�¾せんã€?;
185 throw new RuntimeException( errMsg );
186 }
187
188 xslt = new XSLT();
189
190 xslt.setOutFile( outfile,isAppend );
191 xslt.setXslFile( xslfile );
192 xslt.setParamEntry( paramEntry );
193 xslt.useFileInfo( useFileInfo );
194 xslt.errClose( errAbend ); // エラー時に出力ファイルを閉じるかどã�?�‹ã€?
195 xslt.useErrXmlIn( errXmlIn ); // エラー時にXML形式で出力ファイルに追記するかどã�?�‹ã€?
196 xslt.jspInclude( jspInclude ); // 4.2.3.0 (2008/05/26) jsp:directive.include するかどã�?�‹
197
198 if( tableName != null ) {
199 xslt.setOutData( HEADER_XML );
200 xslt.setOutData( HEADER_ROWSET.replace( "TABLENAME",tableName ) );
201 }
202
203 int size = headerEntry.length;
204 for( int i=0; i<size; i++ ) {
205 xslt.setOutData( headerEntry[i].getValue() );
206 }
207 }
208
209 /**
210 * 引数の LineModel をå?ç�?�™るメソãƒ?ƒ‰ですã?
211 * 変換処ç�?¾Œã? LineModel を返しますã?
212 * 後続å?ç�?‚’行わなã�??å�?ãƒ??タのフィルタリングを行う場å�?はã€?
213 * null ãƒ??タを返しますã?つまりã?null ãƒ??タは、後続å?ç�?‚’行わなã�?
214 * フラグの代わりにも使用してã�?�¾すã?
215 * なおã?変換処ç�?¾Œã? LineModel と、オリジナルの LineModel がã?
216 * 同ä¸?�‹、コピã?(クローン)かã?、各処ç�?ƒ¡ソãƒ?ƒ‰å†?�§決めてã�?�¾すã?
217 * ドキュメントに明記されてã�?�ªã�??合ã?、副作用が問題になるå?合ã?ã€?
218 * å�??ç�?�”とに自åˆ?�§コピã?(クローン)して下さã�??
219 *
220 * @param data オリジナルのLineModel
221 *
222 * @return 処ç�?¤‰換後ã?LineModel
223 */
224 public LineModel action( final LineModel data ) {
225 inCount++ ;
226 if( display ) { println( data.dataLine() ); }
227 if( clmNo < 0 ) { clmNo = data.getColumnNo( FILE_KEY ); }
228 File file = (File)data.getValue( clmNo );
229
230 if( ! file.isFile() ) { return data; }
231
232 String filePath = file.getPath();
233
234 try {
235 xslt.transform( filePath );
236 }
237 catch( RuntimeException ex ) {
238 errCount++ ;
239 if( errAbend ) { throw ex; }
240 else {
241 logging( ex.getMessage() );
242 logging( "xslfile = " + xslfile );
243 logging( "outfile = " + outfile );
244 logging( "xmlFile = " + filePath );
245 }
246 }
247
248 return data ;
249 }
250
251 /**
252 * プロセスの終äº?‚’行いますã?æœ?¾Œにä¸?º¦ã�?�‘、呼び出されますã?
253 * 終äº??ç�?ファイルクローズã€?¼¤?¢クローズç?に使用しますã?
254 *
255 * @param isOK トã?タルで、OKã�?�£たかどã�?�‹[true:成功/false:失敗]
256 */
257 public void end( final boolean isOK ) {
258 if( xslt != null ) {
259 if( isOK ) {
260 int size = footerEntry.length;
261 for( int i=0; i<size; i++ ) {
262 xslt.setOutData( footerEntry[i].getValue() );
263 }
264 if( tableName != null ) {
265 xslt.setOutData( FOOTER_ROWSET );
266 }
267 }
268 xslt.close();
269 }
270 }
271
272 /**
273 * プロセスの処ç�?µ�果のレポã?ト表現を返しますã?
274 * 処ç�??ログラãƒ?��、å?力件数、å?力件数などのæƒ??ですã?
275 * こã?æ–?—å?をそのまま、標準å?力に出すことで、結果レポã?トと出来るよã�?�ª
276 * 形式で出してくださいã€?
277 *
278 * @return 処ç�?µ�果のレポã?ãƒ?
279 */
280 public String report() {
281 String report = "[" + getClass().getName() + "]" + CR
282 + TAB + "XSL File : " + xslfile + CR
283 + TAB + "OUT File : " + outfile + CR
284 + TAB + "Table Name : " + tableName + CR
285 + TAB + "File Count : " + inCount + CR
286 + TAB + "Err Count : " + errCount ;
287
288 return report ;
289 }
290
291 /**
292 * こã?クラスの使用方法を返しますã?
293 *
294 * @return こã?クラスの使用方æ³?
295 */
296 public String usage() {
297 StringBuilder buf = new StringBuilder();
298
299 buf.append( "XSLT変換結果を指定ã?ファイルに出力しますã?" ).append( CR );
300 buf.append( CR );
301 buf.append( "Process_XSLT は、AbstractProcess を継承した、ChainProcess インターフェース" ).append( CR );
302 buf.append( "の実è£?‚¯ラスですã?" ).append( CR );
303 buf.append( "上æµ?プロセスチェインのãƒ??タは上流から渡されますã?)からのLineModel の" ).append( CR );
304 buf.append( "ファイルオブジェクトに対して、指定ã? XSL ファイルを適用して、XSL変換ã‚? ).append( CR );
305 buf.append( "行いますã?出力結果は、ファイル、またã? 標準å?力に出力できますã?" ).append( CR );
306 buf.append( CR );
307 buf.append( "上流ã?ロセスでは、Name 属æ?として、ã?File』を持ち、å?は、Fileオブジェクãƒ? ).append( CR );
308 buf.append( "である、Process_FileSearch を使用するのがã?便利ですã?それ以外ã?クラスã‚? ).append( CR );
309 buf.append( "使用する場合でもã?Name属æ?と、File オブジェクトを持つ LineModel を受け渡ã�? ).append( CR );
310 buf.append( "できれば、使用可能ですã?" ).append( CR );
311 buf.append( CR );
312 buf.append( "-param_XXXX=固定å? を使用して、XSLTにパラメータを設定できますã?" ).append( CR );
313 buf.append( CR );
314 buf.append( "それ以外では、org.opengion.fukurou.xml.XSLT で、å?力ファイルæƒ??の設定が可能に" ).append( CR );
315 buf.append( "なってã�?‚‹為、å?部æƒ??を使用するかどã�?�‹ -useFileInfo を指定できますã?" ).append( CR );
316 buf.append( "-useFileInfo=true とセãƒ?ƒˆすると、以下ã??”é?目がå?部çš?�«セãƒ?ƒˆされますã?" ).append( CR );
317 buf.append( CR );
318 buf.append( "入力ファイル(inXMLのフルパス) : FILEPATH (ä¾? G:/temp/DOC10/query.jsp)" ).append( CR );
319 buf.append( "入力親フォルãƒ?inXMLの親フォルãƒ? : ADDRESS (ä¾? DOC10)" ).append( CR );
320 buf.append( "入力ファイル(inXMLのファイルå�? : FILENAME (ä¾? query.jsp)" ).append( CR );
321 buf.append( "入力ファイル(inXMLの更新日ä»? ) : MODIFIED (ä¾? yyyyMMddHHmmss形å¼?" ).append( CR );
322 buf.append( CR );
323 buf.append( "xsl ファイルでは、xsl:param で宣è¨?�—、xsl:value-of で取り出しますã?" ).append( CR );
324 buf.append( "<xsl:param name=\"ADDRESS\" select=\"\" /> と宣è¨?�—ておき、å¿?¦�なç®?‰€で" ).append( CR );
325 buf.append( "<xsl:value-of select=\"$ADDRESS\" /> とすれば、取得できますã?" ).append( CR );
326 buf.append( CR );
327 buf.append( "引数æ–?—å?中に空白を含ã‚??合ã?、ダブルコーãƒ??ション(\"\") で括って下さã�??" ).append( CR );
328 buf.append( "引数æ–?—å?の ã€?』ã?前後には、空白は挟めません。å¿?�šã€?key=value の様に" ).append( CR );
329 buf.append( "繋げてくださいã€? ).append( CR );
330 buf.append( CR ).append( CR );
331
332 buf.append( getArgument().usage() ).append( CR );
333
334 return buf.toString();
335 }
336
337 /**
338 * こã?クラスは、main メソãƒ?ƒ‰から実行できませんã€?
339 *
340 * @param args コマンド引数配å?
341 */
342 public static void main( final String[] args ) {
343 LogWriter.log( new Process_XSLT().usage() );
344 }
345 }