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 }