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