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 */ 016package org.opengion.hayabusa.filter; 017 018import org.opengion.fukurou.util.StringUtil; 019import org.opengion.fukurou.util.FileUtil; 020 021import java.util.regex.Pattern ; 022import java.util.regex.Matcher ; 023import java.util.Set ; 024import java.util.HashSet ; 025import java.io.File; 026 027/** 028 * FileFilter で使用する、紙芝居用HTMLファイル作成時に内部文字列を変換するクラスです。 029 * 030 * @og.group フィルター処理 031 * 032 * @version 4.0 033 * @author Kazuhiko Hasegawa 034 * @since JDK5.0, 035 */ 036public class FileResponseTransform { 037 038 // 5.6.4.2 (2013/05/17) JFreeChart の画像ファイル(ChartTempフォルダ) のコピー関係の固定値 039 private static final String CHART_KEY = "/ChartTemp/" ; 040 private static final int KEY_LEN = CHART_KEY.length(); 041 042 private static final Set<String> TARGET_CHANGE_SET = new HashSet<String>(); 043 044 private static final ChangeData[] data = new ChangeData[] { 045 new ChangeData( null,"\"/[^/]*/jsp/","\"../" ) // 5.5.7.2 (2012/10/09) マッチ条件を広げる 046 ,new ChangeData( null,"'/[^/]*/jsp/","'../" ) // 5.5.7.2 (2012/10/09) マッチ条件を広げる 047 ,new ChangeData( null,"=\"/[^/]*/[^/]*/ChartTemp/","=\"../ChartTemp/" ) // 5.5.2.5 (2012/05/21) JfreeChart関係の画像のアドレス変換 048 ,new ChangeData( null,"='/[^/]*/[^/]*/ChartTemp/","='../ChartTemp/" ) // 5.5.2.5 (2012/05/21) JfreeChart関係の画像のアドレス変換 049 ,new ChangeData( null,"=\"/[^/]*/help/","=\"../help/" ) // 5.5.2.5 (2012/05/21) help関係の画像のアドレス変換 050 ,new ChangeData( null,"='/[^/]*/help/","='../help/" ) // 5.5.2.5 (2012/05/21) help関係の画像のアドレス変換 051 ,new ChangeData( null,"\\.jsp" ,".htm" ) 052 ,new ChangeData( "forward.htm" ,"type=\"submit\"","type=\"button\"" ) 053 ,new ChangeData( "forward.htm" ,"frame src=\"result","frame src=\"forward" ) // 5.6.3.4 (2013/04/26) result.jsp にフレームを使うパターン(3ペイン) 054 ,new ChangeData( "reset.htm" ,"frame src=\"result","frame src=\"forward" ) // 5.6.4.2 (2013/05/17) reset.htm で、フレームを使うパターン(3ペイン) 055 ,new ChangeData( "index.htm" ,"frame src=\"forward.htm","frame src=\"../common/dummy.html" ) 056 ,new ChangeData( "index.htm" ,"frame src=\"entry.htm" ,"frame src=\"../common/dummy.html" ) // 5.6.3.4 (2013/04/26) ENTRY系の特殊対応 057 ,new ChangeData( "indexRNW.htm","frame src=\"forward.htm","frame src=\"renew.htm" ) 058 ,new ChangeData( "indexNW.htm" ,"frame src=\"query.htm" ,"frame src=\"queryNW.htm" ) 059 ,new ChangeData( "indexNW.htm" ,"frame src=\"entry.htm" ,"frame src=\"../common/dummy.html" ) // 5.6.3.4 (2013/04/26) ENTRY系の特殊対応 060 ,new ChangeData( null ,"onSubmit=\"return oneClick\\(\\);\"","onSubmit=\"return false;\"" ) // 5.5.7.2 (2012/10/09) 変更は、すべて行う。 061 ,new ChangeData( null ,"onSubmit=\"\"" ,"onSubmit=\"return false;\"" ) // 5.6.3.4 (2013/04/26) onSubmit 引数のないケースへの対応 062 ,new ChangeData( null ,"src=\"\\.\\./common/option/ajaxSubmit\\.js\\?v=[^\"]+\"","" ) // 5.6.3.4 (2013/04/26) ajaxSubmit.js を削除 063 // 4.3.3.0 (2008/10/01) 戻るリンクの対応 064 ,new ChangeData( "queryNW.htm" ,"=\"http://.*jsp/+?","=\"../" ) 065 ,new ChangeData( "query.htm" ,"renew\\('query.htm'","renew\\('queryNW.htm'" ) // 5.6.4.2 (2013/05/17) renew('query.htm' 変換 066 // 漢字のボタンでは、後ろにショートカット文字が入る為、前方一致で挿入する。 067 // ,new ChangeData( "forward.htm","value=\"追加","onClick=\"location.href='insert.htm'\" value=\"追加" ) 068 // ,new ChangeData( "forward.htm","value=\"複写","onClick=\"location.href='copy.htm'\" value=\"複写" ) 069 // ,new ChangeData( "forward.htm","value=\"変更","onClick=\"location.href='modify.htm'\" value=\"変更" ) 070 // ,new ChangeData( "forward.htm","value=\"削除","onClick=\"location.href='delete.htm'\" value=\"削除" ) 071 // ,new ChangeData( "query.htm","index.htm\\?command=RENEW" ,"indexRNW.htm?command=RENEW" ) 072 // ,new ChangeData( null ,"index.htm\\?command=NEW" ,"indexNW.htm?command=NEW" ) 073 ,new IndexMatrixMenuData() // 4.3.3.0 (2008/10/01) マトリクスメニュー対応 074 ,new IndexChangeData() 075 ,new HrefChangeData() 076 ,new NoTranHrefChangeData() // 5.6.3.4 (2013/04/26) entry.htm に "noTransitionUrl" が存在するときの処理。 077 ,new FileDownloadChangeData() // 5.6.4.2 (2013/05/17) fileDownload.htm 対応 078 }; 079 080 /** 081 * 変換を行います。 082 * 実際には、各内部クラスのメソッドで処理を行います。 083 * 084 * @og.rev 5.6.4.2 (2013/05/17) JFreeChart の画像ファイル(ChartTempフォルダ) のコピー 085 * 086 * @param file 対象ファイル名 087 * @param inStr 対象データ 088 * 089 * @return 変換後データ 090 */ 091 public String replace( final String file,final String inStr ) { 092 String rtnStr = inStr; 093 094 // query 画面で、登録コマンドが発行された場合の特殊処理 095 if( file.indexOf( "query.htm" ) >= 0 && inStr.indexOf( "name=\"command\" value=\"登録" ) >= 0 ) { 096 rtnStr = inStr.replace( "forward.jsp","entry.htm" ); 097 } 098 099 // 5.6.4.2 (2013/05/17) JFreeChart の画像ファイル(ChartTempフォルダ) のコピー 100 if( inStr.indexOf( "/ChartTemp/" ) >= 0 ) { 101 chartTempFileCopy( file,inStr ); 102 } 103 104 for( int i=0; i<data.length; i++ ) { 105 rtnStr = data[i].replace( file,rtnStr ); 106 } 107 return rtnStr; 108 } 109 110 /** 111 * JFreeChart の画像ファイル(ChartTempフォルダ) のコピーを行います。 112 * これは、Tomcatを停止させずに、ChartTempフォルダ を人手てコピーする予定でしたが、 113 * 万一、停止させると、ファイルが自動削除されるため、自動コピー機能を入れておきます。 114 * 115 * ここの処理は、対象データ(inStr) の文字列変換ではなく、画像ファイルを見つけて、 116 * コピーするという処理を行います。非常に特殊な処理です。 117 * 118 * @og.rev 5.6.4.2 (2013/05/17) 新規追加 119 * 120 * @param file 対象ファイル名 121 * @param inStr 対象データ 122 */ 123 private void chartTempFileCopy( final String file,final String inStr ) { 124 // 以下、決め打ちします。本当は saveDir や、ChartTemp をパラメータから取得すべき 125 // 大前提として、fromDir = filetemp/ChartTemp/ 126 // toDir = filetemp/DIR/ChartTemp/ 127 128 int adrs = file.indexOf( "filetemp/DIR" ); // jsp ファイルの出力先なので、DIR を含んでいます。 129 File fromDir = new File( file.substring( 0,adrs ) + "filetemp/ChartTemp/" ); 130 File toDir = new File( file.substring( 0,adrs ) + "filetemp/DIR/ChartTemp/" ); 131 132 // コピー先ディレクトリが存在しなければ・・・ 133 // 6.0.0.1 (2014/04/25) These nested if statements could be combined 134 if( !toDir.exists() && !toDir.mkdirs() ) { 135 System.err.println( toDir + " の ディレクトリ作成に失敗しました。" ); 136 return ; 137 } 138 139 // 画像ファイル名を求めます。 140 int st = inStr.indexOf( CHART_KEY ) ; 141 while( st >= 0 ) { 142 int ed = inStr.indexOf( ".png" ,st + KEY_LEN ) ; // 検索開始位置は、CHART_KEYの発見場所+文字数 143 String fname = inStr.substring( st + KEY_LEN , ed + 4 ); // + 4 は、".png" の分 144 145 FileUtil.copy( new File( fromDir,fname ) , new File( toDir,fname ) ); 146 147 st = inStr.indexOf( CHART_KEY , ed + 4 ) ; 148 } 149 } 150 151 /** 152 * 個々の変換データを管理している、データクラス 153 * このクラスは、不変クラスのため、マルチスレッドでの同時使用に対して、安全です。 154 * 155 */ 156 private static class ChangeData { 157 private final String filename ; 158 private final String org ; 159 private final String rep ; 160 161 /** 162 * デフォルトコンストラクター 163 * サブクラス作成用に用意された、コンストラクタ。このクラス自身には不要。 164 */ 165 public ChangeData() { 166 this( null,null,null ); 167 } 168 169 /** 170 * コンストラクター 171 * 初期設定を行います。 172 * 対象ファイル名は、処理を実行するかどうかの判定に使用します。 173 * 指定の文字列が含まれているかどうかで判定します。 174 * null の場合は、すべてのファイルを対象にします。 175 * 176 * @param filename 対象ファイル名 177 * @param org 変換元データ 178 * @param rep 変換後データ 179 */ 180 public ChangeData( final String filename,final String org,final String rep ) { 181 this.filename = filename; 182 this.org = org; 183 this.rep = rep; 184 } 185 186 /** 187 * 実際に変換を行うメソッド 188 * 内部的には、入力文字列.replaceAll( 変換元,変換後 ) メソッドを実行します。 189 * 190 * @param file 対象ファイル名 191 * @param inStr 対象データ 192 * @return 変換後データ 193 */ 194 public String replace( final String file,final String inStr ) { 195 String rtnStr = inStr; 196 if( filename == null || file.indexOf( filename ) >= 0 ) { 197 rtnStr = inStr.replaceAll( org,rep ); 198 } 199 return rtnStr; 200 } 201 202 /** 203 * このオブジェクトの文字列表現 204 * "ChangeData( " + filename + " , " + org + " , " + rep + " )" を返します。 205 * 206 * @return 文字列表現 207 */ 208 @Override 209 public String toString() { 210 return "ChangeData( " + filename + " , " + org + " , " + rep + " )" ; 211 } 212 } 213 214 /** 215 * マトリクスメニュー対応のデータ置き換えクラスです。 216 * jsp/ は、先に、../ に変換済みなので、その "../" からの検索条件で判断します。 217 * multiMenu と、matrixMenu は、標準は、menu フォルダですが、場合によっては、custom フォルダに存在する 218 * 場合があるため、menu/ は検索条件に含めません。 219 * ③と④は、変換処理は無いはずなので、ロジックは記述していません。 220 * 221 * matrixMenu対応 222 * URI分離 URI分離 request取出 223 * ① gamenId="jsp" + index.jsp + GAMENID=XXXX ⇒ saveDir + "jsp/indexXXXX.htm" Matrixメニューからの画面呼出し。 224 * ② gamenId="jsp" + result.jsp + GAMENID=XXXX ⇒ saveDir + "jsp/indexXXXX.htm" 画面QUERYのヘッダーメニュー 225 * ③ gamenId="menu" + multiMenu.jsp + group=YYYY ⇒ saveDir + "menu/menuYYYY.htm" 通常メニューのグループ選択 226 * ④ gamenId="menu" + matrixMenu.jsp + group=YYYY ⇒ saveDir + "menu/matrixMenuYYYY.htm" Matrixメニューのグループ選択 227 * 228 * このクラスは、不変クラスのため、マルチスレッドでの同時使用に対して、安全です。 229 * 230 * @og.rev 4.3.3.0 (2008/10/01) Matrixメニュー対応 231 * @og.rev 5.5.2.5 (2012/05/21) TopMenuTag の ONELEVEL メニューリンク対応 232 * @og.rev 5.6.4.2 (2013/05/17) 正規表現修正、判定条件変更 233 */ 234 private static final class IndexMatrixMenuData extends ChangeData { 235 public String replace( final String file,final String inStr ) { 236 String rtnStr = inStr; 237 238 // 5.6.4.2 (2013/05/17) 正規表現修正、判定条件変更 239 // ① gamenId="jsp" + index.jsp + GAMENID=XXXX ⇒ saveDir + "jsp/indexXXXX.htm" Matrixメニューからの画面呼出し。 240 // ④ gamenId="menu" + matrixMenu.jsp + group=YYYY ⇒ saveDir + "menu/matrixMenuYYYY.htm" Matrixメニューのグループ選択 241 if( file.indexOf( "matrixMenu" ) >= 0 ) { 242 rtnStr = rtnStr.replaceAll( "../index.htm\\?[^\"]*GAMENID=([^&\"]*)[^\"]*\"","../jsp/index$1.htm\"" ); // ① 243 rtnStr = rtnStr.replaceAll( "matrixMenu.htm\\?[^\"]*group=([^&\"]*)[^\"]*\"","matrixMenu$1.htm\"" ); // ④ 244 rtnStr = rtnStr.replaceAll( "=\"../../../mr/jsp/","=\"../" ); 245 } 246 // ② gamenId="jsp" + result.jsp + GAMENID=XXXX ⇒ saveDir + "XXXX/index.htm" 画面QUERYのヘッダーメニュー 247 else if( file.indexOf( "query" ) >= 0 ) { 248 rtnStr = rtnStr.replaceAll( "../result.htm\\?[^\"]*GAMENID=([^&\"]*)[^\"]*\"","../jsp/index$1.htm\"" ); // ② 249 } 250 // ③ gamenId="menu" + multiMenu.jsp + group=YYYY ⇒ saveDir + "jsp/menuYYYY.htm" 通常メニューのグループ選択 251 else if( file.indexOf( "multiMenu" ) >= 0 || file.indexOf( "menu" ) >= 0 || file.indexOf( "normalMenu" ) >= 0 ) { 252 rtnStr = rtnStr.replaceAll( "multiMenu.htm\\?[^\"]*group=([^&\"]*)[^\"]*\"","menu$1.htm\"" ); // ③ 253 } 254 return rtnStr; 255 } 256 257 /** 258 * このオブジェクトの文字列表現 259 * "IndexMatrixMenuData()" を返します。 260 * 261 * @return 文字列表現 262 */ 263 @Override 264 public String toString() { 265 return "IndexMatrixMenuData()" ; 266 } 267 } 268 269 /** 270 * index.htm のコマンド単位のファイル名の置き換えクラスです。 271 * このクラスは、不変クラスのため、マルチスレッドでの同時使用に対して、安全です。 272 * 273 */ 274 private static final class IndexChangeData extends ChangeData { 275 // <a href="aaaa/index.htm?command=RENEW&GAMENID=bbbb 形式とマッチし、index.htm 部分を前方参照します。 276 private static final Pattern PTN1 = Pattern.compile( "index.htm\\?[^\"]*command=(NEW|RENEW)" ); 277 278 public String replace( final String file,final String inStr ) { 279 String rtnStr = inStr; 280 // if( file.indexOf( "query" ) >= 0 ) { // query の場合 281 Matcher mch = PTN1.matcher( rtnStr ); 282 int adrs = 0; 283 while( mch.find( adrs ) ) { 284 int indx = mch.start() ; 285 String cmd = mch.group(1); // command=(NEW|RENEW) 部分の()内文字列 286 // index.htm 文字列部に、NW または RNW を追加し、indexNW.html を作成する。 287 if( "NEW".equalsIgnoreCase( cmd ) ) { 288 rtnStr = rtnStr.substring(0,indx+5) + "NW" + rtnStr.substring(indx+5) ; 289 } 290 else if( "RENEW".equalsIgnoreCase( cmd ) ) { 291 rtnStr = rtnStr.substring(0,indx+5) + "RNW" + rtnStr.substring(indx+5) ; 292 } 293 adrs = mch.end() ; 294 mch.reset( rtnStr ); 295 } 296 // } 297 return rtnStr; 298 } 299 300 /** 301 * このオブジェクトの文字列表現 302 * "IndexChangeData()" を返します。 303 * 304 * @return 文字列表現 305 */ 306 @Override 307 public String toString() { 308 return "IndexChangeData()" ; 309 } 310 } 311 312 /** 313 * コマンド転送先を、onClick="location.href=XXX" で指定するように、変換します。 314 * <input type="hidden" name="hX_複写(C)" value="copy.htm" /> を見つけ、 315 * 前方参照で、複写(C) と、copy.htm を取り出します。 316 * その後、<input name="command" value="複写(C)" という文字列をキーに、 317 * <input name="command" onClick="location.href='copy.htm'" value="複写(C)" という 318 * 文字列に置き換えます。 319 * これにより、ボタンを押したときに、ボタンごとに異なる画面に遷移します。 320 * 前提条件として、下記の項目を満たしておく必要がある。 321 * ・form には、onSubmit="return false;" を記述し、フォームを無効化しておく。 322 * ・input タグの type="submit" を、type="button" にしておく。(ボタンイベント) 323 * ・query.htm 以外のファイルのみ適用。location.href では、フレームのtarget指定 324 * まで行っていない。 325 * ・上と同意で、query.htm の登録時処理は、別に行う。 326 * 327 * @og.rev 5.5.2.5 (2012/05/21) update.jsp に出力されるファイルを、コマンド名.htm に出力するように機能追加 328 * @og.rev 5.6.4.2 (2013/05/17) 3ペイン、エントリなど、特殊な画面にフラグを付けます。(TARGET_CHANGE_SET) 329 */ 330 private static final class HrefChangeData extends ChangeData { 331 private static final String PTN1 = "<input type=\"hidden\" name=\"hX_([^\"]*)\" value=\"([^\"]*.htm)" ; 332 private static final Pattern ptnObj1 = Pattern.compile( PTN1 ); 333 334 // 5.5.7.2 (2012/10/09) 定数名の変更 335 private static final String ORG = "<input name=\"command\"" ; 336 private static final String SELF = "<input name=\"command\" onClick=\"location.href='" ; 337 private static final String PRNT = "<input name=\"command\" onClick=\"parent.location.href='" ; 338 private static final String TOP = "<input name=\"command\" onClick=\"top.location.href='" ; 339 340 // 5.5.7.2 (2012/10/09) formのtargetを取得。location.href に利用する。 341 private static final String PTN2 = "<form .*target=\"([^\"]*)\"" ; 342 private static final Pattern ptnObj2 = Pattern.compile( PTN2 ); 343 344 /** 345 * コマンド転送先を、onClick="location.href=XXX" で指定するように、変換します。 346 * <input type="hidden" name="hX_複写(C)" value="copy.htm" /> を見つけ、 347 * 前方参照で、複写(C) と、copy.htm を取り出します。 348 * その後、<input name="command" value="複写(C)" という文字列をキーに、 349 * <input name="command" onClick="location.href='copy.htm'" value="複写(C)" という 350 * 文字列に置き換えます。 351 * 352 * @og.rev 5.5.2.5 (2012/05/21) update.jsp に出力されるファイルを、コマンド名.htm に出力するように機能追加 353 * @og.rev 5.5.7.2 (2012/10/09) 定数名の変更。formのtargetを加味した、location.href を作成する。 354 * @og.rev 5.6.4.2 (2013/05/17) 3ペイン、エントリなど、特殊な画面にフラグを付けます。(TARGET_CHANGE_SET) 355 * 356 * @param file 対象ファイル名 357 * @param inStr 対象データ 358 * @return 変換後データ 359 */ 360 public String replace( final String file,final String inStr ) { 361 String rtnStr = inStr; 362 if( file.indexOf( "query.htm" ) < 0 ) { // query.htm 以外の場合 363 // 5.5.7.2 (2012/10/09) formのtargetを加味した、location.href を作成する。 364 Matcher mch2 = ptnObj2.matcher( rtnStr ); 365 String ptnHref = SELF; // 標準は、location.href 366 if( mch2.find() ) { 367 // 5.6.4.2 (2013/05/17) 3ペイン、エントリなど、特殊な画面にフラグを付けます。(TARGET_CHANGE_SET) 368 int indx = file.lastIndexOf( '/' ); 369 String fileKey = file.substring( 0,indx ); 370 371 String frmTgt = mch2.group(1); 372 if( "CONTENTS".equals( frmTgt ) ) { ptnHref = PRNT; } 373 else if( "_top".equals( frmTgt ) ) { ptnHref = TOP; } 374 else if( !"RESULT".equals( frmTgt ) && frmTgt != null ) { 375 ptnHref = "<input name=\"command\" onClick=\"parent." + frmTgt + ".location.href='" ; 376 // 5.6.4.2 (2013/05/17) ある画面で、特殊なターゲット(INPUT,BUTTOMなど)を使用している場合に記憶 377 TARGET_CHANGE_SET.add( fileKey ); // 別のファイルを処理するときに参照する。 378 } 379 else { 380 // 5.6.4.2 (2013/05/17) ある画面で、特殊なターゲット(INPUT,BUTTOMなど)を使用している場合のチェック 381 if( TARGET_CHANGE_SET.contains( fileKey ) ) { 382 ptnHref = PRNT ; 383 } 384 } 385 } 386 387 Matcher mch = ptnObj1.matcher( rtnStr ); 388 int adrs = 0; 389 while( mch.find( adrs ) ) { 390 String cmd = mch.group(1); 391 if( !cmd.endsWith( "CMD" ) ) { 392 String val = mch.group(2); 393 String str1 = ORG + " value=\"" + cmd ; 394 String str2 ; 395 396 if( val != null && val.startsWith( "../" ) ) { 397 str2 = PRNT + val + "'\" value=\"" + cmd ; 398 } 399 // 5.5.2.5 (2012/05/21) update.jsp に出力されるファイルを、コマンド名.htm に出力するように機能追加 400 else if( val != null && val.startsWith( "update" ) ) { 401 str2 = ptnHref + cmd + ".htm'\" value=\"" + cmd ; 402 } 403 else { 404 str2 = ptnHref + val + "'\" value=\"" + cmd ; 405 } 406 rtnStr = rtnStr.replace( str1,str2 ); 407 } 408 adrs = mch.end(); 409 mch.reset( rtnStr ); 410 } 411 } 412 return rtnStr; 413 } 414 415 /** 416 * このオブジェクトの文字列表現 417 * "HrefChangeData()" を返します。 418 * 419 * @return 文字列表現 420 */ 421 @Override 422 public String toString() { 423 return "HrefChangeData()" ; 424 } 425 } 426 427 /** 428 * 雛形自動作成 で、useAjaxSubmit="true" の対策 429 * 430 * update.jsp で、useAjaxSubmit="true" の場合、entry.htm は、update.jsp の 431 * JavaScriptでforward されるため、雛形には、HTMLの結果は出力されません。 432 * (result.jsp に出力されます。) 433 * そこで、雛形作成時には、entry.htm にJavaScriptを入れて、forward させます。 434 * このクラスは、不変クラスのため、マルチスレッドでの同時使用に対して、安全です。 435 * 挿入するのは、BODYタグの最後です。BODYタグがなければ、最後に追加します。 436 * 437 * @og.rev 5.6.3.4 (2013/04/26) entry.htm に "noTransitionUrl" が存在するときの処理。 438 */ 439 private static final class NoTranHrefChangeData extends ChangeData { 440 private static final String BODY_END = "</body>" ; 441 private static final String APPEND_JS = "<script type=\"text/javascript\" src=\"../common/option/noTranHref.js\" ><!-- --></script>" ; 442 443 public String replace( final String file,final String inStr ) { 444 String rtnStr = inStr; 445 // entry.jsp で、かつ noTransitionUrl 文字列を含む場合のみ 446 if( file.indexOf( "entry" ) >= 0 && inStr.indexOf( "noTransitionUrl" ) >= 0 ) { 447 int adrs = inStr.indexOf( BODY_END ); 448 if( adrs > 0 ) { // </body> タグが存在した場合は、その直前に挿入する。 449 rtnStr = inStr.substring( 0,adrs ) + APPEND_JS + inStr.substring( adrs ) ; 450 } 451 else { // 存在しない場合は、最後に挿入する。 452 rtnStr = inStr + APPEND_JS ; 453 } 454 } 455 return rtnStr; 456 } 457 458 /** 459 * このオブジェクトの文字列表現 460 * "NoTranHrefChangeData()" を返します。 461 * 462 * @return 文字列表現 463 */ 464 @Override 465 public String toString() { 466 return "NoTranHrefChangeData()" ; 467 } 468 } 469 470 /** 471 * 雛形自動作成 で、fileDownload の日本語名対応 472 * 473 * 標準的な、fileDownload 処理では、../common/fileDownload.jsp?・・・・GAMENID=XXXX&filename=YYYY" と 474 * なっており、filename 部分は、日本語にも対応できるように urlEncode されています。 475 * これを、元に戻さないとうまくダウンロードできませんでした。 476 * 477 * ※ 参考情報 478 * 1.urlEncode のままで、ファイル名を取得する場合は、下記の標準系で対応可能です。 479 * ,new ChangeData( null ,"../common/fileDownload.htm\\?[^\"]*filename=([^&\"]*)[^\"]*\"","$1\"" ) 480 * 2.ファイル名を、fileDownload.xls 固定にする場合は、下記の標準系で対応可能です。 481 * ,new ChangeData( null ,"../common/fileDownload.htm\\?[^\"]*\"","fileDownload.xls\"" ) 482 * 483 * @og.rev 5.6.4.2 (2013/05/17) 新規追加 484 */ 485 private static final class FileDownloadChangeData extends ChangeData { 486 private static final String PTN1 = "../common/fileDownload.htm\\?[^\"]*filename=([^&\"]*)[^\"]*\"" ; 487 private static final Pattern ptnObj1 = Pattern.compile( PTN1 ); 488 489 public String replace( final String file,final String inStr ) { 490 String rtnStr = inStr; 491 // entry.jsp で、かつ noTransitionUrl 文字列を含む場合のみ 492 if( rtnStr.indexOf( "../common/fileDownload.htm" ) >= 0 ) { 493 Matcher mch = ptnObj1.matcher( rtnStr ); 494 int adrs = 0; 495 while( mch.find( adrs ) ) { 496 String fname = mch.group(1); 497 fname = StringUtil.urlDecode( fname ); // デコードしています。 498 499 int indx = mch.start() ; 500 adrs = mch.end(); 501 rtnStr = rtnStr.substring( 0,indx ) + fname + "\"" + rtnStr.substring( adrs ) ; 502 503 mch.reset( rtnStr ); 504 } 505 } 506 return rtnStr; 507 } 508 509 /** 510 * このオブジェクトの文字列表現 511 * "FileDownloadChangeData()" を返します。 512 * 513 * @return 文字列表現 514 */ 515 @Override 516 public String toString() { 517 return "FileDownloadChangeData()" ; 518 } 519 } 520}