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.xml; 017 018 import java.io.File; 019 import java.io.IOException; 020 import java.io.BufferedReader; 021 import java.util.Map; 022 import java.util.WeakHashMap; 023 024 import org.opengion.fukurou.util.FileUtil; 025 import org.opengion.fukurou.util.Closer; 026 import org.opengion.fukurou.util.LogWriter; 027 028 /** 029 * ã“ã?クラスã¯ã€jspファイルã®XSLT変æ›ã«ç‰¹åŒ–ã—ãŸã?Readerオブジェクトを作æ?ã™ã‚‹ã‚¯ãƒ©ã‚¹ã§ã™ã? 030 * jspファイル ã«è¨˜è¿°ã•れるã?jsp:directive.include を見ã¤ã‘ã¦ã€ãã®ãƒ•ァイル属æ?ã« 031 * 記述ã•れã¦ã?‚‹ãƒ•ァイルをã?インクルードã—ã¾ã™ã? 032 * Tomcat ã®ç‰¹æ€§ä¸Šã?インクルード時ã®ãƒ•ァイルã¯ã€?¼?‰ã?エスケープを処ç?—ã¦ãŠã 033 * å¿?¦ãŒã‚りã¾ã™ã? 034 * エスケープã?å‰å?ç??ã€jsp:root ã‚¿ã‚°ã®ã‚ã‚‹ãªã—ã§åˆ¤å®šã—ã¾ã™ã? 035 * ç¾æ™‚点ã§ã¯ã€?&amp; , < , <= , > , >= ã‚’å‰å‡¦ç?—ã¾ã™ã? 036 * 037 * JSP ã§ã¯ã€og:head ã‚¿ã‚°ã§ã€?lt;html> ã‚’å?力ã—ãŸã‚Šã€htmlend.jsp インクルード㧠038 * </body></html> ã‚’å?力ã—ã¦ã?¾ã™ãŒã€ãƒ•レーãƒ?‚„ã€ãƒ•ォワードãªã©ã€æ•´åˆæ?ã? 039 * å–れãªã?‚±ãƒ¼ã‚¹ãŒã‚りã¾ã™ã?ã§ã€XML処ç?”¨ã¨ã—ã¦ã€?lt;html> ã‚’å?力ã—ã¦ã?¾ã›ã‚“ã€? 040 * 変æ›çµæžœã‚’ã?æ£å¼ãª HTML ファイルã¨ã—ã¦å†åˆ©ç”¨ã•れるå?åˆã?ã€ã”注æ„ãã?•ã?? 041 * 042 * ãªãŠã?ã“ã?クラスã¯ã€ã?ルãƒã‚¹ãƒ¬ãƒ?ƒ‰å¯¾å¿œã•れã¦ã?¾ã›ã‚“ã€? 043 * 044 * @og.rev 4.0.0.2 (2007/12/10) æ–°è¦è¿½åŠ? 045 * 046 * @version 4.0 047 * @author Kazuhiko Hasegawa 048 * @since JDK5.0, 049 */ 050 public class JspIncludeReader { 051 private static final String CR = System.getProperty("line.separator"); 052 053 // 5.6.7.1 (2013/08/09) includeã—ãŸãƒ•ァイルをã‚ャãƒ?‚·ãƒ¥ã—ã¦ãŠãã¾ã™ã? 054 private static final Map<String,String> includeFiles = new WeakHashMap<String,String>(); 055 056 // 5.6.7.1 (2013/08/09) ãƒ?ƒãƒ?‚°ç”¨ã«includeã—ãŸãƒ•ァイルをä¿å˜ã—ã¦ãŠãã¾ã™ã? 057 private final StringBuilder incFiles = new StringBuilder(); 058 059 // 5.7.6.2 (2014/05/16) realPath ã§ã€?jsp/common/以下ã«ã€å®Ÿãƒ•ァイルãŒå˜åœ¨ã—ãªã??åˆã?代替å–å¾—å?を指定ã—ã¾ã™ã? 060 private String realPath = null; 061 062 // ã‚¿ã‚°ã®å±žæ?ã®å€¤ã®ã¿ã‚’抜ãå?ã—ã¦ã?¾ã™ã?特ã«ã€?>& ã‚’å«ã‚??åˆã? 063 // 5.2.1.0 (2010/10/01) ä»®å»?¢ 064 // private static final Pattern ptn = Pattern.compile( "=[ \t]*\"([^\"]*[<>&].[^\"]*)\"" ); 065 066 /** 067 * JSP ã®ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ã‚’è€??ã—ãŸã€JSPファイルをã?String ã§è¿”ã—ã¾ã™ã? 068 * ã“ã?メソãƒ?ƒ‰ã¯ã€å?部ã§å†å¸°å®šç¾©ã•れã¦ã?¾ã™ã?ã¤ã¾ã‚Šã?jsp:directive.include 069 * æ–?—å?ãŒè¦‹ã¤ã‹ã£ãŸå?åˆã?ã€ãã®ä»£ã‚りã«ã€ãƒ•ァイルåã‚’å–å?ã—ã¦ã€ã‚‚ã?¸?º¦ 070 * ã“ã?メソãƒ?ƒ‰ã‚’呼ã³å‡ºã—ã¾ã™ã?インクルードファイルã¨ã®é–¢é€£ã‚’ãƒã‚§ãƒ?‚¯ã™ã‚‹ç‚ºã« 071 * ãƒ?ƒŸãƒ¼ã®spanã‚¿ã‚°ã‚’å?れã¦ãŠãã¾ã™ã? 072 * <span type="jsp:directive" include="ファイルå?><!-- --></span> 073 * ãŸã ã—ã?ソースãƒã‚§ãƒ?‚¯æ™‚ã«ã€? 074 * Ver4 以é™ã§ã€ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ãƒ•ァイルã«ã€XML宣è¨?¨ã€jsp:root を付与ã™ã‚‹ã‚±ãƒ¼ã‚¹ãŒã‚りã¾ã™ã? 075 * 擬似çš?«å–り込ã‚?¨ãã«ã¯ã€XML宣è¨??削除ã—ã¾ã™ã? 076 * 077 * @og.rev 5.2.1.0 (2010/10/01) directive.include ã§ã€XMLã‚¿ã‚°ã¨root ã‚¿ã‚°ã¯å–り込ã¾ãªã?? 078 * @og.rev 5.2.1.0 (2010/10/01) エスケープå?ç??引数をå»?¢ã—ã¾ã™ã? 079 * @og.rev 5.6.5.2 (2013/06/21) å°ç´°å·¥å†?®¹ã®å¤‰æ›´ã€‚replaceAll ã«ã™ã‚‹ã®ã¨ã€ã‚¹ãƒšã?スã¾ãŸã?タブを使用ã—ã¾ã™ã? 080 * @og.rev 5.6.7.1 (2013/08/09) コメントã?処ç??ãƒã‚°ä¿®æ£ã€‚includeファイルåä¿å˜ã? 081 * @og.rev 5.6.7.1 (2013/08/09) includeファイルãŒå˜åœ¨ã—ãªã??åˆã?ã€gf共有ã‹ã‚‰å–å¾—ã™ã‚‹ã? 082 * @og.rev 5.6.7.2 (2013/08/16) includeファイルをå–り込ã‚??åˆã?代ã‚りã®spanã‚¿ã‚°ã‚’å?力ã—ã¦ãŠãã¾ã™ã? 083 * @og.rev 5.6.7.4 (2013/08/30) includeファイルã®å…ˆé?ã®pageEncodingæŒ?®šã?ãƒã‚§ãƒ?‚¯ç”¨ span ã‚¿ã‚°ã®å‡ºåŠ? 084 * @og.rev 5.7.6.2 (2014/05/16) realPath ã§ã€?jsp/common/以下ã«ã€å®Ÿãƒ•ァイルãŒå˜åœ¨ã—ãªã??åˆã?代替å–å¾—å?を指定ã—ã¾ã™ã? 085 * 086 * @param file JSPファイル 087 * @param encode ファイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ? 088 * 089 * @return インクルードをè€??ã—ãŸã€JSPファイル 090 */ 091 public String getString( final File file,final String encode ) { 092 StringBuilder buf = new StringBuilder() ; 093 BufferedReader reader = FileUtil.getBufferedReader( file,encode ); 094 095 // ファイルãŒã?jsp 直下ã‹ã©ã?‹ã‚’判æ–ã—ã¾ã™ã? 096 String parentFile = file.getParent() ; 097 boolean isUnder = parentFile.endsWith( "\\jsp" ); 098 099 int cmntIn = -1; 100 int cmntOut = -1; 101 boolean isCmnt = false; 102 boolean isEscape = true; // エスケープã™ã‚‹ã‹ã©ã?‹(true:ã™ã‚‹/false:ã—ãªã? 103 try { 104 String line ; 105 while((line = reader.readLine()) != null) { 106 // 5.2.1.0 (2010/10/01) directive.include ã§ã€XMLã‚¿ã‚°ã¯å–り込ã¾ãªã?? 107 if( line.indexOf( "<?xml" ) >= 0 && line.indexOf( "?>" ) >= 0 ) { continue; } 108 // jsp:root ãŒã‚れã?ã€ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—å?ç?‚’行ã‚ãªã? 109 if( line.indexOf( "<jsp:root" ) >= 0 ) { isEscape = false; } 110 111 // コメントã?削除 112 cmntIn = line.indexOf( "<!--" ); 113 cmntOut = line.indexOf( "-->" ); 114 if( cmntIn >= 0 && cmntOut >= 0 ) { 115 line = line.substring( 0,cmntIn ) + line.substring( cmntOut+3 ); // 5.6.7.1 (2013/08/09) コメントã?処ç??ãƒã‚°ä¿®æ£ 116 } 117 else if( cmntIn >= 0 && cmntOut < 0 ) { 118 line = line.substring( 0,cmntIn ); 119 isCmnt = true; 120 } 121 else if( cmntIn < 0 && cmntOut >= 0 ) { 122 line = line.substring( cmntOut+3 ); // 5.6.7.1 (2013/08/09) コメントã?処ç??ãƒã‚°ä¿®æ£ 123 isCmnt = false; 124 } 125 else if( isCmnt && cmntIn < 0 && cmntOut < 0 ) { continue; } 126 127 // 特殊å?ç?¼šog:head ã§ html ã‚¿ã‚°ã‚’å?力ã—ã¦ã?‚‹ã€? 128 // if( line.indexOf( "<og:head" ) >= 0 ) { 129 // buf.append( "<html>" ); 130 // } 131 132 if( isEscape ) { 133 // 5.6.5.2 (2013/06/21) å°ç´°å·¥å†?®¹ã®å¤‰æ›´ã€‚replaceAll ã«ã™ã‚‹ã®ã¨ã€ã‚¹ãƒšã?スã¾ãŸã?タブを使用ã—ã¾ã™ã? 134 // & , < , <= , > , >= ã‚’å‰å‡¦ç?—ã¾ã™ã? 135 line = line.replaceAll( "&" ,"&" ); // ã¡ã‚?£ã¨å°ç´°å·¥ 136 line = line.replaceAll( "[ \\t]<[ \\t]"," < " ); // ã¡ã‚?£ã¨å°ç´°å·¥ 137 line = line.replaceAll( "[ \\t]>[ \\t]"," > " ); // ã¡ã‚?£ã¨å°ç´°å·¥ 138 line = line.replaceAll( "[ \\t]<="," <=" ); // ã¡ã‚?£ã¨å°ç´°å·¥ 139 line = line.replaceAll( "[ \\t]>="," >=" ); // ã¡ã‚?£ã¨å°ç´°å·¥ 140 // 5.2.1.0 (2010/10/01) ä»®å»?¢ 141 // Matcher mtch = ptn.matcher( line ); 142 // int adrs = 0; 143 // StringBuilder buf2 = new StringBuilder(); 144 // while( mtch.find(adrs) ) { 145 // String grp = mtch.group(1); 146 // String htm = StringUtil.htmlFilter( grp ); 147 // int in = mtch.start(1); 148 // buf2.append( line.substring( adrs,in ) ).append( htm ); 149 // adrs = mtch.end(1); 150 // } 151 // buf2.append( line.substring( adrs ) ); 152 // line = buf2.toString(); 153 } 154 155 int st = line.indexOf( "<jsp:directive.include" ); 156 if( st < 0 ) { buf.append( line ); } // include ãŒç„¡ã‘れã°ã€ãã®ã¾ã¾è¿½åŠ? 157 else { 158 buf.append( line.substring( 0,st ) ); 159 int fin = line.indexOf( '\"',st ); // ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ?? 160 int fout= line.indexOf( '\"',fin+1 ); // ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ?¾? 161 String fname = line.substring( fin+1,fout ); // ファイルå? 162 163 // 5.6.7.2 (2013/08/16) includeファイルをå–り込ã‚??åˆã?代ã‚りã®spanã‚¿ã‚°ã‚’å?力ã—ã¦ãŠãã¾ã™ã? 164 buf.append( "<span type=\"jsp:directive\"" ) 165 .append( " include=\"" ).append( fname ).append( "\" ><!-- --></span>" ) ; 166 167 // htmlend.jsp 㮠インクルードã?行ã‚ãªã?? 168 if( fname.endsWith( "htmlend.jsp" ) ) { 169 if( buf.indexOf( "<body" ) >= 0 && buf.indexOf( "</body>" ) < 0 ) { 170 buf.append( "</body>" ); 171 } 172 173 // if( buf.indexOf( "<html" ) >= 0 ) { 174 // buf.append( "</html>" ); 175 // } 176 } 177 else { 178 // 5.6.7.1 (2013/08/09) ãƒ?ƒãƒ?‚°ç”¨ã«includeã—ãŸãƒ•ァイルをä¿å˜ã—ã¦ãŠãã¾ã™ã? 179 if( incFiles.length() > 0 ) { incFiles.append( " , " ); } 180 incFiles.append( fname ); 181 182 // 5.6.7.1 (2013/08/09) includeã—ãŸãƒ•ァイルをã‚ャãƒ?‚·ãƒ¥ã‹ã‚‰æ¤œç´¢ã—ã¾ã™ã? 183 String fileData = includeFiles.get( fname ); // ã‚ャãƒ?‚·ãƒ¥ã‚’検索(fname ãŒã‚ー) 184 if( fileData == null ) { 185 // ã¡ã‚?£ã¨å°ç´°å·¥ 186 String fname2 = fname ; 187 // include ã™ã‚‹ãƒ•ァイルã¯ã€?jsp/ ã‹ã‚‰ã®çµ¶å¯¾ãƒ‘スã€? 188 // jsp 直下ã?å ´åˆã?ã€?/ ã€ãれ以外ã?ã€?./ ã¨ç½®ãæ›ãˆã¾ã™ã? 189 if( isUnder ) { fname2 = fname2.replace( "/jsp/","./" ); } 190 else { fname2 = fname2.replace( "/jsp/","../" ); } 191 // 5.6.7.1 (2013/08/09) includeファイルãŒå˜åœ¨ã—ãªã??åˆã?ã€gf共有ã‹ã‚‰å–å¾—ã™ã‚‹ã? 192 File newfile = new File( parentFile,fname2 ); 193 if( !newfile.exists() ) { 194 if( fname2.contains( "/common/" ) || fname2.contains( "/menu/" ) ) { 195 if( realPath == null ) { 196 // 本当ã? classPathã‹ã‚‰ã€å–å¾—ã™ã¹ãã? 197 // 今ã?ã€å®Ÿè¡Œç’°å¢??相対パスã®ä½ç½®ã«ã€gf/jsp/common,menu ã®ãƒ•ァイルãŒå¿?¦ã? 198 fname2 = isUnder 199 ? "./../../gf/jsp/" + fname2.substring( 2 ) 200 : "../../../gf/jsp/" + fname2.substring( 3 ) ; 201 newfile = new File( parentFile,fname2 ); // ã“ã“ã§ãªã‘れã°ã€ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ã? 202 } 203 else { 204 // 5.7.6.2 (2014/05/16) realPath ã§ã€?jsp/common/以下ã«ã€å®Ÿãƒ•ァイルãŒå˜åœ¨ã—ãªã??åˆã?代替å–å¾—å?を指定ã—ã¾ã™ã? 205 newfile = new File( realPath,fname ); // 稼åƒã—ã¦ã?‚‹ gf ã® common ç‰ã‚’使用ã—ã¾ã™ã? 206 } 207 } 208 } 209 fileData = getString( newfile,encode ); 210 211 // 5.6.7.4 (2013/08/30) includeファイルã®å…ˆé?ã®pageEncodingæŒ?®šã?ãƒã‚§ãƒ?‚¯ç”¨ span ã‚¿ã‚°ã®å‡ºåŠ? 212 // インクルードファイルã®å…ˆé?ã«ã¯ã€pageEncoding="UTF-8" 宣è¨?Œå¿?¦?UTF-8ã‹ã©ã?‹ã¯æœªãƒã‚§ãƒ?‚¯) 213 if( ! fileData.startsWith( "<jsp:directive.page pageEncoding" ) ) { 214 // ãƒã‚§ãƒ?‚¯ç”¨ã®spanã‚¿ã‚°ã‚’å?力ã—ã¦ãŠãã¾ã™ã? 215 buf.append( "<span type=\"jsp:directive\"" ) 216 .append( " pageEncoding=\"non\" file=\"" ).append( fname ).append( "\" ><!-- --></span>" ) ; 217 } 218 219 // 5.6.7.1 (2013/08/09) includeã—ãŸãƒ•ァイルをã‚ャãƒ?‚·ãƒ¥ã—ã¦ãŠãã¾ã™ã? 220 includeFiles.put( fname,fileData ); // includeファイルをã‚ャãƒ?‚·ãƒ¥(fname ãŒã‚ー) 221 } 222 223 buf.append( fileData ); 224 } 225 int tagout = line.indexOf( "/>",fout+1 ); // ã‚¿ã‚°ã®æœ?¾? 226 227 buf.append( line.substring( tagout+2 ) ); 228 } 229 230 // og:commonForward を見ã¤ã‘ãŸå ´åˆã?ã€æœ€å¾Œã« html ã‚¿ã‚°ã‚’å?力ã™ã‚‹ã? 231 // if( line.indexOf( "<og:commonForward" ) >= 0 ) { 232 // buf.append( "</html>" ); 233 // } 234 235 buf.append( CR ); 236 } 237 } 238 catch( IOException ex ) { 239 LogWriter.log( ex ); 240 } 241 finally { 242 Closer.ioClose( reader ); 243 } 244 return buf.toString(); 245 } 246 247 /** 248 * jspInclude=true 時ã«ã€?jsp/common/** ç‰ã? include ファイルãŒå˜åœ¨ã—ãªã??åˆã?共有å–å¾—å?æ‰?‚’æŒ?®šã—ã¾ã™ã? 249 * 250 * 引数ã®å‡¦ç?¯¾è±¡ãƒ•ァイル(transformã®å¼•数ファイル)ãŒã?ã€?jspã€ã§ã€ã‹ã¤ã€jspInclude=true ã®å ´åˆã? 251 * ãã?ファイルã‚?INCLUDE ã™ã‚‹ã®ã§ã™ãŒã€?jsp/common/** ç‰ã? include ファイルã¯ã€? 252 * エンジン共通ã¨ã—ã¦ã€jspCommon6.x.x.x.jar ã§æä¾›ã—ã¦ã?¾ã™ã? 253 * 従æ¥ã¯ã€å?ç?¯¾è±¡jspã®ç›¸å¯¾ãƒ‘スã§ã€?./../../gf/jsp/commom/** ã‚’å–り込んã§ã?¾ã—ãŸãŒã? 254 * Tomcat起動フォルãƒ?»¥å¤–ã?シスãƒ?ƒ ã®JSPãƒã‚§ãƒ?‚¯ãªã©ã‚’行ã†å ´åˆã?ã€gf フォルãƒ?Œå˜åœ¨ã—ãªã? 255 * ケースãŒã‚りã¾ã™ã? 256 * ãã“ã§ã€ç¢ºå®Ÿã«gf ãŒå˜åœ¨ã™ã‚‹ã€å?ç?‚’ã‚ãƒ?‚¯ã—ã¦ã?‚‹ç’°å¢?? gf を使用ã™ã‚‹ã‚ˆã†ã«å¤‰æ›´ã—ã¾ã™ã? 257 * ãã?ç’°å¢?¨ã¯ã€ã¤ã¾ã‚Šã?エンジンå†?ƒ¨å¤‰æ•°ã® REAL_PATH ã§ã™ãŒã€jsp ãªã©ãŒå®Ÿè¡Œã—ã¦ã?ªã?¨å–å¾—ã§ãã¾ã›ã‚“ã€? 258 * 259 * @param path /jsp/common/** ç‰ã? include ファイルã®å…±æœ‰å–å¾—å?æ‰? 260 */ 261 public void setRealPath( final String path ) { 262 realPath = path ; 263 } 264 265 /** 266 * インクルードã—ãŸãƒ•ァイルå?相対パス)ã®ãƒªã‚¹ãƒˆæ–‡å—å?ã‚’è¿”ã—ã¾ã™ã? 267 * 通常ã¯ã€XSLT変æ›å‡¦ç?§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå?åˆã?ã€includeãƒ•ã‚¡ã‚¤ãƒ«ã®æ•´åˆæ?ã? 268 * ãŠã‹ã—ã„å ´åˆãŒå¤šã„ã®ã§ã€ãƒ‡ãƒãƒƒã‚°æƒ??ã¨ã—ã¦åˆ©ç”¨ã—ã¾ã™ã? 269 * ãŸã ã—ã?エラー発生時ã®ä½ç½®ç‰¹å®šã¾ã§ã¯ã§ãã¾ã›ã‚“ã€? 270 * 271 * ã“ã?å†?ƒ¨å¤‰æ•°ã¯ã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹å¤‰æ•°ã§ã™ã?ã§ã€includeファイルã®ã‚ャãƒ?‚·ãƒ¥ã¨ã¯å¯¿å‘½ãŒç•°ãªã‚Šã¾ã™ã? 272 * 273 * @og.rev 5.6.7.1 (2013/08/09) æ–°è¦è¿½åŠ? 274 * 275 * @return includeファイルåã?リスト文å—å? 276 */ 277 public String getIncludeFiles() { 278 return incFiles.toString(); 279 } 280 281 /** 282 * インクルードã—ãŸãƒ•ァイルã®ã‚ャãƒ?‚·ãƒ¥ã‚’クリアã—ã¾ã™ã? 283 * ã‚ャãƒ?‚·ãƒ¥ã¯ã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ã¯ãªãã?スタãƒ?‚£ãƒ?‚¯å¤‰æ•°ã§ç®¡ç?—ã¦ã?¾ã™ã? 284 * よã£ã¦ã€ä¸??ã®å‡¦ç??åˆã‚ã¨æœ?¾Œã«ã‚¯ãƒªã‚¢ã—ã¦ãŠã„ã¦ãã ã•ã„ã€? 285 * 286 * @og.rev 5.6.7.1 (2013/08/09) æ–°è¦è¿½åŠ? 287 */ 288 public static void cacheClear() { 289 includeFiles.clear(); 290 } 291 292 /** 293 * ãƒ?‚¹ãƒˆç”¨ã® main メソãƒ?ƒ‰ 294 * 295 * Usage: org.opengion.fukurou.xml.JspIncludeReader inFile [outFile] 296 * 297 * @param args コマンド引数é…å? 298 */ 299 public static void main( final String[] args ) { 300 JspIncludeReader reader = new JspIncludeReader(); 301 String xml = reader.getString( new File( args[0] ),"UTF-8" ); 302 303 if( args.length > 1 ) { 304 java.io.PrintWriter writer = FileUtil.getPrintWriter( new File( args[1] ),"UTF-8" ); 305 writer.print( xml ); 306 Closer.ioClose( writer ); 307 } 308 else { 309 System.out.println( xml ); 310 } 311 } 312 }