    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.taglib;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020import org.opengion.hayabusa.resource.GUIInfo;
    021import org.opengion.fukurou.db.Transaction;
    022import org.opengion.fukurou.db.TransactionReal;
    023// import org.opengion.fukurou.util.FileUtil;
    024// import org.opengion.fukurou.util.Closer ;
    025import org.opengion.fukurou.util.StringUtil;
    026// import org.opengion.fukurou.xml.HybsXMLSave ;
    027import org.opengion.fukurou.xml.XMLFileLoader;                          // 6.0.0.0 (2014/04/11) XMLFileLoader を使う様に変更
    028
    029import static org.opengion.fukurou.util.StringUtil.nval ;
    030
    031import java.sql.Connection;
    032
    033import java.io.File;
    034// import java.io.BufferedReader;
    035import java.io.StringWriter;                                                            // 6.0.0.0 (2014/04/11) XMLFileLoader に渡す Log
    036import java.util.Map;
    037import java.util.HashMap;
    038import java.util.Arrays;                                                                        // 6.0.0.0 (2014/04/11) keys,vals のエラーメッセージ作成用
    039
    040/**
    041 * 指定の拡張XDK形式ファイルを直接データベースに登録するデータ入力タグです。
    042 *
    043 * このクラスは、オラクル XDKの oracle.xml.sql.dml.OracleXMLSave クラスと
    044 * ほぼ同様の目的で使用できる org.opengion.fukurou.xml.HybsXMLSave のラッパークラスです。
    045 *
    046 * 拡張XDK形式のXMLファイルを読み込み、データベースに INSERT します。
    047 * 拡張XDK形式の元となる オラクル XDK(Oracle XML Developer's Kit)については、以下の
    048 * リンクを参照願います。
    049 * <a href="http://otn.oracle.co.jp/software/tech/xml/xdk/index.html" target="_blank" >
    050 * XDK(Oracle XML Developer's Kit)</a>
    051 *
    052 * このタグでは、keys,vals を登録することにより、XMLファイルに存在しないカラムを
    053 * 追加したり、XMLファイルの情報を書き換えることが可能になります。
    054 * 例えば、登録日や、登録者、または、テンプレートより各システムID毎に
    055 * 登録するなどです。
    056 *
    057 * 拡張XDK形式とは、ROW 以外に、SQL処理用タグ(EXEC_SQL)を持つ XML ファイルです。
    058 * また、登録するテーブル(table)を ROWSETタグの属性情報として付与することができます。
    059 * (大文字小文字に注意)
    060 * これは、オラクルXDKで処理する場合、無視されますので、同様に扱うことが出来ます。
    061 * この、EXEC_SQL は、それそれの XMLデータをデータベースに登録する際に、
    062 * SQL処理を自動的に流す為の、SQL文を記載します。
    063 * この処理は、イベント毎に実行される為、その配置順は重要です。
    064 * このタグは、複数記述することも出来ますが、BODY部には、１つのSQL文のみ記述します。
    065 *
    066 * 6.0.0.0 (2014/04/11)
    067 *   指定のファイルがフォルダの場合は、以下のファイルすべて(拡張子はxml)を対象に読込-登録します。
    068 *   また、拡張子が、zip の場合は、zip内部の xml ファイルを読込-登録します。
    069 *
    070 * ※ このタグは、Transaction タグの対象です。
    071 *
    072 *   &lt;ROWSET tableName="XX" &gt;
    073 *       &lt;EXEC_SQL&gt;                    最初に記載して、初期処理(データクリア等)を実行させる。
    074 *           delete from GEXX where YYYYY
    075 *       &lt;/EXEC_SQL&gt;
    076 *       &lt;MERGE_SQL&gt;                   このSQL文で UPDATEして、結果が０件ならINSERTを行います。
    077 *           update GEXX set AA=[AA] , BB=[BB] where CC=[CC]
    078 *       &lt;/MERGE_SQL&gt;
    079 *       &lt;ROW num="1"&gt;
    080 *           &lt;カラム1&gt;値1&lt;/カラム1&gt;
    081 *             ･･･
    082 *           &lt;カラムn&gt;値n&lt;/カラムn&gt;
    083 *       &lt;/ROW&gt;
    084 *        ･･･
    085 *       &lt;ROW num="n"&gt;
    086 *          ･･･
    087 *       &lt;/ROW&gt;
    088 *       &lt;EXEC_SQL&gt;                    最後に記載して、項目の設定(整合性登録)を行う。
    089 *           update GEXX set AA='XX' , BB='XX' where YYYYY
    090 *       &lt;/EXEC_SQL&gt;
    091 *   &lt;ROWSET&gt;
    092 *
    093 * @og.formSample
    094 * ●形式：&lt;og:directXMLSave fileURL="[･･･]" ･･･ /&gt;
    095 * ●body：なし
    096 *
    097 * ●Tag定義：
    098 *   &lt;og:directXMLSave
    099 *       dbid               【TAG】(通常は使いません)検索時のDB接続IDを指定します(初期値:DEFAULT)
    100 *       fileURL            【TAG】読み取り元ディレクトリ名を指定します (初期値:FILE_URL[=filetemp/])
    101 *       filename           【TAG】ファイルを作成するときのファイル名をセットします (初期値:null)
    102 *       displayMsg         【TAG】query の結果を画面上に表示するメッセージIDを指定します(初期値:MSG0003[ファイルの登録が完了しました。])
    103 *       keys               【TAG】XMLファイルを読み取った後で指定するキーをCSV形式で複数指定します
    104 *       vals               【TAG】XMLファイルを読み取った後で指定する値をCSV形式で複数指定します
    105 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    106 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    107 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true)
    108 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true)
    109 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    110 *   /&gt;
    111 *
    112 * ●使用例
    113 *     &lt;og:directXMLSave
    114 *         dbid         = "ORCL"                接続データベースID(初期値:DEFAULT)
    115 *         fileURL      = "{&#064;USER.ID}"     読み取り元ディレクトリ名
    116 *         filename     = "{&#064;filename}"    読み取り元ファイル名
    117 *         displayMsg   = "MSG0003"             登録完了後のメッセージ
    118 *     /&gt;
    119 *
    120 * @og.group ファイル入力
    121 * @og.rev 4.0.0.0 (2007/03/08) 新規追加
    122 * @og.rev 6.0.0.0 (2014/04/11) 単体ファイル以外（フォルダ、ZIPファイル）への対応
    123 *
    124 * @version  4.0
    125 * @author   Kazuhiko Hasegawa
    126 * @since    JDK5.0,
    127 */
    128public class DirectXMLSaveTag extends CommonTagSupport {
    129        //* このプログラムのVERSION文字列を設定します。   {@value} */
    130        private static final String VERSION = "6.0.0.0 (2014/04/11)" ;
    131
    132        private static final long serialVersionUID = 600020140411L ;
    133
    134//      private static final String ENCODE = "UTF-8";           // 6.0.0.0 (2014/04/11) XMLFileLoader を使うため、廃止
    135        private String  dbid            = null;
    136        private String  fileURL         = HybsSystem.sys( "FILE_URL" );                 // 4.0.0 (2005/01/31)
    137//      private String  filename        = HybsSystem.sys( "FILE_FILENAME" );    // ファイル名
    138        private String  filename        = null;                                                                 // 6.0.0.0 (2014/04/11) 初期値:null
    139//      private String  displayMsg      = "MSG0040";    // 　件登録しました。
    140        private String  displayMsg      = "MSG0003";    // ファイルの登録が完了しました。
    141        private String[]        keys    = null;
    142        private String[]        vals    = null;
    143        private long    dyStart         = 0;    // 実行時間測定用のDIV要素を出力します。
    144
    145        /**
    146         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    147         *
    148         * @og.rev 5.6.6.1 (2013/07/12) caseKey 、caseVal 属性対応
    149         *
    150         * @return      後続処理の指示( SKIP_BODY )
    151         */
    152        @Override
    153        public int doStartTag() {
    154                // 5.6.6.1 (2013/07/12) caseKey 、caseVal 属性対応
    155                if( useTag() ) {
    156                        dyStart = System.currentTimeMillis();           // 時間測定用
    157                }
    158                return SKIP_BODY ;      // Body を評価しない
    159        }
    160
    161        /**
    162         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    163         *
    164         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel )
    165         * @og.rev 4.0.0.1 (2007/12/03) try ～ catch ～ finally をきちんと行う。
    166         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応
    167         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    168         * @og.rev 5.5.2.6 (2012/05/25) findbugs対応。例外経路で null 値を利用することが保証されています。
    169         * @og.rev 5.6.6.1 (2013/07/12) caseKey 、caseVal 属性対応
    170         * @og.rev 5.6.7.0 (2013/07/27) DDL（データ定義言語：Data Definition Language）の処理件数追加
    171         *
    172         * @return      後続処理の指示
    173         */
    174        @Override
    175        public int doEndTag() {
    176                debugPrint();           // 4.0.0 (2005/02/28)
    177                // 5.6.6.1 (2013/07/12) caseKey 、caseVal 属性対応
    178                if( !useTag() ) { return EVAL_PAGE ; }
    179
    180                StringWriter logW = new StringWriter();         // 6.0.0.0 (2014/04/11) XMLFileLoader で Logをセット
    181
    182                // 6.0.0.0 (2014/04/11) XMLFileLoader に渡す 読み取り開始ファイルオブジェクト。
    183                String directory = HybsSystem.url2dir( fileURL );
    184                File loadFile = ( filename != null ) ? new File( directory,filename ) : new File( directory );
    185
    186//              BufferedReader reader   = null;
    187                final int insCnt ;                              // 追加数だけ記録する。
    188//              final int updCnt ;
    189//              final int delCnt ;
    190//              final int ddlCnt ;                              // 5.6.7.0 (2013/07/27) DDL処理件数追加
    191                boolean errFlag = true;
    192                Transaction tran = null;                // 5.1.9.0 (2010/08/01) Transaction 対応
    193                try {
    194                        // 5.1.9.0 (2010/08/01) Transaction 対応
    195                        TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class );
    196                        if( tranTag == null ) {
    197                                tran = new TransactionReal( getApplicationInfo() );             // 5.3.7.0 (2011/07/01) 引数変更
    198                        }
    199                        else {
    200                                tran = tranTag.getTransaction();
    201                        }
    202
    203                        Connection conn = tran.getConnection( dbid );           // 5.1.9.0 (2010/08/01) Transaction 対応
    204
    205                        // 6.0.0.0 (2014/04/11) フォルダ一括登録ができるようにします。
    206                        XMLFileLoader loader = new XMLFileLoader( conn,false ); // リソースコネクションとuseTimeStamp=false 指定
    207                        if( keys != null ) { loader.setAfterMap( getAfterMap() ); }
    208                        loader.setLogWriter( logW );
    209
    210                        loader.loadXMLFiles( loadFile );
    211
    212                        int[] crudCnt = loader.getCRUDCount();  // 実行結果のカウント数
    213                        insCnt = crudCnt[XMLFileLoader.INS];
    214
    215//                      HybsXMLSave save = new HybsXMLSave( conn );
    216//                      if( keys != null ) { save.setAfterMap( getAfterMap() ); }
    217//
    218//                      reader = getBufferedReader();
    219//                      save.insertXML( reader );
    220//                      insCnt = save.getInsertCount();
    221//                      updCnt = save.getUpdateCount();
    222//                      delCnt = save.getDeleteCount();
    223//                      ddlCnt = save.getDDLCount();            // 5.6.7.0 (2013/07/27) DDL処理件数追加
    224                        tran.commit();                  // 5.1.9.0 (2010/08/01) Transaction 対応
    225                        errFlag = false;                // エラーではない
    226                }
    227                catch( Throwable ex ) {
    228                        if( tran != null ) {            // 5.5.2.6 (2012/05/25) findbugs対応
    229                                tran.rollback();                // 5.1.9.0 (2010/08/01) Transaction 対応
    230                        }
    231                        throw new HybsSystemException( ex );
    232                }
    233                finally {
    234                        if( tran != null ) {            // 5.5.2.6 (2012/05/25) findbugs対応
    235                                tran.close( errFlag );
    236                        }
    237//                      Closer.ioClose( reader );
    238                }
    239
    240                // 実行件数の表示
    241                // 4.0.0 (2005/11/30) 出力順の変更。一番最初に出力します。
    242                if( displayMsg != null && displayMsg.length() > 0 ) {
    243                        StringBuilder buf = new StringBuilder();
    244//                      buf.append( "INS:"    ).append( insCnt );
    245//                      buf.append( " / UPD:" ).append( updCnt );
    246//                      buf.append( " / DEL:" ).append( delCnt );
    247//                      buf.append( " / DDL:" ).append( ddlCnt );                               // 5.6.7.0 (2013/07/27) DDL処理件数追加
    248                        buf.append( "<pre>" );
    249                        buf.append( logW.toString() );                                                  // 6.0.0.0 (2014/04/11) XMLFileLoader で Logをセット
    250                        buf.append( HybsSystem.CR );
    251                        buf.append( HybsSystem.getDate() ).append( "  " );
    252                        buf.append( getResource().getLabel( displayMsg ) );
    253                        buf.append( HybsSystem.CR );
    254                        buf.append( "</pre>" );
    255
    256                        jspPrint( buf.toString() );
    257                }
    258
    259                // 時間測定用の DIV 要素を出力
    260                long dyTime = System.currentTimeMillis()-dyStart;
    261                jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" );  // 3.5.6.3 (2004/07/12)
    262
    263                // 4.0.0 (2005/01/31) セキュリティチェック(データアクセス件数登録)
    264                GUIInfo guiInfo = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY );
    265//              if( guiInfo != null ) { guiInfo.addWriteCount( insCnt,dyTime,fileURL + filename ); }
    266                if( guiInfo != null ) { guiInfo.addWriteCount( insCnt,dyTime,loadFile.getPath() ); }
    267
    268                return EVAL_PAGE ;
    269        }
    270
    271        /**
    272         * タグリブオブジェクトをリリースします。
    273         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    274         *
    275         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    276         * @og.rev 6.0.0.0 (2014/04/11) filename の初期値を、システムプロパティーのFILE_FILENAME から null に変更
    277         * @og.rev 6.0.0.0 (2014/04/11) displayMsg の初期値を、MSG0040 から MSG0003 に変更
    278         */
    279        @Override
    280        protected void release2() {
    281                super.release2();
    282                dbid            = null;
    283                fileURL         = HybsSystem.sys( "FILE_URL" );                 // 4.0.0 (2005/01/31)
    284//              filename        = HybsSystem.sys( "FILE_FILENAME" );    // ファイル名
    285                filename        = null;                                                                 // 6.0.0.0 (2014/04/11) 初期値:null
    286//              displayMsg      = "MSG0040";                                                    // 　件登録しました。
    287                displayMsg      = "MSG0003";                                                    // ファイルの登録が完了しました。
    288                keys            = null;
    289                vals            = null;
    290        }
    291
    292        /**
    293         * BufferedReader を取得します。
    294         *
    295         * ここでは、一般的なファイル出力を考慮した BufferedReader を作成します。
    296         *
    297         * @og.rev 6.0.0.0 (2014/04/11) XMLFileLoader を使うため、廃止
    298         *
    299         * @return      ファイル入力用BufferedReaderオブジェクト
    300         */
    301//      private BufferedReader getBufferedReader() {
    302//              if( filename == null ) {
    303//                      String errMsg = "ファイル名がセットされていません。";
    304//                      throw new HybsSystemException( errMsg );
    305//              }
    306//              String directory = HybsSystem.url2dir( fileURL );
    307//              File file = new File( StringUtil.urlAppend( directory,filename ) );
    308//
    309//              BufferedReader out = FileUtil.getBufferedReader( file,ENCODE );
    310//
    311//              return out ;
    312//      }
    313
    314        /**
    315         * XMLファイルを読み取った後で指定するカラムと値のペア(マップ)情報を作成します。
    316         *
    317         * このカラムと値のペアのマップは、オブジェクト構築後に設定される為、
    318         * XMLファイルのキーの存在に関係なく、Mapのキーと値が使用されます。(Map優先)
    319         * key が null や ゼロ文字列の場合は、Map に追加しません。
    320         *
    321         * @og.rev 5.6.6.1 (2013/07/12) key が null や ゼロ文字列の場合は、Map に追加しません。
    322         * @og.rev 6.0.0.0 (2014/04/11) keys と vals の個数チェックを追加
    323         *
    324         * @return      カラムと値のペア(マップ)情報
    325         */
    326        private Map<String,String> getAfterMap() {
    327                // 6.0.0.0 (2014/04/11) keys と vals の個数チェックを追加
    328                if( keys != null && keys.length != vals.length ) {
    329                        String errMsg = "keys と vals の個数が異なります。"
    330                                                                + " keys=" + Arrays.toString( keys )
    331                                                                + " vals=" + Arrays.toString( vals ) ;
    332                        throw new HybsSystemException( errMsg );
    333                }
    334
    335                Map<String,String> map = new HashMap<String,String>();
    336                for( int i=0; i<keys.length; i++ ) {
    337                        if( keys[i] != null && keys[i].length() > 0 ) {         // 5.6.6.1 (2013/07/12)
    338                                map.put( keys[i],vals[i] );
    339                        }
    340                }
    341                return map ;
    342        }
    343
    344        /**
    345         * 【TAG】(通常は使いません)検索時のDB接続IDを指定します(初期値:DEFAULT)。
    346         *
    347         * @og.tag
    348         *   検索時のDB接続IDを指定します。初期値は、DEFAULT です。
    349         *
    350         * @param       id データベース接続ID
    351         */
    352        public void setDbid( final String id ) {
    353                dbid = nval( getRequestParameter( id ),dbid );
    354        }
    355
    356        /**
    357         * 【TAG】読み取り元ディレクトリ名を指定します
    358         *              (初期値:FILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。
    359         *
    360         * @og.tag
    361         * この属性で指定されるディレクトリより、ファイルを読み取ります。
    362         * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、２文字目が、
    363         * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、
    364         * fileURL = "{&#064;USER.ID}" と指定すると、FILE_URL 属性で指定のフォルダの下に、
    365         * さらに、各個人ID別のフォルダの下より、読み取ります。
    366         * (初期値:システム定数のFILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。
    367         *
    368         * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。
    369         *
    370         * @param       url ファイルURL
    371         * @see         org.opengion.hayabusa.common.SystemData#FILE_URL
    372         */
    373        public void setFileURL( final String url ) {
    374                String furl = nval( getRequestParameter( url ),null );
    375                if( furl != null ) {
    376                        char ch = furl.charAt( furl.length()-1 );
    377                        if( ch != '/' && ch != '\\' ) { furl = furl + "/"; }
    378                        fileURL = StringUtil.urlAppend( fileURL,furl );
    379                }
    380        }
    381
    382        /**
    383         * 【TAG】ファイルを作成するときのファイル名をセットします(初期値:null)。
    384         *
    385         * @og.tag
    386         * ファイルを作成するときのファイル名をセットします。
    387         * (初期値:null)。
    388         *
    389         * @og.rev 6.0.0.0 (2014/04/11) filename の初期値を、システムプロパティーのFILE_FILENAME から null に変更
    390         *
    391         * @param   fname ファイル名
    392         */
    393        public void setFilename( final String fname ) {
    394                filename = nval( getRequestParameter( fname ),filename );
    395        }
    396
    397        /**
    398         * 【TAG】query の結果を画面上に表示するメッセージIDを指定します(初期値:MSG0003[ファイルの登録が完了しました。])。
    399         *
    400         * @og.tag
    401         * ここでは、検索結果の件数や登録された件数をまず出力し、
    402         * その次に、ここで指定したメッセージをリソースから取得して
    403         * 表示します。
    404         * 表示させたくない場合は, displayMsg = "" をセットしてください。
    405         * 初期値は、検索件数を表示します。
    406         * ※ この属性には、リクエスト変数({&#064;XXXX})は使用できません。
    407         *
    408         * @param   id ディスプレイに表示させるメッセージ ID
    409         */
    410        public void setDisplayMsg( final String id ) {
    411                if( id != null ) { displayMsg = id; }
    412        }
    413
    414        /**
    415         * 【TAG】XMLファイルを読み取った後で指定するキーをCSV形式で複数指定します。
    416         *
    417         * @og.tag
    418         * XMLファイルを読み取った後で、データを変更できます。
    419         * 変更するカラム名(キー)をCSV形式で指定します。
    420         * XMLファイルにキーが存在していた場合は、vals で指定の値に書き換えます。
    421         * キーが存在していない場合は、ここで指定するキーと値が、データとして
    422         * 追加されます。
    423         * 例えば、登録日や、登録者、または、テンプレートより各システムID毎に
    424         * 登録するなどの使い方を想定しています。
    425         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
    426         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
    427         *
    428         * @param       key リンク先に渡すキー
    429         * @see         #setVals( String )
    430         */
    431        public void setKeys( final String key ) {
    432                keys = getCSVParameter( key );
    433        }
    434
    435        /**
    436         * 【TAG】XMLファイルを読み取った後で指定する値をCSV形式で複数指定します。
    437         *
    438         * @og.tag
    439         * XMLファイルを読み取った後で、データを変更できます。
    440         * 変更する値をCSV形式で指定します。
    441         * XMLファイルにキーが存在していた場合は、vals で指定の値に書き換えます。
    442         * キーが存在していない場合は、ここで指定するキーと値が、データとして
    443         * 追加されます。
    444         * 例えば、登録日や、登録者、または、テンプレートより各システムID毎に
    445         * 登録するなどの使い方を想定しています。
    446         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
    447         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
    448         *
    449         * @param       val keys属性に対応する値
    450         * @see         #setKeys( String )
    451         */
    452        public void setVals( final String val ) {
    453                vals = getCSVParameter( val );
    454        }
    455
    456        /**
    457         * このオブジェクトの文字列表現を返します。
    458         * 基本的にデバッグ目的に使用します。
    459         *
    460         * @return このクラスの文字列表現
    461         */
    462        @Override
    463        public String toString() {
    464                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
    465                                .println( "VERSION"                     ,VERSION                )
    466                                .println( "dbid"                        ,dbid                   )
    467                                .println( "fileURL"                     ,fileURL                )
    468                                .println( "filename"            ,filename               )
    469                                .println( "displayMsg"          ,displayMsg             )
    470                                .println( "dyStart"                     ,dyStart                )
    471                                .println( "Other..."            ,getAttributes().getAttribute() )
    472                                .fixForm().toString() ;
    473        }
    474}