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