    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        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}