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