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 */ 016 package org.opengion.hayabusa.taglib; 017 018 import org.opengion.hayabusa.common.HybsSystem; 019 import org.opengion.hayabusa.common.HybsSystemException; 020 import org.opengion.fukurou.util.XHTMLTag; 021 import org.opengion.fukurou.util.Attributes; 022 import org.opengion.fukurou.util.StringUtil; 023 024 import static org.opengion.fukurou.util.StringUtil.nval ; 025 026 import java.io.File; 027 import java.io.FileFilter; 028 import java.io.Serializable; 029 import java.io.ObjectOutputStream; 030 import java.io.ObjectInputStream; 031 import java.io.IOException; 032 import java.util.Arrays; 033 import java.util.Comparator; 034 035 /** 036 * ファイルのプル?ンリスト?作?するタグです? 037 * 038 * SelectタグのBODY部に?します? 039 * 並び替えにつ?は、このタグで?しますが、ファイルの選別は? 040 * BODY 部に記述する fileWhere タグで?します? 041 * 042 * @og.formSample 043 * ●形式?lt;og:fileOption from="…" value="[…]" ??? >???</og:fileOption> 044 * ●body?あ?EVAL_BODY_BUFFERED:BODYを評価し?{@XXXX} を解析しま? 045 * 046 * ●Tag定義?? 047 * <og:fileOption 048 * from 【TAG】ファイルの検索?なるディレクトリを指定しま?(初期値:FILE_URL[=filetemp/]) 049 * value 【TAG】Optionの初期値で選ばれる値を指定しま? 050 * orderBy 【TAG】検索した結果を表示する表示?ファイル属?名で?しま?初期値:自然?? 051 * desc 【TAG】表示??するかど?[true/false]を指定しま?初期値:false) 052 * debug 【TAG】デバッグ??を?力するかど?[true/false]を指定しま?初期値:false) 053 * > ... Body ... 054 * </og:fileOption> 055 * 056 * ●使用? 057 * ・<og:fileOption val1="ABCD" val2="{@value}" > 058 * <og:fileWhere startsWith="ABCD" ??? /> 059 * </og:fileOption> 060 * 061 * @og.rev 2.1.1.0 (2002/11/11) 新規作? 062 * @og.rev 4.0.0.0 (2005/01/31) ?ロジ?改? 063 * @og.group そ?他?? 064 * 065 * @version 4.0 066 * @author Kazuhiko Hasegawa 067 * @since JDK5.0, 068 */ 069 public class FileOptionTag extends CommonTagSupport { 070 //* こ?プログラ??VERSION??を設定します? {@value} */ 071 private static final String VERSION = "5.3.4.0 (2011/04/01)" ; 072 073 private static final long serialVersionUID = 534020110401L ; 074 075 private String orderBy = null; // ?????目 076 private boolean desc = false; // 降??ラク?? 077 private String from = HybsSystem.sys( "FILE_URL" ); // 検索起点?ァ??? 078 private String selValue = null; // 選択済み初期値にする場? 079 private transient FileFilter filter = null; // FileWhere で?したフィルター 080 081 private static final String[] ORDER_BY = new String[] { 082 "NAME","LASTMODIFIED","FILE_LENGTH","LENGTH" }; // 5.3.4.0 (2011/04/01) FILE_LENGTH 追? 083 084 /** 085 * Taglibの開始タグが見つかったときに処??doStartTag() ?オーバ?ライドします? 086 * 087 * @return 後続????( EVAL_BODY_BUFFERED ) 088 */ 089 @Override 090 public int doStartTag() { 091 return( EVAL_BODY_BUFFERED ); // Body を評価する? extends BodyTagSupport ? 092 } 093 094 /** 095 * Taglibのタグ本体を処??doAfterBody() ?オーバ?ライドします? 096 * 097 * @return 後続????(SKIP_BODY) 098 */ 099 @Override 100 public int doAfterBody() { 101 return(SKIP_BODY); 102 } 103 104 /** 105 * Taglibの終?グが見つかったときに処??doEndTag() ?オーバ?ライドします? 106 * 107 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応?release2() ?doEndTag()で呼ぶ? 108 * 109 * @return 後続???? 110 */ 111 @Override 112 public int doEndTag() { 113 debugPrint(); // 4.0.0 (2005/02/28) 114 // SelectTag select = (SelectTag)findAncestorWithClass( this, SelectTag.class ); 115 OptionAncestorIF select = (OptionAncestorIF)findAncestorWithClass( this, OptionAncestorIF.class ); 116 if( select == null ) { 117 // String errMsg = "こ?タグは、SelectTag のBODY に記述する?があります?"; 118 String errMsg = "<b>" + getTagName() + "タグは、SelectTag また?、DatalistTag のBODY に記述する?があります?</b>"; 119 throw new HybsSystemException( errMsg ); 120 } 121 Comparator<File> comp = makeComparator( orderBy,desc ); 122 makeLabel( select,comp ); 123 124 return(EVAL_PAGE); 125 } 126 127 /** 128 * タグリブオブジェクトをリリースします? 129 * キャ?ュされて再利用される?で、フィールド?初期設定を行います? 130 * 131 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応?release2() ?doEndTag()で呼ぶ? 132 * 133 */ 134 @Override 135 protected void release2() { 136 super.release2(); 137 orderBy = null; // ?????目 138 desc = false; // 降??ラク?? 139 from = HybsSystem.sys( "FILE_URL" ); 140 filter = null; 141 selValue = null; 142 } 143 144 /** 145 * オプションを作?します? 146 * 147 * ファイル名を "value" に? 148 * BODY属? に登録するOptionを作?します? 149 * 150 * @og.rev 5.3.4.0 (2011/04/01) FILE_LENGTH 追? 151 * 152 * @param orderBy ソートする属?[NAME/LASTMODIFIED/FILE_LENGTH/LENGTH] 153 * @param desc 並び?true:??/false:降?] 154 * 155 * @return ファイル比?のComparatorオブジェク? 156 */ 157 private Comparator<File> makeComparator( final String orderBy,final boolean desc ) { 158 if( orderBy == null ) { return null; } 159 160 Comparator<File> comp = null ; 161 162 if( "NAME".equalsIgnoreCase( orderBy ) ) { 163 comp = new NameComparator( desc ); 164 } 165 else if( "LASTMODIFIED".equalsIgnoreCase( orderBy ) ) { 166 comp = new ModifiedComparator( desc ); 167 } 168 // "LENGTH" を残すのは、互換性のため 169 else if( "FILE_LENGTH".equalsIgnoreCase( orderBy ) || "LENGTH".equalsIgnoreCase( orderBy ) ) { 170 comp = new LengthComparator( desc ); 171 } 172 173 return comp ; 174 } 175 176 /** 177 * オプションを作?します? 178 * 179 * ?ァ??名?"value" に? 180 * BODY属? に登録するOptionを作?します? 181 * 182 * @og.rev 3.8.0.9 (2005/10/17) ?選択可能時に全選択を設定する? 183 * 184 * @param select SelectTagオブジェク? 185 * @param comp 並び??するため?Comparatorオブジェク? 186 */ 187 // private void makeLabel( final SelectTag select,final Comparator<File> comp ) { 188 private void makeLabel( final OptionAncestorIF select,final Comparator<File> comp ) { 189 File path = new File( from ); 190 191 File[] list = path.listFiles( filter ); 192 193 boolean multipleAll = select.isMultipleAll(); // 3.8.0.9 (2005/10/17) 194 if( list != null ) { 195 Arrays.sort( list, comp ); 196 for( int i = 0; i < list.length; i++ ) { 197 if( list[i].isDirectory() ) { continue; } // ?レクトリは除? 198 Attributes attri = new Attributes(); 199 String value = list[i].getName(); 200 attri.set( "value", value ); 201 if( ( selValue != null && selValue.equalsIgnoreCase( value ) ) || multipleAll ) { 202 attri.set( "selected", "selected" ); 203 } 204 attri.set( "body", value ); 205 select.addOption( XHTMLTag.option( attri ) ); 206 } 207 } 208 } 209 210 /** 211 * 【TAG】Optionの初期値で選ばれる値を指定します? 212 * 213 * @og.tag 214 * キーになる?は、ファイル属?の NAME です?(?レクトリなし?ファイル? 215 * ここで value属?に?した?合?こ?ファイル名と(大?小文字を無視して) 216 * ??する場合に、?ル?ンの初期値に表示されます?(selected 属?が設定される? 217 * 218 * @param val 初期値で選ばれる値 219 */ 220 public void setValue( final String val ) { 221 selValue = nval( getRequestParameter( val ),selValue ); 222 } 223 224 /** 225 * 【TAG】ファイルの検索?なるディレクトリを指定しま? 226 * (初期値:FILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])? 227 * 228 * @og.tag ファイルの検索?なるディレクトリを指定します? 229 * (初期値:シス?定数のFILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])? 230 * 231 * @og.rev 4.0.0.0 (2007/11/20) ?された?レクトリ名??が"\"or"/"で終わって???合に?/"を付加する? 232 * 233 * @param url ファイルの検索?なるディレクトリ 234 * @see org.opengion.hayabusa.common.SystemData#FILE_URL 235 */ 236 public void setFrom( final String url ) { 237 String furl = nval( getRequestParameter( url ),null ); 238 if( furl != null ) { 239 char ch = furl.charAt( furl.length()-1 ); 240 if( ch != '/' && ch != '\\' ) { furl = furl + "/"; } 241 } 242 furl = StringUtil.urlAppend( from,furl ); 243 furl = StringUtil.urlAppend( furl,"." ); 244 from = HybsSystem.url2dir( furl ); 245 } 246 247 /** 248 * 【TAG】検索した結果を表示する表示?ファイル属?名で?しま?初期値:自然??? 249 * 250 * @og.tag 251 * ファイルをソートする?(Comparator)を指定します?ソートに?できる 252 * ファイル属?名??NAME","LASTMODIFIED","FILE_LENGTH" の??どれかひとつです? 253 * 何も?しな??合?、Fileオブジェクト?自然?でのソートになります? 254 * (※ 下位互換性のため、LENGTH も残しますが、?予定です?) 255 * 256 * @og.rev 3.5.6.2 (2004/07/05) ??の連結にStringBuilderを使用します? 257 * @og.rev 4.0.0.0 (2005/01/31) 新規ロジ?で改? 258 * @og.rev 5.3.4.0 (2011/04/01) ORDER_BYリスト?出力方?見直? 259 * 260 * @param ordr ソートキー("NAME","LASTMODIFIED","FILE_LENGTH") 261 */ 262 public void setOrderBy( final String ordr ) { 263 orderBy = nval( getRequestParameter( ordr ),orderBy ); 264 265 if( orderBy != null && ! check( orderBy, ORDER_BY ) ) { 266 StringBuilder errMsg = new StringBuilder(); 267 errMsg.append( "orderBy 属?に、下記?属?名以外?値が設定されました? ); 268 errMsg.append( HybsSystem.CR ); 269 errMsg.append( " orderBy=[" ).append( orderBy ).append( "]" ); 270 errMsg.append( HybsSystem.CR ); 271 errMsg.append( " orderBy List=[" ); 272 errMsg.append( StringUtil.array2csv( ORDER_BY ) ); 273 errMsg.append( "]" ); 274 // for( int i=0; i<ORDER_BY.length; i++ ) { 275 // errMsg.append( ORDER_BY[i] ); 276 // if( i == ORDER_BY.length-1 ) { errMsg.append( "]" ); } 277 // else { errMsg.append( "," ); } 278 // } 279 throw new HybsSystemException( errMsg.toString() ); 280 } 281 } 282 283 /** 284 * 【TAG】表示??するかど?[true/false]を指定しま?初期値:false)? 285 * 286 * @og.tag 287 * orderBy 属?で?した表示????するかど?を指定できます? 288 * 初期値は、false (??) です? 289 * 290 * @param flag 表示??するかど? [true:??/false:??] 291 */ 292 public void setDesc( final String flag ) { 293 desc = nval( getRequestParameter( flag ),desc ); 294 } 295 296 /** 297 * FileFilterオブジェクトをセ?します? 298 * これは、BODY 部に登録した、FileWhereタグによって設定された 299 * ファイルフィルターです? 300 * 301 * @param filter オブジェク? 302 */ 303 protected void setFileFilter( final FileFilter filter ) { 304 this.filter = filter; 305 } 306 307 /** 308 * 名前?のソート?を指定す?Comparator の実体?部クラス 309 * 310 * @og.group そ?他?? 311 * 312 * @version 4.0 313 * @author Kazuhiko Hasegawa 314 * @since JDK5.0, 315 */ 316 static class NameComparator implements Comparator<File>,Serializable { 317 private static final long serialVersionUID = 4000 ; 318 319 private final boolean desc ; 320 321 /** 322 * 名前?の比?行うオブジェクトを作?します? 323 * 324 * @param desc [true:??/false:降?] 325 */ 326 public NameComparator( final boolean desc ) { this.desc = desc; } 327 328 /** 329 * Comparator インターフェースの compare( File,File ) メソ? 330 * 331 * @param o1 File 比????ファイルオブジェク? 332 * @param o2 File 比????ファイルオブジェク? 333 */ 334 public int compare( final File o1, final File o2 ) { 335 File f1 = (desc) ? o2 : o1 ; 336 File f2 = (desc) ? o1 : o2 ; 337 return (f1.getName()).compareTo( f2.getName() ) ; 338 } 339 } 340 341 /** 342 * 更新日?のソート?を指定す?Comparator の実体?部クラス 343 * 344 * @og.group そ?他?? 345 * 346 * @version 4.0 347 * @author Kazuhiko Hasegawa 348 * @since JDK5.0, 349 */ 350 static class ModifiedComparator implements Comparator<File>,Serializable { 351 private static final long serialVersionUID = 4000 ; 352 353 private final boolean desc ; 354 355 /** 356 * 更新日?の比?行うオブジェクトを作?します? 357 * 358 * @param desc [true:??/false:降?] 359 */ 360 public ModifiedComparator( final boolean desc ) { this.desc = desc; } 361 362 /** 363 * Comparator インターフェースの compare( File,File ) メソ? 364 * 365 * @param o1 File 比????ファイルオブジェク? 366 * @param o2 File 比????ファイルオブジェク? 367 */ 368 public int compare( final File o1, final File o2 ) { 369 File f1 = (desc) ? o2 : o1 ; 370 File f2 = (desc) ? o1 : o2 ; 371 return (int)( f1.lastModified() - f2.lastModified() ) ; 372 } 373 } 374 375 /** 376 * ファイルサイズ?のソート?を指定す?Comparator の実体?部クラス 377 * 378 * @og.group そ?他?? 379 * 380 * @version 4.0 381 * @author Kazuhiko Hasegawa 382 * @since JDK5.0, 383 */ 384 static class LengthComparator implements Comparator<File>,Serializable { 385 private static final long serialVersionUID = 4000 ; 386 387 private final boolean desc ; 388 389 /** 390 * ファイルサイズでの比?行うオブジェクトを作?します? 391 * 392 * @param desc [true:??/false:降?] 393 */ 394 public LengthComparator( final boolean desc ) { this.desc = desc; } 395 396 /** 397 * Comparator インターフェースの compare( File,File ) メソ? 398 * 399 * @param o1 File 比????ファイルオブジェク? 400 * @param o2 File 比????ファイルオブジェク? 401 */ 402 public int compare( final File o1, final File o2 ) { 403 File f1 = (desc) ? o2 : o1 ; 404 File f2 = (desc) ? o1 : o2 ; 405 return (int)( f1.length() - f2.length() ) ; 406 } 407 } 408 409 /** 410 * シリアライズ用のカスタ?リアライズ書き込みメソ? 411 * 412 * @og.rev 4.0.0.0 (2006/09/31) 新規追? 413 * @serialData ?のオブジェクト?、シリアライズされません? 414 * 415 * @param strm ObjectOutputStreamオブジェク? 416 * @throws IOException シリアライズに関する入出力エラーが発生した?? 417 */ 418 private void writeObject( final ObjectOutputStream strm ) throws IOException { 419 strm.defaultWriteObject(); 420 } 421 422 /** 423 * シリアライズ用のカスタ?リアライズ読み込みメソ? 424 * 425 * ここでは、transient 宣?れた?変数の??初期化が?なフィールド?み設定します? 426 * 427 * @og.rev 4.0.0.0 (2006/09/31) 新規追? 428 * @serialData ?のオブジェクト?、シリアライズされません? 429 * 430 * @param strm ObjectInputStreamオブジェク? 431 * @see #release2() 432 * @throws IOException シリアライズに関する入出力エラーが発生した?? 433 * @throws ClassNotFoundException クラスを見つけることができなかった?? 434 */ 435 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 436 strm.defaultReadObject(); 437 } 438 439 /** 440 * こ?オブジェクト???表現を返します? 441 * 基本???目?使用します? 442 * 443 * @return こ?クラスの??表現 444 */ 445 @Override 446 public String toString() { 447 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 448 .println( "VERSION" ,VERSION ) 449 .println( "orderBy" ,orderBy ) 450 .println( "desc" ,desc ) 451 .println( "from" ,from ) 452 .println( "selValue" ,selValue ) 453 .println( "Other..." ,getAttributes().getAttribute() ) 454 .fixForm().toString() ; 455 } 456 }