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 }