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.hayabusa.filter; 017 018 import org.opengion.hayabusa.common.HybsSystem; 019 020 import java.util.Locale; 021 022 import java.io.File; 023 import java.io.IOException; 024 import java.io.UnsupportedEncodingException; 025 import javax.servlet.ServletRequest; 026 import javax.servlet.ServletResponse; 027 import javax.servlet.ServletContext; 028 import javax.servlet.Filter; 029 import javax.servlet.FilterChain; 030 import javax.servlet.FilterConfig; 031 import javax.servlet.ServletException; 032 import javax.servlet.http.HttpServletRequest; 033 import javax.servlet.http.HttpServletResponse; 034 035 /** 036 * Filter インターフェースを継承した HTML?画面を作?するフィルタクラスです? 037 * web.xml で filter 設定することにより、使用できます? 038 * こ?フィルターでは??常の画面アクセスを行うと、指定?フォル?対して 039 * JSPをHTMLに変換した形で、ファイルをセーブして?ます?こ?HTMLは? 040 * ?サンプル画面として、使用できます? 041 * 出来る限り??画面として使えるように、画面間リンク??ボタン制御? 042 * JavaScript を挿入する事で実現して?す? 043 * 044 * フィルターに対してweb.xml でパラメータを設定します? 045 * ・saveDir :ファイルをセーブするディレクトリ 046 * 047 * パラメータがな??合?、G:/webapps/作番/filetemp/DIR/ 以下に自動設定されます? 048 * また??レクトリが?相対パスの場合?、G:/webapps/作番/ 以下に、絶対パスの 049 * 場合?、そのパスの下に作?されます? * 050 * 051 * 【WEB-INF/web.xml? 052 * <filter> 053 * <filter-name>FileFilter</filter-name> 054 * <filter-class>org.opengion.hayabusa.filter.FileFilter</filter-class> 055 * <init-param> 056 * <param-name>saveDir</param-name> 057 * <param-value>filetemp/DIR/</param-value> 058 * </init-param> 059 * </filter> 060 * 061 * <filter-mapping> 062 * <filter-name>FileFilter</filter-name> 063 * <url-pattern>/jsp/*</url-pattern> 064 * </filter-mapping> 065 * 066 * @og.group フィルター処? 067 * 068 * @version 4.0 069 * @author Kazuhiko Hasegawa 070 * @since JDK5.0, 071 */ 072 public class FileFilter implements Filter { 073 private String saveDir = null; // "G:/webapps/gf/filetemp/DIR/" など 074 075 /** 076 * Filter インターフェースの doFilter メソ? 077 * 078 * Filter クラスの doFilter メソ?はコン?により呼び出され???チェーンにおけ? 079 * リソースへのクライアントリクエスト?ために?毎回リクエスト?レスポンスのペアが? 080 * チェーンを?して渡されます? こ?メソ?に渡され?FilterChain を利用して、Filter ? 081 * リクエストやレスポンスをチェーン??次のエン??(Filter)にリクエストとレスポンス? 082 * 渡す事ができます? 083 * こ?メソ?の典型的な実??以下?ようなパターンとなるでしょ?? 084 * 1. リクエスト?検査 085 * 2. オプションとして、?力フィルタリング用にコン??しくはヘッ?フィルタリング 086 * するためにカスタ??よるリクエストオブジェクト?ラ?? 087 * 3. オプションとして、?力フィルタリング用にコン??しくはヘッ?フィルタリング 088 * するためにカスタ??よるレスポンスオブジェクトラ?? 089 * 4. 以下? a)、b) のどちらか 090 * a) FileterChain オブジェク?chain.doFilter()) を利用してチェーンの次のエン??を呼び出? 091 * b) リクエスト??止めるために、リクエスト?レスポンスのペアをフィルタチェーンの次の 092 * エン??に渡さな? 093 * 5. フィルタチェーンの次のエン??の呼び出した後?直接レスポンスのヘッ?セ? 094 * 095 * @param req ServletRequestオブジェク? 096 * @param res ServletResponseオブジェク? 097 * @param chain FilterChainオブジェク? 098 * @throws IOException 099 * @throws ServletException 100 */ 101 public void doFilter( final ServletRequest req, 102 final ServletResponse res, 103 final FilterChain chain ) 104 throws IOException, ServletException { 105 if(req instanceof HttpServletRequest && res instanceof HttpServletResponse) { 106 HttpServletRequest request = (HttpServletRequest) req; 107 HttpServletResponse response = (HttpServletResponse) res; 108 109 try { 110 request.setCharacterEncoding( "UTF-8" ); 111 } 112 catch ( UnsupportedEncodingException ex ) { 113 throw new RuntimeException( ex ); 114 } 115 116 String filename = makeFileName( request ); 117 if( filename != null ) { 118 FileResponseWrapper wrappedResponse = new FileResponseWrapper(response,filename); 119 chain.doFilter(req, wrappedResponse); 120 wrappedResponse.finishResponse(); 121 } 122 else { 123 chain.doFilter(req, res); 124 } 125 } 126 } 127 128 /** 129 * フィルターの初期処?ソ?です? 130 * 131 * フィルターに対してweb.xml で初期パラメータを設定します? 132 * ・startTime:停止開始時刻 133 * ・stopTime :停止終?刻 134 * ・filename :停止時メ?ージ表示ファイル? 135 * 136 * @param filterConfig FilterConfigオブジェク? 137 */ 138 public void init(final FilterConfig filterConfig) { 139 ServletContext context = filterConfig.getServletContext(); 140 String realPath = context.getRealPath( "/" ); 141 142 String dir = filterConfig.getInitParameter("saveDir"); 143 if( dir != null && dir.length() > 1 ) { 144 dir = dir.replace( '\\','/' ); 145 if( dir.charAt(0) == '/' || dir.charAt(1) == ':' ) { 146 saveDir = dir; 147 } 148 else { 149 saveDir = realPath + dir ; 150 } 151 152 if( dir.charAt(dir.length()-1) != '/' ) { 153 saveDir = saveDir + "/" ; 154 } 155 } 156 else { 157 saveDir = realPath + "filetemp/DIR/" ; 158 } 159 } 160 161 /** 162 * Filter インターフェースの destroy メソ? (何もしません)? 163 * 164 * サービス状態を終えた事を Filter に伝えるために Web コン?が呼び出します? 165 * Filter の doFilter メソ?が終?たか、タイ?ウトに達した?てのスレ?において? 166 * こ?メソ?を??呼び出されます? Web コン?がこのメソ?を呼び出した後?? 167 * Filter のこ?インスタンスにおいて二度と doFilter メソ?を呼び出す事?ありません? 168 * 169 * こ?メソ?は、フィルタに保持されて?(例えば、メモリ、ファイルハンドル、スレ?) 170 * 様?なリソースを開放する機会を与え?あら?永続?の状態が、メモリ上におけ?Filter 171 * の現在の状態と同期して?ように注意してください? 172 */ 173 public void destroy() { 174 // noop 175 } 176 177 /** 178 * セーブするファイル名を、リクエスト情報より取得します? 179 * 180 * リクエストされたファイル(.jsp)を?HTMLファイル(.htm)にする?でなく? 181 * 呼び出されたとき? command を?に、ファイル名を作?します? 182 * command="NEW" + forward.jsp ? "forward.htm" 183 * command="RENEW" + forward.jsp ? "renew.htm" 184 * command="日本語名+ forward.jsp ? "コマンド名.htm" 185 * command="日本語名+ update.jsp ? "コマンド名.htm" 186 * command="NEW" + index.jsp ? "indexNW.htm" 187 * command="RENEW" + index.jsp ? "indexRNW.htm" 188 * command="NEW" + query.jsp ? "queryNW.htm" 189 * command="NEW" + resultXX.jsp ? "forwardXX.htm" 5.6.3.4 (2013/04/26) result.jsp にフレー?使?ターン(??イン) 190 * matrixMenu対? 191 * URI? URI? request取? 192 * ?gamenId="jsp" + index.jsp + GAMENID=XXXX ?saveDir + "jsp/indexXXXX.htm" Matrixメニューからの画面呼出し? 193 * ② gamenId="jsp" + result.jsp + GAMENID=XXXX ?saveDir + "XXXX/index.htm" 画面QUERYのヘッ??メニュー 194 * ③ gamenId="jsp" + index.jsp + group=YYYY ?saveDir + "jsp/indexYYYY.htm" ?存在しな??ず? 195 * ④ gamenId="menu" + multiMenu.jsp + GAMENID=XXXX ?saveDir + "jsp/menuXXXX.htm" ?存在しな??ず? 196 * ⑤ gamenId="menu" + multiMenu.jsp + group=YYYY ?saveDir + "jsp/menuYYYY.htm" 通常メニューのグループ選? 197 * ⑥ gamenId="menu" + matrixMenu.jsp + group=YYYY ?saveDir + "menu/matrixMenuYYYY.htm" Matrixメニューのグループ選? 198 * <del>GAMENID=XXXX&buttonRequest=true + index.jsp ?"jsp/indexXXXX.htm"</del> 199 * <del>GAMENID=XXXX&buttonRequest=true + multiMenu.jsp ?"jsp/menuXXXX.htm"</del> 200 * そ?? xxxx.jsp ? "xxxx.htm" 201 * 202 * こ?メソ?は、フィルタに保持されて?(例えば、メモリ、ファイルハンドル、スレ?) 203 * 様?なリソースを開放する機会を与え?あら?永続?の状態が、メモリ上におけ?Filter 204 * の現在の状態と同期して?ように注意してください? 205 * 206 * @og.rev 4.0.0.0 (2007/11/28) メソ?の戻り?をチェ?します? 207 * @og.rev 4.3.3.0 (2008/10/01) Matrixメニュー対? 208 * @og.rev 5.5.2.5 (2012/05/21) update.jsp に出力されるファイルを?コマンド名.htm に出力するよ?機?追? 209 * @og.rev 5.6.3.4 (2013/04/26) 5.6.3.4 (2013/04/26) command="NEW" + resultXX.jsp ? "forwardXX.htm"?result.jsp にフレー?使?ターン(??イン) 210 * @og.rev 5.6.4.2 (2013/05/17) Matrixメニュー buttonRequest ?対? 211 * 212 * @param request ServletRequestオブジェク? 213 * 214 * @return セーブするファイル? 215 */ 216 private String makeFileName( final ServletRequest request ) { 217 HttpServletRequest myReq = (HttpServletRequest) request; 218 String requestURI = myReq.getRequestURI(); 219 220 int index2 = requestURI.lastIndexOf( '/' ); 221 String jspID = requestURI.substring( index2+1 ); 222 int index1 = requestURI.lastIndexOf( '/',index2-1 ); 223 String gamenId = requestURI.substring( index1+1,index2 ); 224 225 String file = null; 226 227 if( jspID != null && jspID.endsWith( ".jsp" ) ) { 228 String cmd = request.getParameter( "command" ); 229 if( cmd != null && jspID.equals( "forward.jsp" ) ) { 230 if( "NEW".equals( cmd ) ) { file = "forward.htm"; } 231 else if( "RENEW".equals( cmd ) || "REVIEW".equals( cmd ) ) { file = "renew.htm"; } 232 else { 233 String xferVal = request.getParameter( HybsSystem.NO_XFER_KEY + cmd ); 234 // 5.5.2.5 (2012/05/21) update.jsp に出力されるファイルを?コマンド名.htm に出力するよ?機?追? 235 if( "update.jsp".equals( xferVal ) ) { 236 file = cmd + ".htm" ; 237 } 238 else if( xferVal != null && xferVal.endsWith( "jsp" ) ) { 239 file = xferVal.toLowerCase(Locale.JAPAN).replace( "jsp","htm" ); 240 } 241 else { 242 String xferCmd = request.getParameter( HybsSystem.NO_XFER_KEY + cmd + "CMD" ); 243 if( xferCmd != null ) { 244 file = xferCmd.toLowerCase(Locale.JAPAN) + ".htm"; 245 } 246 else { 247 file = cmd.toLowerCase(Locale.JAPAN) + ".htm"; 248 } 249 } 250 } 251 } 252 else if( "index.jsp".equals( jspID ) && ( "RENEW".equals( cmd ) || "REVIEW".equals( cmd ) ) ) { 253 file = "indexRNW.htm"; 254 } 255 else if( "index.jsp".equals( jspID ) && "NEW".equals( cmd ) ) { 256 file = "indexNW.htm"; 257 } 258 else if( "query.jsp".equals( jspID ) && "NEW".equals( cmd ) ) { 259 file = "queryNW.htm"; 260 } 261 // 5.6.3.4 (2013/04/26) command="NEW" + resultXX.jsp ? "forwardXX.htm"?result.jsp にフレー?使?ターン(??イン) 262 // else if( jspID.startsWith( "result" ) && jspID.endsWith( ".jsp" ) && "NEW".equals( cmd ) ) { 263 else if( jspID.startsWith( "result" ) && "NEW".equals( cmd ) ) { 264 file = "forward" + jspID.substring( 6,jspID.length()-4 ) + ".htm" ; 265 } 266 // 5.6.4.2 (2013/05/17) fileDownload.jsp の対? 267 else if( "fileDownload.jsp".equals( jspID ) ) { 268 gamenId = request.getParameter( "GAMENID" ); // gamenId(??フォル?抽出)をリクエスト変数から取得する? 269 file = request.getParameter( "filename" ); // 日本語ファイル名で抽出する場合? 270 file = "fileDownload:" + file ; // ただし?セーブ時は、UnicodeLittle なので?fileDownload:" でマ?カーする? 271 } 272 else { 273 file = jspID.substring( 0,jspID.length()-4 ) + ".htm" ; 274 } 275 276 // 5.6.4.2 (2013/05/17) Matrixメニュー 対? 277 // URI? URI? request取? 278 // ?gamenId="jsp" + index.jsp + GAMENID=XXXX ?saveDir + "jsp/indexXXXX.htm" Matrixメニューからの画面呼出し? 279 // ② gamenId="jsp" + result.jsp + GAMENID=XXXX ?saveDir + "jsp/indexXXXX.htm" 画面QUERYのヘッ??メニュー 280 // ③ gamenId="menu" + multiMenu.jsp + group=YYYY ?saveDir + "menu/menuYYYY.htm" 通常メニューのグループ選? 281 // ④ gamenId="menu" + matrixMenu.jsp + group=YYYY ?saveDir + "menu/matrixMenuYYYY.htm" Matrixメニューのグループ選? 282 String guiKey = request.getParameter( "GAMENID" ); 283 String group = request.getParameter( "group" ); 284 285 if( "jsp".equals( gamenId ) && guiKey != null ) { 286 if( "index.jsp".equals( jspID ) || "result.jsp".equals( jspID ) ) { 287 file = "jsp/index" + guiKey + ".htm"; // ?② 288 } 289 } 290 else if( group != null ) { 291 if( "multiMenu.jsp".equals( jspID ) ) { 292 file = gamenId + "/menu" + group + ".htm"; // ③ 293 } 294 else if( "matrixMenu.jsp".equals( jspID ) ) { 295 file = gamenId + "/matrixMenu" + group + ".htm"; // ④ 296 } 297 gamenId = "jsp" ; // トリ?ー 298 } 299 300 // 5.6.4.2 (2013/05/17) Matrixメニュー buttonRequest ? 301 // // 4.3.3.0 (2008/10/01) Matrixメニュー対? 302 // // GAMENID=XXXX&buttonRequest=true + index.jsp ?"jsp/indexXXXX.htm" 303 // // GAMENID=XXXX&buttonRequest=true + multiMenu.jsp ?"jsp/menuXXXX.htm" 304 // // group=YYYY&buttonRequest=true + matrixMenu.jsp ?"menu/matrixMenuYYYY.htm" 305 // String guiKey = request.getParameter( "GAMENID" ); 306 // String btnReq = request.getParameter( "buttonRequest" ); 307 // if( "true".equals( btnReq ) ) { 308 // if( guiKey != null ) { 309 // if( "index.jsp".equals( jspID ) ) { 310 // file = "jsp/index" + guiKey + ".htm"; 311 // } 312 // else if( "multiMenu.jsp".equals( jspID ) ) { 313 // file = "jsp/menu" + guiKey + ".htm"; 314 // gamenId = "jsp" ; // トリ?ー 315 // } 316 // } 317 // else { 318 // 319 // String group = request.getParameter( "group" ); 320 // if( group != null ) { 321 // if( "matrixMenu.jsp".equals( jspID ) ) { 322 // file = "menu/matrixMenu" + group + ".htm"; 323 // gamenId = "jsp" ; // トリ?ー 324 // } 325 // } 326 // } 327 // } 328 329 // int index1 = requestURI.lastIndexOf( '/',index2-1 ); 330 // String gamenId = requestURI.substring( index1+1,index2 ); 331 332 if( "jsp".equals( gamenId ) ) { file = saveDir + file; } 333 else { file = saveDir + gamenId + "/" + file; } 334 335 // File fl = new File( saveDir + gamenId ); 336 // if( !fl.exists() && !fl.mkdirs() ) { 337 File fl = new File( file ).getParentFile(); 338 if( fl != null && !fl.exists() && !fl.mkdirs() ) { 339 String errMsg = "??フォル?作?できませんでした?" + fl + "]" ; 340 throw new RuntimeException( errMsg ); 341 } 342 } 343 344 return file; 345 } 346 }