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?あ?
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 if( select == null ) {
116 String errMsg = "こ?タグは、SelectTag のBODY に記述する?があります?";
117 throw new HybsSystemException( errMsg );
118 }
119 Comparator<File> comp = makeComparator( orderBy,desc );
120 makeLabel( select,comp );
121
122 return(EVAL_PAGE);
123 }
124
125 /**
126 * タグリブオブジェクトをリリースします?
127 * キャ?ュされて再利用される?で、フィールド?初期設定を行います?
128 *
129 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応?release2() ?doEndTag()で呼ぶ?
130 *
131 */
132 @Override
133 protected void release2() {
134 super.release2();
135 orderBy = null; // ?????目
136 desc = false; // 降??ラク??
137 from = HybsSystem.sys( "FILE_URL" );
138 filter = null;
139 selValue = null;
140 }
141
142 /**
143 * オプションを作?します?
144 *
145 * ファイル名を "value" に?
146 * BODY属? に登録するOptionを作?します?
147 *
148 * @og.rev 5.3.4.0 (2011/04/01) FILE_LENGTH 追?
149 *
150 * @param orderBy ソートする属?[NAME/LASTMODIFIED/FILE_LENGTH/LENGTH]
151 * @param desc 並び?true:??/false:降?]
152 *
153 * @return ファイル比?のComparatorオブジェク?
154 */
155 private Comparator<File> makeComparator( final String orderBy,final boolean desc ) {
156 if( orderBy == null ) { return null; }
157
158 Comparator<File> comp = null ;
159
160 if( "NAME".equalsIgnoreCase( orderBy ) ) {
161 comp = new NameComparator( desc );
162 }
163 else if( "LASTMODIFIED".equalsIgnoreCase( orderBy ) ) {
164 comp = new ModifiedComparator( desc );
165 }
166 // "LENGTH" を残すのは、互換性のため
167 else if( "FILE_LENGTH".equalsIgnoreCase( orderBy ) || "LENGTH".equalsIgnoreCase( orderBy ) ) {
168 comp = new LengthComparator( desc );
169 }
170
171 return comp ;
172 }
173
174 /**
175 * オプションを作?します?
176 *
177 * ?ァ??名?"value" に?
178 * BODY属? に登録するOptionを作?します?
179 *
180 * @og.rev 3.8.0.9 (2005/10/17) ?選択可能時に全選択を設定する?
181 *
182 * @param select SelectTagオブジェク?
183 * @param comp 並び??するため?Comparatorオブジェク?
184 */
185 private void makeLabel( final SelectTag select,final Comparator<File> comp ) {
186 File path = new File( from );
187
188 File[] list = path.listFiles( filter );
189
190 boolean multipleAll = select.isMultipleAll(); // 3.8.0.9 (2005/10/17)
191 if( list != null ) {
192 Arrays.sort( list, comp );
193 for( int i = 0; i < list.length; i++ ) {
194 if( list[i].isDirectory() ) { continue; } // ?レクトリは除?
195 Attributes attri = new Attributes();
196 String value = list[i].getName();
197 attri.set( "value", value );
198 if( ( selValue != null && selValue.equalsIgnoreCase( value ) ) || multipleAll ) {
199 attri.set( "selected", "selected" );
200 }
201 attri.set( "body", value );
202 select.addOption( XHTMLTag.option( attri ) );
203 }
204 }
205 }
206
207 /**
208 * 【TAG】Optionの初期値で選ばれる値を指定します?
209 *
210 * @og.tag
211 * キーになる?は、ファイル属?の NAME です?(?レクトリなし?ファイル?
212 * ここで value属?に?した?合?こ?ファイル名と(大?小文字を無視して)
213 * ??する場合に、?ル?ンの初期値に表示されます?(selected 属?が設定される?
214 *
215 * @param val 初期値で選ばれる値
216 */
217 public void setValue( final String val ) {
218 selValue = nval( getRequestParameter( val ),selValue );
219 }
220
221 /**
222 * 【TAG】ファイルの検索?なるディレクトリを指定しま?
223 * (初期値:FILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])?
224 *
225 * @og.tag ファイルの検索?なるディレクトリを指定します?
226 * (初期値:シス?定数のFILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])?
227 *
228 * @og.rev 4.0.0.0 (2007/11/20) ?された?レクトリ名??が"\"or"/"で終わって???合に?/"を付加する?
229 *
230 * @param url ファイルの検索?なるディレクトリ
231 * @see org.opengion.hayabusa.common.SystemData#FILE_URL
232 */
233 public void setFrom( final String url ) {
234 String furl = nval( getRequestParameter( url ),null );
235 if( furl != null ) {
236 char ch = furl.charAt( furl.length()-1 );
237 if( ch != '/' && ch != '\\' ) { furl = furl + "/"; }
238 }
239 furl = StringUtil.urlAppend( from,furl );
240 furl = StringUtil.urlAppend( furl,"." );
241 from = HybsSystem.url2dir( furl );
242 }
243
244 /**
245 * 【TAG】検索した結果を表示する表示?ファイル属?名で?しま?初期値:自然???
246 *
247 * @og.tag
248 * ファイルをソートする?(Comparator)を指定します?ソートに?できる
249 * ファイル属?名??NAME","LASTMODIFIED","FILE_LENGTH" の??どれかひとつです?
250 * 何も?しな??合?、Fileオブジェクト?自然?でのソートになります?
251 * (※ 下位互換性のため、LENGTH も残しますが、?予定です?)
252 *
253 * @og.rev 3.5.6.2 (2004/07/05) ??の連結にStringBuilderを使用します?
254 * @og.rev 4.0.0.0 (2005/01/31) 新規ロジ?で改?
255 * @og.rev 5.3.4.0 (2011/04/01) ORDER_BYリスト?出力方?見直?
256 *
257 * @param ordr ソートキー("NAME","LASTMODIFIED","FILE_LENGTH")
258 */
259 public void setOrderBy( final String ordr ) {
260 orderBy = nval( getRequestParameter( ordr ),orderBy );
261
262 if( orderBy != null && ! check( orderBy, ORDER_BY ) ) {
263 StringBuilder errMsg = new StringBuilder();
264 errMsg.append( "orderBy 属?に、下記?属?名以外?値が設定されました? );
265 errMsg.append( HybsSystem.CR );
266 errMsg.append( " orderBy=[" ).append( orderBy ).append( "]" );
267 errMsg.append( HybsSystem.CR );
268 errMsg.append( " orderBy List=[" );
269 errMsg.append( StringUtil.array2csv( ORDER_BY ) );
270 errMsg.append( "]" );
271 // for( int i=0; i<ORDER_BY.length; i++ ) {
272 // errMsg.append( ORDER_BY[i] );
273 // if( i == ORDER_BY.length-1 ) { errMsg.append( "]" ); }
274 // else { errMsg.append( "," ); }
275 // }
276 throw new HybsSystemException( errMsg.toString() );
277 }
278 }
279
280 /**
281 * 【TAG】表示??するかど?[true/false]を指定しま?初期値:false)?
282 *
283 * @og.tag
284 * orderBy 属?で?した表示????するかど?を指定できます?
285 * 初期値は、false (??) です?
286 *
287 * @param flag 表示??するかど? [true:??/false:??]
288 */
289 public void setDesc( final String flag ) {
290 desc = nval( getRequestParameter( flag ),desc );
291 }
292
293 /**
294 * FileFilterオブジェクトをセ?します?
295 * これは、BODY 部に登録した、FileWhereタグによって設定された
296 * ファイルフィルターです?
297 *
298 * @param filter オブジェク?
299 */
300 protected void setFileFilter( final FileFilter filter ) {
301 this.filter = filter;
302 }
303
304 /**
305 * 名前?のソート?を指定す?Comparator の実体?部クラス
306 *
307 * @og.group そ?他??
308 *
309 * @version 4.0
310 * @author Kazuhiko Hasegawa
311 * @since JDK5.0,
312 */
313 static class NameComparator implements Comparator<File>,Serializable {
314 private static final long serialVersionUID = 4000 ;
315
316 private final boolean desc ;
317
318 /**
319 * 名前?の比?行うオブジェクトを作?します?
320 *
321 * @param desc [true:??/false:降?]
322 */
323 public NameComparator( final boolean desc ) { this.desc = desc; }
324
325 /**
326 * Comparator インターフェースの compare( File,File ) メソ?
327 *
328 * @param o1 File 比????ファイルオブジェク?
329 * @param o2 File 比????ファイルオブジェク?
330 */
331 public int compare( final File o1, final File o2 ) {
332 File f1 = (desc) ? o2 : o1 ;
333 File f2 = (desc) ? o1 : o2 ;
334 return (f1.getName()).compareTo( f2.getName() ) ;
335 }
336 }
337
338 /**
339 * 更新日?のソート?を指定す?Comparator の実体?部クラス
340 *
341 * @og.group そ?他??
342 *
343 * @version 4.0
344 * @author Kazuhiko Hasegawa
345 * @since JDK5.0,
346 */
347 static class ModifiedComparator implements Comparator<File>,Serializable {
348 private static final long serialVersionUID = 4000 ;
349
350 private final boolean desc ;
351
352 /**
353 * 更新日?の比?行うオブジェクトを作?します?
354 *
355 * @param desc [true:??/false:降?]
356 */
357 public ModifiedComparator( final boolean desc ) { this.desc = desc; }
358
359 /**
360 * Comparator インターフェースの compare( File,File ) メソ?
361 *
362 * @param o1 File 比????ファイルオブジェク?
363 * @param o2 File 比????ファイルオブジェク?
364 */
365 public int compare( final File o1, final File o2 ) {
366 File f1 = (desc) ? o2 : o1 ;
367 File f2 = (desc) ? o1 : o2 ;
368 return (int)( f1.lastModified() - f2.lastModified() ) ;
369 }
370 }
371
372 /**
373 * ファイルサイズ?のソート?を指定す?Comparator の実体?部クラス
374 *
375 * @og.group そ?他??
376 *
377 * @version 4.0
378 * @author Kazuhiko Hasegawa
379 * @since JDK5.0,
380 */
381 static class LengthComparator implements Comparator<File>,Serializable {
382 private static final long serialVersionUID = 4000 ;
383
384 private final boolean desc ;
385
386 /**
387 * ファイルサイズでの比?行うオブジェクトを作?します?
388 *
389 * @param desc [true:??/false:降?]
390 */
391 public LengthComparator( final boolean desc ) { this.desc = desc; }
392
393 /**
394 * Comparator インターフェースの compare( File,File ) メソ?
395 *
396 * @param o1 File 比????ファイルオブジェク?
397 * @param o2 File 比????ファイルオブジェク?
398 */
399 public int compare( final File o1, final File o2 ) {
400 File f1 = (desc) ? o2 : o1 ;
401 File f2 = (desc) ? o1 : o2 ;
402 return (int)( f1.length() - f2.length() ) ;
403 }
404 }
405
406 /**
407 * シリアライズ用のカスタ?リアライズ書き込みメソ?
408 *
409 * @og.rev 4.0.0.0 (2006/09/31) 新規追?
410 * @serialData
411 *
412 * @param strm ObjectOutputStreamオブジェク?
413 */
414 private void writeObject( final ObjectOutputStream strm ) throws IOException {
415 strm.defaultWriteObject();
416 }
417
418 /**
419 * シリアライズ用のカスタ?リアライズ読み込みメソ?
420 *
421 * ここでは、transient 宣?れた?変数の??初期化が?なフィールド?み設定します?
422 *
423 * @og.rev 4.0.0.0 (2006/09/31) 新規追?
424 * @serialData
425 *
426 * @param strm ObjectInputStreamオブジェク?
427 * @see #release2()
428 */
429 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
430 strm.defaultReadObject();
431 }
432
433 /**
434 * こ?オブジェクト???表現を返します?
435 * 基本???目?使用します?
436 *
437 * @return こ?クラスの??表現
438 */
439 @Override
440 public String toString() {
441 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
442 .println( "VERSION" ,VERSION )
443 .println( "orderBy" ,orderBy )
444 .println( "desc" ,desc )
445 .println( "from" ,from )
446 .println( "selValue" ,selValue )
447 .println( "Other..." ,getAttributes().getAttribute() )
448 .fixForm().toString() ;
449 }
450 }