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