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