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