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.db.DBTableModel;
021import org.opengion.hayabusa.db.DBTableModelSorter;
022import org.opengion.hayabusa.db.DBColumn;
023import org.opengion.hayabusa.db.DBTableModelUtil;
024import org.opengion.fukurou.util.StringUtil;
025import org.opengion.fukurou.security.HybsCryptography ;         // 5.7.4.3 (2014/03/28)
026
027import static org.opengion.fukurou.util.StringUtil.nval ;
028
029import java.util.Arrays;
030import java.io.File;
031import java.io.FileFilter;
032import java.io.ObjectOutputStream;
033import java.io.ObjectInputStream;
034import java.io.IOException;
035
036/**
037 * ファイルを検索し、DBTableModel にセットするタグです。
038 *
039 * ファイルの検索結果は、[WRITABLE],LEVEL,FILE_TYPE,PARENT,NAME,LASTMODIFIED,FILE_LENGTH,RWH,[MD5],[TO_PARENT,TO_NAME],[・・・・]
040 * のカラムを持つ DBTableModel にセット されます。このカラムは、固定です。
041 * 並び替えについては、このタグで指定しますが、ファイルの選別(where 条件)は、
042 * BODY 部に記述する fileWhere タグで指定します。(複数指定可能))
043 *
044 * [カラム名]      検索するファイルの属性は、以下のカラム名で作成されます。
045 *     [WRITABLE]       useWritable=trueで、先頭カラムに、WRITABLE カラムが挿入されます。
046 *      LEVEL           ディレクトリを展開する場合のレベル。
047 *      FILE_TYPE       ファイル(F)かディレクトリ(D)であるか判定。
048 *      PARENT          この抽象パス名の親のパス名文字列を返します。
049 *      NAME            この抽象パス名が示すファイルまたはディレクトリの名前を返します。
050 *      LASTMODIFIED    最後に変更された時刻を返します。
051 *      FILE_LENGTH     ファイルの長さを返します。
052 *      RWH             読み込み、書き込み、隠し属性をそれぞれ、r,w,h で表します。
053 *     [MD5]            useMD5=trueで、MD5 というカラムを追加したうえで、ファイルのMD5計算を行います。
054 *     [TO_PARENT]      useUpdateClms=trueで、fileUpdateタグでCOPYやMOVEを行う時に使用する必須となるカラム(TO_PARENT,TO_NAME)を追加します。
055 *     [TO_NAME]        同上
056 *     [・・・・]           addClms属性で指定されたカラムを追加します。
057 *
058 * @og.formSample
059 * ●形式:<og:fileQuery from="…" multi="true/false" >
060 *             <og:fileWhere … />
061 *              …
062 *         </og:fileQuery>
063 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
064 *
065 * ●Tag定義:
066 *   <og:fileQuery
067 *       from             ○【TAG】検索を開始するファイルまたはディレクトリを指定します(必須)。
068 *       multi              【TAG】多段階展開するか、1レベル展開するかどうか[true:多段階/false:1レベル]を指定します(初期値:false:1レベル)。
069 *       level              【TAG】多段階展開するレベルを指定します(初期値:100)。
070 *       orderBy            【TAG】ソートするカラム名を指定します(一つのみ)。
071 *       desc               【TAG】表示順を逆転するかどうか[true/false]を指定します(初期値:false)。
072 *       useWritable        【TAG】先頭カラムに、WRITABLE カラムを追加するかどうか[true/false]を指定します(初期値:false)。
073 *       useMD5             【TAG】MD5カラムを追加したうえで、MD5計算を行うかどうか[true/false]を指定します(初期値:false)。
074 *       useUpdateClms      【TAG】TO_PARENT、TO_NAMEカラムを追加するかどうか[true/false]を指定します(初期値:false)。
075 *       addClms            【TAG】検索結果のカラム列に追加するカラム名を、カンマ区切り文字で指定します。
076 *       fileType           【TAG】選択対象[FILE/DIR]を指定します。下位展開は考慮(multi 属性準拠)されます。
077 *       addFrom            【TAG】from属性で指定された基準ファイル/フォルダ自体をリストに追加するかどうか[true/false]を指定します(初期値:true)。
078 *       command            【TAG】コマンド(NEW,RENEW)をセットします("NEW" と "RENEW" 時のみ実行する(初期値:NEW))。
079 *       maxRowCount        【TAG】(通常は使いません)データの最大読み込み件数を指定します (初期値:DB_MAX_ROW_COUNT[=1000])(0:[無制限])。
080 *       displayMsg         【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します (初期値:VIEW_DISPLAY_MSG[=])v
081 *       overflowMsg        【TAG】検索データが最大検索数をオーバーした場合に表示するメッセージリソースIDを指定します (初期値:MSG0007[検索結果が、制限行数を超えましたので、残りはカットされました])。
082 *       notfoundMsg        【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])。
083 *       stopZero           【TAG】検索結果が0件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])
084 *       tableId            【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
085 *       scope              【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session)。
086 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)。
087 *   >   ... Body ...
088 *   </og:fileQuery>
089 *
090 * ●使用例
091 *    ・一般的な属性でファイルの検索を行います。
092 *         <og:fileQuery
093 *                from    = "d:/webapps/dbdef/jsp/"
094 *                multi   = "true"
095 *                command = "{@command}"  >
096 *            <og:fileWhere endWith=".jsp" />
097 *      </og:fileQuery>
098 *
099 *    ・最終変更日で逆順ソートする。対象は、2002/10/01 以降に変更されたファイル。
100 *        <og:fileQuery
101 *                from    = "d:/webapps/dbdef/jsp/"
102 *                multi   = "true"
103 *                orderBy = "LASTMODIFIED"
104 *                desc    = "true"
105 *                command = "{@command}"  >
106 *            <og:fileWhere lastModified="20021001000000" />
107 *        </og:fileQuery>
108 *
109 * @og.rev 4.0.0.0 (2005/01/31) 内部ロジック改定
110 * @og.group その他入力
111 *
112 * @version  4.0
113 * @author       Kazuhiko Hasegawa
114 * @since    JDK5.0,
115 */
116public class FileQueryTag extends QueryTag {
117        //* このプログラムのVERSION文字列を設定します。   {@value} */
118        private static final String VERSION = "5.7.4.3 (2014/03/28)" ;
119
120        private static final long serialVersionUID = 574320140328L ;
121
122        private static final String[] SELECT =
123                                new String[] { "LEVEL","FILE_TYPE","PARENT","NAME","LASTMODIFIED","FILE_LENGTH","RWH" };
124
125        private static final String[] USE_UPDATE_CLM = new String[] { "TO_PARENT","TO_NAME" };  // 5.3.4.0 (2011/04/01)
126
127        private transient FileFilter filter     = null;                                                 // FileWhere で指定したフィルター
128
129        private boolean         multi                   = false;                                                // 下位層展開フラグ
130        private int                     level                   = 100;                                                  // 展開レベル
131        private String      from                        = HybsSystem.sys( "FILE_URL" ); // 検索起点ファイル
132        private String          orderBy                 = null;                                                 // 5.3.4.0 (2011/04/01) ソートカラム
133        private boolean         desc                    = false;                                                // 5.3.4.0 (2011/04/01) ソートの方向(true:逆順)
134        private String[]        addClms                 = new String[0];                                // 5.3.4.0 (2011/04/01) 追加カラム配列
135        private String[]        defClms                 = null;                                                 // 5.7.4.3 (2014/03/28) 初期値のカラム配列
136        private String          fileType                = null;                                                 // 5.3.4.0 (2011/04/01) 選択対象を指定(FILE,DIR)
137        private boolean         useWritable             = false;                                                // 5.7.4.3 (2014/03/28) 先頭カラムに、WRITABLE カラムを追加するかどうか[true/false](初期値:false)
138        private boolean         useMD5                  = false;                                                // 5.7.4.3 (2014/03/28) MD5カラムを追加したうえで、MD5計算を行うかどうか[true/false](初期値:false)
139        private boolean         useUpdateClms   = false;                                                // 5.3.4.0 (2011/04/01) TO_PARENT、TO_NAMEカラムを追加(true:追加)
140        private boolean         addFrom                 = true;                                                 // 5.3.9.0 (2011/09/01) from属性で指定された基準ファイル/フォルダ自体をリストに追加するかどうか
141
142        /**
143         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
144         *
145         * @og.rev 5.3.4.0 (2011/04/01) 指定カラムのソート処理機能追加
146         * @og.rev 5.3.5.0 (2011/05/01) 最初のファイルが存在する場合のみ、実行する。
147         *
148         * @return      後続処理の指示(SKIP_BODY)
149         */
150        @Override
151        public int doAfterBody() {
152                executeCount = 0;
153
154                table = initDBTable();
155                if( maxRowCount < 0 ) {
156                        maxRowCount     = sysInt( "DB_MAX_ROW_COUNT" ) ;
157                }
158
159                // 5.3.5.0 (2011/05/01) 最初のファイルが存在する場合のみ、実行する。
160                File fin = new File( from );
161                if( fin.exists() ) {
162                        execute( fin,0 ) ;
163
164                        // 5.3.4.0 (2011/04/01) 指定カラムのソート処理
165                        if( orderBy != null ) {
166                                int clmNo = table.getColumnNo( orderBy );
167                                DBTableModelSorter temp = new DBTableModelSorter();
168                                temp.setModel( table );
169                                temp.sortByColumn( clmNo,!desc );       // 注意 desc の値と ソート正逆は、反対です。
170                                table = temp;
171                        }
172                }
173
174                return SKIP_BODY ;
175        }
176
177        /**
178         * タグリブオブジェクトをリリースします。
179         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
180         *
181         * @og.rev 5.3.4.0 (2011/04/01) 指定カラムのソート処理機能、カラム追加機能、fileType追加
182         * @og.rev 5.3.9.0 (2011/09/01) addFrom属性追加
183         * @og.rev 5.7.4.3 (2014/03/28) useWritable,useMD5属性追加。valClms を defClms に置き換え。
184         */
185        @Override
186        protected void release2() {
187                super.release2();
188                multi                   = false;
189                level                   = 100;
190                from                    = HybsSystem.sys( "FILE_URL" );
191                filter                  = null;
192                orderBy                 = null;                         // 5.3.4.0 (2011/04/01) ソートカラム
193                desc                    = false;                        // 5.3.4.0 (2011/04/01) 降順フラグ
194                addClms                 = new String[0];        // 5.3.4.0 (2011/04/01) 追加カラム配列
195                defClms                 = null;                         // 5.7.4.3 (2014/03/28) 初期値のカラム配列
196                fileType                = null;                         // 5.3.4.0 (2011/04/01) 選択対象を指定(FILE,DIR,ALL)
197                useWritable             = false;                        // 5.7.4.3 (2014/03/28) 先頭カラムに、WRITABLE カラムを追加するかどうか[true/false](初期値:false)
198                useMD5                  = false;                        // 5.7.4.3 (2014/03/28) MD5カラムを追加したうえで、MD5計算を行うかどうか[true/false](初期値:false)
199                useUpdateClms   = false;                        // 5.3.4.0 (2011/04/01) TO_PARENT、TO_NAMEカラムを追加(true:追加)
200                addFrom                 = true;                         // 5.3.9.0 (2011/09/01) addFrom属性追加
201        }
202
203        /**
204         * FileQuery を実行します。
205         *
206         * @og.rev 5.3.4.0 (2011/04/01) fileType の条件に合致する場合だけ、データを作成する。
207         * @og.rev 5.3.7.0 (2011/07/01) フォルダにアクセスできない場合は、null となるのでその対応
208         * @og.rev 5.3.9.0 (2011/09/01) addFrom属性追加
209         *
210         * @param       fin     検索を開始するファイル/ディレクトリ
211         * @param       lvl     階層展開レベル
212         */
213        protected void execute( final File fin,final int lvl ) {
214                if( ( !multi && lvl > 1 ) || lvl > level ) { return; }  // 階層展開する、しない
215                if( executeCount > maxRowCount ) { table.setOverflow( true ); return; }
216
217                boolean isDIR = fin.isDirectory();
218
219                if( fileType == null ||
220                        (  isDIR &&  "DIR".equalsIgnoreCase( fileType ) ) ||
221                        ( !isDIR && "FILE".equalsIgnoreCase( fileType ) ) ) {
222                                if( addFrom || ( !addFrom && lvl > 0 ) ) {
223                                        addFileData( executeCount++,lvl,fin );
224                                }
225                }
226                if( isDIR ) {
227                        File[] list = fin.listFiles( filter );
228                        // 5.3.7.0 (2011/07/01) フォルダにアクセスできない場合は、null となる。
229                        if( list != null ) {
230                                for( int i = 0; i < list.length; i++ ) {
231                                        execute( list[i],lvl+1 );
232                                }
233                        }
234                }
235        }
236
237        /**
238         * 初期化された DBTableModel を返します。
239         *
240         * ここでは、useWritable、useMD5、useUpdateClms、addClms を加味した
241         * DBTableModel と初期値データ(defClms)を作成します。
242         * 以前は、TO_PARENT、TO_NAMEと、addClms 分のみ初期値を持っていましたが、
243         * 5.7.4.3 (2014/03/28)で、先頭カラムのWRITABLEの初期値を、DBColumn の初期値ではなく
244         * 手動設定する必要がある為、すべてのカラム列の初期値を持っておきます。
245         *
246         * @og.rev 5.3.4.0 (2011/04/01) 指定カラム追加機能追加
247         * @og.rev 5.7.4.3 (2014/03/28) useWritable,useMD5属性追加
248         *
249         * @return       テーブルモデル
250         */
251        private DBTableModel initDBTable() {
252                DBTableModel tbl = DBTableModelUtil.newDBTable();
253
254                // 5.7.4.3 (2014/03/28) 以下の処理は、ほぼ全面見直し
255                int size = SELECT.length ;                                                              // 基本カラムの数
256                if( useWritable   ) { size++ ; }                                                // WRITABLE カラムを追加
257                if( useMD5        ) { size++ ; }                                                // MD5 カラムを追加
258                if( useUpdateClms ) { size += USE_UPDATE_CLM.length; }  // TO_PARENT、TO_NAMEカラムを追加
259                size += addClms.length ;                                                                // addClms(追加カラム)数を追加
260
261                // DBTableModel の初期化と、初期値配列の確保
262                tbl.init( size );
263                defClms = new String[size];
264
265                int ad=0;
266                // 先頭は、WRITABLE
267                if( useWritable ) {
268                        DBColumn dbColumn = getDBColumn( "WRITABLE" );
269                        defClms[ad] = "1";                                                                      // WRITABLE を設定するときは、とりあえず 書き込み許可
270                        tbl.setDBColumn( ad++,dbColumn );
271                }
272
273                // SELECT の 基本カラムの設定。(初期値は不要)
274                for( int i=0; i<SELECT.length; i++ ) {
275                        DBColumn dbColumn = getDBColumn( SELECT[i] );
276                        tbl.setDBColumn( ad++,dbColumn );
277                }
278
279                // MD5 カラムを追加。
280                if( useMD5 ) {
281                        DBColumn dbColumn = getDBColumn( "MD5" );
282                        defClms[ad] = "";                                                                       // ディレクトリの場合は、MD5計算しません。
283                        tbl.setDBColumn( ad++,dbColumn );
284                }
285
286                // TO_PARENT、TO_NAMEカラムを追加
287                if( useUpdateClms ) {
288                        for( int i=0; i<USE_UPDATE_CLM.length; i++ ) {
289                                DBColumn dbColumn = getDBColumn( USE_UPDATE_CLM[i] );
290                                defClms[ad] = dbColumn.getDefault();                    // 初期値を指定しておく
291                                tbl.setDBColumn( ad++,dbColumn );
292                        }
293                }
294
295                // 追加カラムのaddClmsカラムを追加
296                for( int i=0; i<addClms.length; i++ ) {
297                        DBColumn dbColumn = getDBColumn( addClms[i] );
298                        defClms[ad] = dbColumn.getDefault();                                    // 初期値を指定しておく
299                        tbl.setDBColumn( ad++,dbColumn );
300                }
301
302                return tbl ;
303        }
304
305        /**
306         * DBTableModel に、ファイル情報をセットします。
307         * ファイル情報は、[WRITABLE],LEVEL,FILE_TYPE,PARENT,NAME,LASTMODIFIED,FILE_LENGTH,RWH,[MD5],[TO_PARENT,TO_NAME],[・・・・] です。
308         *
309         * useWritable=true の場合、先頭カラムに、WRITABLE カラムを追加します。
310         * useMD5=true の場合、MD5カラムを追加したうえで、MD5計算を行います(ファイルのみ計算します)。
311         * useUpdateClms=true の場合TO_PARENT、TO_NAMEカラムを追加します。
312         * addClms で指定されたカラムをその後ろに追加します。
313         *
314         * @og.rev 5.3.4.0 (2011/04/01) 指定カラム追加機能追加
315         * @og.rev 5.7.4.3 (2014/03/28) useWritable,useMD5属性追加
316         *
317         * @param       rowNo   セットする行番号
318         * @param       lvl     セットするレベル
319         * @param       fin             ファイル情報の元となるファイルオブジェクト
320         */
321        private void addFileData( final int rowNo,final int lvl,final File fin ) {
322                try {
323                        File file = fin.getCanonicalFile();
324
325                        String rwh = (    file.canRead()  ? "r" : "-" )
326                                                +       ( file.canWrite() ? "w" : "-" )
327                                                +       ( file.isHidden() ? "h" : "-" );
328
329                        String lastModified = HybsSystem.getDate( file.lastModified(),"yyyyMMddHHmmss" );
330
331                        boolean isF = file.isFile();                                                            // File=true,それ以外=false
332
333                        int size = table.getColumnCount() ;
334                        String[] data = Arrays.copyOf( defClms,size );                          // JDK1.6
335
336                        int ad=0;
337                        if( useWritable ) { ad++ ; }            // 単にひとつ進める。初期値はセット済み。
338
339                        // SELECT の 基本カラムの設定
340                        data[ad++] = String.valueOf( lvl ) ;                                            // LEVEL
341                        data[ad++] = isF ? "F" : "D" ;                                                          // FILE_TYPE
342                        data[ad++] = file.getParent() ;                                                         // PARENT
343                        data[ad++] = file.getName() ;                                                           // NAME
344                        data[ad++] = lastModified ;                                                                     // LASTMODIFIED
345                        data[ad++] = isF ? String.valueOf( file.length() ) : "" ;       // FILE_LENGTH
346                        data[ad++] = rwh ;                                                                                      // RWH
347
348                        // MD5 カラムを追加(ファイルの場合のみ計算します)
349                        if( useMD5 && isF ) {
350                                data[ad++] = HybsCryptography.getMD5( file );
351                        }
352
353                        // useUpdateClms=true 時の TO_PARENT、TO_NAMEカラムや、addClmsの追加カラムは、初期値のみセット
354                        // 初期値セットは、Arrays.copyOf で、defClms のコピーで完了。
355
356                        table.addColumnValues( data );
357                }
358                catch( IOException ex ) {
359                        String errMsg = "正式なファイル名の取得に失敗しました。[" + fin + "]"
360                                                + " ROW=[" + rowNo + "]"
361                                                + HybsSystem.CR + ex.getMessage();
362                        throw new HybsSystemException( errMsg,ex );
363                }
364        }
365
366        /**
367         * 【TAG】ファイルの検索元となるディレクトリを指定します。
368         *
369         * @og.tag ファイルの検索元となるディレクトリを指定します。
370         *
371         * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。
372         *
373         * @param       url ファイルの検索元となるディレクトリ
374         */
375        public void setFrom( final String url ) {
376                String furl = nval( getRequestParameter( url ),null );
377                if( furl != null ) {
378                        char ch = furl.charAt( furl.length()-1 );
379                        if( ch != '/' && ch != '\\' ) { furl = furl + "/"; }
380                }
381                furl = StringUtil.urlAppend( from,furl );
382                furl = StringUtil.urlAppend( furl,"." );
383
384                from = HybsSystem.url2dir( furl );
385        }
386
387        /**
388         * 【TAG】多段階展開するか、1レベル展開するかどうか[true/false]を指定します(初期値:false)。
389         *
390         * @og.tag
391         * 初期値は、false (1レベル) です。
392         *
393         * @param       mlti 多段階展開するか [true:する/false:1レベル]
394         */
395        public void setMulti( final String mlti ) {
396                multi = nval( getRequestParameter( mlti ),multi );
397        }
398
399        /**
400         * 【TAG】多段階展開するレベルを指定します(初期値:100)。
401         *
402         * @og.tag
403         *
404         * @param       lvl 多段階展開するレベル
405         */
406        public void setLevel( final String lvl ) {
407                level = nval( getRequestParameter( lvl ),level );
408        }
409
410        /**
411         * 【TAG】ソートするカラム名を指定します(一つのみ)。
412         *
413         * @og.tag
414         * ソートするカラム名を、"LEVEL","FILE_TYPE","PARENT","NAME","LASTMODIFIED","FILE_LENGTH","RWH"
415         * から一つ選びます。
416         * これは、複数カラムでのソートはできません。
417         * 逆順にソートする場合は、desc属性を true にセットください。
418         * + をつけても、無効(カラム名がないということでエラーになります。
419         *
420         * @og.rev 5.3.4.0 (2011/04/01) 新規追加
421         *
422         * @param       clm ソートするカラム名(一つのみ)、逆順は、マイナスを付ける。
423         * @see         #setDesc( String )
424         */
425        public void setOrderBy( final String clm ) {
426                orderBy = nval( getRequestParameter( clm ),orderBy );
427
428                if( orderBy != null && ! check( orderBy, SELECT ) ) {
429                        String errMsg = "指定の orderBy は、指定できません。" + HybsSystem.CR
430                                                        + "orderBy=[" + orderBy + "] "   + HybsSystem.CR
431                                                        + StringUtil.array2csv( SELECT ) + HybsSystem.CR ;
432                        throw new HybsSystemException( errMsg );
433                }
434        }
435
436        /**
437         * 【TAG】表示順を逆転するかどうか[true/false]を指定します(初期値:false)。
438         *
439         * @og.tag
440         * orderBy 属性で指定した表示順を、逆順にするかどうかを指定できます。
441         * 初期値は、false (昇順) です。
442         *
443         * @og.rev 5.3.4.0 (2011/04/01) 新規追加
444         *
445         * @param       flag 表示順を逆転するかどうか [逆順:true/正順:false]
446         * @see         #setOrderBy( String )
447         */
448        public void setDesc( final String flag ) {
449                desc = nval( getRequestParameter( flag ),desc );
450        }
451
452        /**
453         * 【TAG】先頭カラムに、WRITABLE カラムを追加するかどうか[true/false]を指定します(初期値:false)。
454         *
455         * @og.tag
456         * ファイル検索結果の1レコード単位に、書き込み許可/禁止属性を付けるには、
457         * カラム列の先頭に、WRITABLE カラムを追加する必要があります。
458         * 初期値は、false (追加しない) です。
459         *
460         * @og.rev 5.7.4.3 (2014/03/28) 新規追加
461         *
462         * @param       flag 先頭カラムに、WRITABLE カラムを追加するかどうか[true:追加する/false:追加しない]
463         */
464        public void setUseWritable( final String flag ) {
465                useWritable = nval( getRequestParameter( flag ),useWritable );
466        }
467
468        /**
469         * 【TAG】MD5カラムを追加したうえで、MD5計算を行うかどうか[true/false]を指定します(初期値:false)。
470         *
471         * @og.tag
472         * ファイルの改変等をチェックするには、ファイルのハッシュ値を拾う必要があります。
473         * タイムスタンプとサイズ(LASTMODIFIED,FILE_LENGTH)でも、類似の処理は可能ですが、
474         * より、厳密な一致をみるなら、MD5でハッシュした結果を突き合わせるのがベストです。
475         * useMD5=true に設定すると、MD5 というカラムを追加したうえで、MD5計算結果をセットします。
476         * 初期値は、false (追加しない) です。
477         *
478         * @og.rev 5.7.4.3 (2014/03/28) 新規追加
479         *
480         * @param       flag MD5カラムを追加したうえで、MD5計算を行うかどうか[true:追加する/false:追加しない]
481         */
482        public void setUseMD5( final String flag ) {
483                useMD5 = nval( getRequestParameter( flag ),useMD5 );
484        }
485
486        /**
487         * 【TAG】TO_PARENT、TO_NAMEカラムを追加するかどうか[true/false]を指定します(初期値:false)。
488         *
489         * @og.tag
490         * fileUpdateタグでは、ファイルのCOPYやMOVEが出来ますが、そのコピー先、移動先の
491         * ファイルを行ごとに指定する場合、TO_PARENT、TO_NAMEカラムという固定名のカラムが
492         * 必要です。
493         * これを、addClms 属性で指定する代わりに、この属性で、true をセットすることで、
494         * 自動的に追加されます。
495         * 初期値は、false (追加しない) です。
496         *
497         * @og.rev 5.3.4.0 (2011/04/01) 新規追加
498         *
499         * @param       flag TO_PARENT、TO_NAMEカラムを追加するかどうか [true:追加する/false:追加しない]
500         * @see         #setAddClms( String )
501         * @see         org.opengion.hayabusa.taglib.FileUpdateTag
502         */
503        public void setUseUpdateClms( final String flag ) {
504                useUpdateClms = nval( getRequestParameter( flag ),useUpdateClms );
505        }
506
507        /**
508         * 【TAG】検索結果のカラム列に追加するカラム名を、カンマ区切り文字で指定します。
509         *
510         * @og.tag
511         * デフォルトのカラム名、[WRITABLE],LEVEL,FILE_TYPE,PARENT,NAME,LASTMODIFIED,FILE_LENGTH,RWH,[MD5],[TO_PARENT,TO_NAME]
512         * 以外に、指定のカラム名を追加することが可能です。
513         * これは、ファイル検索結果以外の項目を追加して、データベースに書き込む場合に、利用できます。
514         * 並び順は、デフォルトカラムの後ろに、指定のカラムの順番で付きます。
515         * ここで追加したカラムには、カラムリソースの初期値がセットされます。
516         *
517         * @og.rev 5.3.4.0 (2011/04/01) 新規追加
518         *
519         * @param       clms 検索結果のカラム列に追加するカラム名を、カンマ区切り文字で指定します。
520         * @see         #setUseUpdateClms( String )
521         */
522        public void setAddClms( final String clms ) {
523                String tmpClms = nval( getRequestParameter( clms ),null );
524
525                if( tmpClms != null && tmpClms.length() > 0 ) {
526                        addClms = StringUtil.csv2Array( tmpClms );
527                }
528        }
529
530        /**
531         * 【TAG】ファイル名が、指定されたファイルタイプ[DIR/FILE]と一致した場合、スルー(選択)されます。
532         * @og.tag
533         * 大文字小文字は区別しません。
534         * ファイルタイプ は、DIR,FILE が指定できます。
535         * DIR は、ディレクトリのみ検索します。(階層下がりも行います)
536         * FILEは、ファイルのみ検索します。(階層下がりも行います)
537         * 引数が null の場合は、追加しません。(つまり、すべてスルーされます。)
538         *
539         * @og.rev 5.3.4.0 (2011/04/01) fileType メソッドで選択対象指定の追加
540         *
541         * @param    str 指定するファイルタイプ(DIR,FILE,null)
542         */
543        public void setFileType( final String str ) {
544                String tmp = nval( getRequestParameter( str ),fileType );
545                if( tmp == null                                         ||
546                        "DIR".equalsIgnoreCase( tmp )   ||
547                        "FILE".equalsIgnoreCase( tmp ) ) {
548                                fileType = tmp;
549                }
550                else {
551                        // ファイルタイプに不正な値が設定された場合は、エラーになる。
552                        String errMsg = "この、fileType 属性には、DIR,FILE 以外は指定できません。["
553                                                + tmp + "]";
554                        throw new HybsSystemException( errMsg );
555                }
556        }
557
558        /**
559         * 【TAG】from属性で指定された基準ファイル/フォルダ自体をリストに追加するかどうか[true/false]を指定します(初期値:true)。
560         * @og.tag
561         * 初期値はtrue(追加する)です。
562         *
563         * @og.rev 5.3.9.0 (2011/09/01) 新規作成
564         *
565         * @param    flg 基準ファイル/フォルダ自体をリストに追加するかどうか true:追加する/false:追加しない]
566         */
567        public void setAddFrom( final String flg ) {
568                addFrom = nval( getRequestParameter( flg ),addFrom );
569        }
570
571        /**
572         * FileFilterオブジェクトをセットします。
573         * これは、BODY 部に登録した、FileWhereタグによって設定された
574         * ファイルフィルターです。
575         *
576         * @param       filter  オブジェクト
577         */
578        protected void setFileFilter( final FileFilter filter ) {
579                this.filter = filter;
580        }
581
582        /**
583         * シリアライズ用のカスタムシリアライズ書き込みメソッド
584         *
585         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
586         * @serialData 一部のオブジェクトは、シリアライズされません。
587         *
588         * @param       strm    ObjectOutputStreamオブジェクト
589         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
590         */
591        private void writeObject( final ObjectOutputStream strm ) throws IOException {
592                strm.defaultWriteObject();
593        }
594
595        /**
596         * シリアライズ用のカスタムシリアライズ読み込みメソッド
597         *
598         * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
599         *
600         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
601         * @serialData 一部のオブジェクトは、シリアライズされません。
602         *
603         * @param       strm    ObjectInputStreamオブジェクト
604         * @see #release2()
605         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
606         * @throws ClassNotFoundException       クラスを見つけることができなかった場合
607         */
608        private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
609                strm.defaultReadObject();
610        }
611
612        /**
613         * このオブジェクトの文字列表現を返します。
614         * 基本的にデバッグ目的に使用します。
615         *
616         * @return このクラスの文字列表現
617         */
618        @Override
619        public String toString() {
620                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
621                                .println( "VERSION"             ,VERSION        )
622                                .println( "multi"               ,multi  )
623                                .println( "level"               ,level  )
624                                .println( "from"                ,from   )
625                                .fixForm().toString()
626                        + HybsSystem.CR
627                        + super.toString() ;
628        }
629}