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 }