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