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.fukurou.util;
017
018import java.io.File;
019import java.io.FileFilter;
020import java.util.List;
021import java.util.ArrayList;
022import java.util.Calendar;
023import java.util.StringTokenizer;
024
025import java.util.regex.Pattern;
026import java.util.regex.Matcher;
027
028/**
029 * HybsFileFilter.java は、複数の FileFilter を順次実行する フィルタクラスです。
030 *
031 * FileFilter インターフェースを継承し、File クラスの listFiles(FileFilter) メソッドに
032 * 渡すことができます。
033 * Filterに設定された複数のフィルタすべてを満たす場合の時のみ、accept(File pathname)
034 * メソッドは、true を返します。
035 *
036 * この実装は同期化されません。
037 *
038 * @version  4.0
039 * @author   Kazuhiko Hasegawa
040 * @since    JDK5.0,
041 */
042public final class HybsFileFilter implements FileFilter {
043        private final List<FileFilter> list = new ArrayList<FileFilter>();
044        private final boolean isUseDIR ;
045
046        /**
047         * 引数に、ディレクトリの判定を行うかどうかを指定するコンストラクタです。
048         * ここで、true を指定すると、ファイル、ディレクトリの両方に対して
049         * 処理を実施します。
050         * ディレクトリの判定の場合、acceptメソッドで、false が返ると
051         * それ以下の処理も実行されません。
052         *
053         * @og.rev 5.1.2.0 (2010/01/01) 引数つきコンストラクタ追加
054         *
055         * @param       useDIR  判定をディレクトリでも行うかどうか
056         */
057        public HybsFileFilter( final boolean useDIR ) {
058                super();
059                isUseDIR = useDIR;
060        }
061
062        /**
063         * 指定された抽象パス名がパス名リストに含まれる必要がある場合、スルー(選択)されます。
064         * ここでの判定ロジックでは、ファイルについてのみ処理します。
065         * ディレクトリは、常に、true を返します。
066         */
067        public HybsFileFilter() {
068                this( false );
069        }
070
071        /**
072         * 指定された抽象パス名がパス名リストに含まれる必要がある場合、スルー(選択)されます。
073         * ここでの判定ロジックでは、ファイルについてのみ処理します。
074         * ディレクトリは、常に、true を返します。
075         *
076         * @param       pathname        ファイルオブジェクト
077         *
078         * @return      パス名リストに含まれるかどうか
079         * @see java.io.FileFilter#accept(File)
080         */
081        public boolean accept( final File pathname ) {
082                if( pathname != null && (pathname.isFile() || isUseDIR) ) {     // 5.1.2.0 (2010/01/01)
083                        int size = list.size();
084                        for( int i=0; i<size; i++ ) {
085                                FileFilter filter = list.get(i);
086                                if( !filter.accept( pathname ) ) {
087                                        return false;
088                                }
089                        }
090                }
091                return true;
092        }
093
094        /**
095         * 外部指定フィルタ: 内部判定条件に、フィルタを追加します。
096         * 引数が null の場合は、追加しません。
097         *
098         * @param    filter 外部指定フィルタ
099         */
100        public void addFileFilter( final FileFilter filter ) {
101                if( filter != null ) { list.add( filter ); }
102        }
103
104        /**
105         * 内部判定フィルタ: 指定された接頭辞で始まる場合、スルー(選択)されます。
106         * 引数が null の場合は、追加しません。
107         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
108         *
109         * @param    prefix 接頭辞
110         * @see java.lang.String#startsWith(String)
111         */
112        public void startsWith( final String prefix ) {
113                startsWith( prefix, false );    // 反転しない
114//              if( prefix != null ) {
115//                      list.add( new StartsWithFilter( prefix ) );
116//              }
117        }
118
119        /**
120         * 内部判定フィルタ: 指定された接頭辞で始まる場合、スルー(選択)されます。
121         * 引数が null の場合は、追加しません。
122         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
123         * reverse = true に設定すると、結果を反転させます。
124         *
125         * @og.rev 5.1.2.0 (2010/01/01) reverse属性の追加
126         *
127         * @param    prefix             接頭辞
128         * @param    reverse    true:結果を反転する
129         * @see java.lang.String#startsWith(String)
130         */
131        public void startsWith( final String prefix,final boolean reverse ) {
132                if( prefix != null ) {
133                        list.add( new StartsWithFilter( prefix,reverse ) );
134                }
135        }
136
137        /**
138         * 指定された接頭辞で始まる場合に選択される FileFilter インターフェースの実装内部クラスです。
139         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
140         *
141         * @og.rev 5.1.2.0 (2010/01/01) '|' 区切り文字で複数設定処理の追加、reverse属性の追加
142         *
143         * @version  4.0
144         * @author   Kazuhiko Hasegawa
145         * @since    JDK5.0,
146         */
147        private static class StartsWithFilter implements FileFilter {
148//              private final String pfix ;
149                private final String[] pfix ;
150                private final int      cnt  ;
151                private final boolean  rvse ;
152
153                /**
154                 * 接頭辞フィルターオブジェクトを作成します。
155                 *
156                 * @param       desc    true:昇順 / false:降順
157                 * @param       reverse true:結果を反転する
158                 */
159                StartsWithFilter( final String prefix,final boolean reverse ) {
160//                      pfix = prefix;
161                        rvse = reverse;
162
163                        StringTokenizer token = new StringTokenizer( prefix, "|" );
164                        cnt = token.countTokens();
165
166                        pfix = new String[cnt];
167
168                        for( int i=0; i<cnt; i++ ) {
169                                pfix[i] = token.nextToken();
170                        }
171                }
172
173                /**
174                 * FileFilter インターフェースの accept( File ) メソッド
175                 *
176                 * @param       pathname        ファイルオブジェクト
177                 * @return      true:処理対象 / false:処理非対象
178                 * @see java.io.FileFilter#accept( File )
179                 */
180                public boolean accept( final File pathname ) {
181//                      return pathname.getName().startsWith( pfix );
182
183                        for( int i=0; i<cnt; i++ ) {
184                                if( pathname.getName().startsWith( pfix[i] ) ) {
185                                        return !rvse;
186                                }
187                        }
188                        return rvse;
189                }
190        }
191
192        /**
193         * 内部判定フィルタ: 指定された接頭辞で終わる場合、スルー(選択)されます。
194         * 引数が null の場合は、追加しません。
195         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
196         *
197         * @param    suffix 接尾辞
198         * @see java.lang.String#endsWith(String)
199         */
200        public void endsWith( final String suffix ) {
201                endsWith( suffix, false );      // 反転しない
202//              if( suffix != null ) {
203//                      list.add( new EndsWithFilter( suffix ) );
204//              }
205        }
206
207        /**
208         * 内部判定フィルタ: 指定された接頭辞で終わる場合、スルー(選択)されます。
209         * 引数が null の場合は、追加しません。
210         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
211         * reverse = true に設定すると、結果を反転させます。
212         *
213         * @og.rev 5.1.2.0 (2010/01/01) reverse属性の追加
214         *
215         * @param       suffix  接尾辞
216         * @param       reverse true:結果を反転する
217         * @see java.lang.String#endsWith(String)
218         */
219        public void endsWith( final String suffix,final boolean reverse ) {
220                if( suffix != null ) {
221                        list.add( new EndsWithFilter( suffix,reverse ) );
222                }
223        }
224
225        /**
226         * 指定された接頭辞で終わる場合に選択される FileFilter インターフェースの実装内部クラスです。
227         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
228         *
229         * @og.rev 5.1.2.0 (2010/01/01) '|' 区切り文字で複数設定処理の追加、reverse属性の追加
230         *
231         * @version  4.0
232         * @author   Kazuhiko Hasegawa
233         * @since    JDK5.0,
234         */
235        private static class EndsWithFilter implements FileFilter {
236//              private final String sfix ;
237                private final String[] sfix ;
238                private final int      cnt  ;
239                private final boolean  rvse ;
240
241                /**
242                 * 接頭辞フィルターオブジェクトを作成します。
243                 *
244                 * @param       desc    true:昇順 / false:降順
245                 * @param       reverse true:結果を反転する
246                 */
247                EndsWithFilter( final String suffix,final boolean reverse ) {
248//                      sfix = suffix;
249                        rvse = reverse;
250
251                        StringTokenizer token = new StringTokenizer( suffix, "|" );
252                        cnt = token.countTokens();
253
254                        sfix = new String[cnt];
255
256                        for( int i=0; i<cnt; i++ ) {
257                                sfix[i] = token.nextToken();
258                        }
259                }
260
261                /**
262                 * FileFilter インターフェースの accept( File ) メソッド
263                 *
264                 * @param       pathname        ファイルオブジェクト
265                 * @return      true:処理対象 / false:処理非対象
266                 * @see java.io.FileFilter#accept( File )
267                 */
268                public boolean accept( final File pathname ) {
269//                      return pathname.getName().endsWith( sfix );
270
271                        for( int i=0; i<cnt; i++ ) {
272                                if( pathname.getName().endsWith( sfix[i] ) ) {
273                                        return !rvse;
274                                }
275                        }
276                        return rvse;
277                }
278        }
279
280        /**
281         * 内部判定フィルタ: 指定された文字列がファイル名に含まれる場合、スルー(選択)されます。
282         * 引数が null の場合は、追加しません。
283         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
284         *
285         * @param    str 指定の部分文字列
286         */
287        public void instr( final String str ) {
288                instr( str, false );    // 反転しない
289//              if( str != null ) {
290//                      list.add( new InstrFilter( str ) );
291//              }
292        }
293
294        /**
295         * 内部判定フィルタ: 指定された文字列がファイル名に含まれる場合、スルー(選択)されます。
296         * 引数が null の場合は、追加しません。
297         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
298         * reverse = true に設定すると、結果を反転させます。
299         *
300         * @og.rev 5.1.2.0 (2010/01/01) reverse属性の追加
301         *
302         * @param       str     指定の部分文字列
303         * @param       reverse 結果を反転させるかどうか(true:反転)
304         */
305        public void instr( final String str,final boolean reverse ) {
306                if( str != null ) {
307                        list.add( new InstrFilter( str,reverse ) );
308                }
309        }
310
311        /**
312         * 指定された文字列がファイル名に含まれる場合に選択される FileFilter インターフェースの実装内部クラスです。
313         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
314         *
315         * @og.rev 5.1.2.0 (2010/01/01) '|' 区切り文字で複数設定処理の追加、reverse属性の追加
316         *
317         * @version  4.0
318         * @author   Kazuhiko Hasegawa
319         * @since    JDK5.0,
320         */
321        private static class InstrFilter implements FileFilter {
322//              private final String instr ;
323                private final String[] instr ;
324                private final int      cnt  ;
325                private final boolean  rvse ;
326
327                /**
328                 * 文字列包含フィルターオブジェクトを作成します。
329                 *
330                 * @param       desc    true:昇順 / false:降順
331                 * @param reverse       true:結果を反転する
332                 */
333                InstrFilter( final String str,final boolean reverse ) {
334//                      instr = str;
335                        rvse = reverse;
336
337                        StringTokenizer token = new StringTokenizer( str, "|" );
338                        cnt = token.countTokens();
339
340                        instr = new String[cnt];
341
342                        for( int i=0; i<cnt; i++ ) {
343                                instr[i] = token.nextToken();
344                        }
345                }
346
347                /**
348                 * FileFilter インターフェースの accept( File ) メソッド
349                 *
350                 * @param       pathname        ファイルオブジェクト
351                 * @return      true:処理対象 / false:処理非対象
352                 * @see java.io.FileFilter#accept( File )
353                 */
354                public boolean accept( final File pathname ) {
355//                      return ( pathname.getName().indexOf( instr ) >= 0 );
356
357                        for( int i=0; i<cnt; i++ ) {
358                                if( pathname.getName().indexOf( instr[i] ) >= 0 ) {
359                                        return !rvse;
360                                }
361                        }
362                        return rvse;
363                }
364        }
365
366        /**
367         * 内部判定フィルタ: ファイル名が一致する場合、スルー(選択)されます。
368         * 大文字小文字は区別しません。
369         * 引数が null の場合は、追加しません。
370         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
371         *
372         * @param    str ファイル名文字列
373         */
374        public void fileEquals( final String str ) {
375                fileEquals( str, false );       // 反転しない
376//              if( str != null ) {
377//                      list.add( new EqualsFilter( str ) );
378//              }
379        }
380
381        /**
382         * 内部判定フィルタ: ファイル名が一致する場合、スルー(選択)されます。
383         * 大文字小文字は区別しません。
384         * 引数が null の場合は、追加しません。
385         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
386         * reverse = true に設定すると、結果を反転させます。
387         *
388         * @og.rev 5.1.2.0 (2010/01/01) reverse属性の追加
389         *
390         * @param    str ファイル名文字列
391         * @param    reverse    true:結果を反転する
392         */
393        public void fileEquals( final String str,final boolean reverse ) {
394                if( str != null ) {
395                        list.add( new EqualsFilter( str,reverse ) );
396                }
397        }
398
399        /**
400         * ファイル名が一致する場合に選択される FileFilter インターフェースの実装内部クラスです。
401         * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。
402         *
403         * @og.rev 5.1.2.0 (2010/01/01) '|' 区切り文字で複数設定処理の追加、reverse属性の追加
404         *
405         * @version  4.0
406         * @author   Kazuhiko Hasegawa
407         * @since    JDK5.0,
408         */
409        private static class EqualsFilter implements FileFilter {
410//              private final String eqstr ;
411                private final String[] eqstr ;
412                private final int      cnt  ;
413                private final boolean  rvse ;
414
415                /**
416                 * ファイル名一致フィルターオブジェクトを作成します。
417                 *
418                 * @param       desc    true:昇順 / false:降順
419                 * @param reverse       true:結果を反転する
420                 */
421                EqualsFilter( final String str,final boolean reverse ) {
422//                      eqstr = str;
423                        rvse = reverse;
424
425                        StringTokenizer token = new StringTokenizer( str, "|" );
426                        cnt = token.countTokens();
427
428                        eqstr = new String[cnt];
429
430                        for( int i=0; i<cnt; i++ ) {
431                                eqstr[i] = token.nextToken();
432                        }
433                }
434
435                /**
436                 * FileFilter インターフェースの accept( File ) メソッド
437                 *
438                 * @param       pathname        ファイルオブジェクト
439                 * @return      true:処理対象 / false:処理非対象
440                 * @see java.io.FileFilter#accept( File )
441                 */
442                public boolean accept( final File pathname ) {
443//                      return pathname.getName().equalsIgnoreCase( eqstr );
444
445                        for( int i=0; i<cnt; i++ ) {
446                                if( pathname.getName().equalsIgnoreCase( eqstr[i] ) ) {
447                                        return !rvse;
448                                }
449                        }
450                        return rvse;
451                }
452        }
453
454        /**
455         * 内部判定フィルタ: ファイル名が、指定された
456         * <a href="/java/api14/api/java/util/regex/Pattern.html#sum">正規表現</a>
457         * と一致する場合、スルー(選択)されます
458         * 大文字小文字は区別しません。
459         * Pattern.compile( str,Pattern.CASE_INSENSITIVE ) ;
460         * pattern.matcher( pathname.getName() ).find() == true と同じ結果が得られます。
461         * 引数が null の場合は、追加しません。
462         *
463         * @param    str ファイル名文字列(正規表現)
464         * @see java.util.regex.Pattern#compile(String,int)
465         * @see java.util.regex.Matcher#find()
466         */
467        public void matches( final String str ) {
468                matches( str, false );  // 反転しない
469//              if( str != null ) {
470//                      list.add( new MatchesFilter( str ) );
471//              }
472        }
473
474        /**
475         * 内部判定フィルタ: ファイル名が、指定された
476         * <a href="/java/api14/api/java/util/regex/Pattern.html#sum">正規表現</a>
477         * と一致する場合、スルー(選択)されます
478         * 大文字小文字は区別しません。
479         * Pattern.compile( str,Pattern.CASE_INSENSITIVE ) ;
480         * pattern.matcher( pathname.getName() ).find() == true と同じ結果が得られます。
481         * 引数が null の場合は、追加しません。
482         * reverse = true に設定すると、結果を反転させます。
483         *
484         * @og.rev 5.1.2.0 (2010/01/01) reverse属性の追加
485         *
486         * @param    str ファイル名文字列(正規表現)
487         * @param    reverse    true:結果を反転する
488         * @see java.util.regex.Pattern#compile(String,int)
489         * @see java.util.regex.Matcher#find()
490         */
491        public void matches( final String str,final boolean reverse ) {
492                if( str != null ) {
493                        list.add( new MatchesFilter( str,reverse ) );
494                }
495        }
496
497        /**
498         * ファイル名が、指定された正規表現と一致する場合に選択される FileFilter インターフェースの実装内部クラスです。
499         *
500         * @og.rev 5.1.2.0 (2010/01/01) reverse属性の追加
501         *
502         * @version  4.0
503         * @author   Kazuhiko Hasegawa
504         * @since    JDK5.0,
505         */
506        private static class MatchesFilter implements FileFilter {
507                private final Pattern pattern ;
508                private final boolean  rvse ;
509
510                /**
511                 * 正規表現一致フィルターオブジェクトを作成します。
512                 *
513                 * @param       desc    true:昇順 / false:降順
514                 * @param reverse       true:結果を反転する
515                 */
516                MatchesFilter( final String str,final boolean reverse ) {
517                        pattern = Pattern.compile( str,Pattern.CASE_INSENSITIVE );
518                        rvse = reverse;
519                }
520
521                /**
522                 * FileFilter インターフェースの accept( File ) メソッド
523                 *
524                 * @param       pathname        ファイルオブジェクト
525                 * @return      true:処理対象 / false:処理非対象
526                 * @see java.io.FileFilter#accept( File )
527                 */
528                public boolean accept( final File pathname ) {
529                        Matcher match = pattern.matcher( pathname.getName() );
530//                      return match.find() ;
531                        if( match.find() ) { return !rvse; }
532                        else { return rvse; }
533                }
534        }
535
536        /**
537         * 内部判定フィルタ: ファイル名が、指定された
538         * <a href="/java/api14/api/java/util/regex/Pattern.html#sum">正規表現</a>
539         * と一致しない場合、スルー(選択)されます。
540         * 大文字小文字は区別しません。
541         * Pattern.compile( str,Pattern.CASE_INSENSITIVE ) ;
542         * pattern.matcher( pathname.getName() ).find() == false と同じ結果が得られます。
543         * 引数が null の場合は、追加しません。
544         *
545         * @param    str ファイル名文字列(正規表現) とマッチしない
546         * @see java.util.regex.Pattern#compile(String,int)
547         * @see java.util.regex.Matcher#find()
548         */
549//      public void unMatches( final String str ) {
550//              if( str != null ) {
551//                      list.add( new UnMatchesFilter( str ) );
552//              }
553//      }
554
555        /**
556         * ファイル名が、指定された正規表現と一致しない場合に選択される FileFilter インターフェースの実装内部クラスです。
557         *
558         * @version  4.0
559         * @author   Kazuhiko Hasegawa
560         * @since    JDK5.0,
561         */
562//      private static class UnMatchesFilter implements FileFilter {
563//              private final Pattern pattern ;
564//
565//              /**
566//               * 正規表現不一致フィルターオブジェクトを作成します。
567//               *
568//               * @param       desc    true:昇順 / false:降順
569//               */
570//              UnMatchesFilter( String str ) {
571//                      pattern = Pattern.compile( str,Pattern.CASE_INSENSITIVE );
572//              }
573//
574//              /**
575//               * FileFilter インターフェースの accept( File ) メソッド
576//               *
577//               * @param       pathname        ファイルオブジェクト
578//               * @return      true:処理対象 / false:処理非対象
579//               * @see java.io.FileFilter#accept( File )
580//               */
581//              public boolean accept( final File pathname ) {
582//                      Matcher match = pattern.matcher( pathname.getName() );
583//                      return ! match.find() ;
584//              }
585//      }
586
587        /**
588         * 内部判定フィルタ: 指定のタイムスタンプ以後に変更されている場合、スルー(選択)されます。
589         * ディレクトリは、ここの判定では無視します。(必ず true を返します)
590         * 日付けの指定に、YYYYMMDD 形式の 8文字数字文字列以外に、
591         * TODAY や YESTERDAY なども使用できます。
592         * TODAY は、実行日の 00:00:00 を基準時刻とし、YESTERDAY は、その前日になります。
593         * 引数が null の場合は、追加しません。
594         *
595         * @param    modify 時刻を表す long 値(ミリ秒単位)
596         */
597        public void lastModified( final String modify ) {
598                if( modify != null ) {
599                        list.add( new ModifyFileFilter( modify ) );
600                }
601        }
602
603        /**
604         * 共通処理:単位記号の付与されたバイト文字列から、long値であるバイトを求めます。
605         * 現時点では、K , KB , M , MB , G , GB のみ単位指定可能です。
606         * それぞれ、元の値に対して、1024倍されます。
607         *
608         * 処理が正常に出来ない場合は、-1L を返します。
609         *
610         * @og.rev 5.7.4.3 (2014/03/28) 新規追加
611         *
612         * @param       slen 単位記号付きバイト値
613         * @return      longに換算したバイト値
614         */
615        private long getByteSize( final String slen ) {
616                if( slen == null ) { return -1L; }
617
618                String buf  = slen;
619                int    size = buf.length();
620
621                // 'B' は、単位換算に関係ない為、あれば削除します。
622                if( size > 0 && 'B' == buf.charAt( size-1 ) ) {
623                        buf = buf.substring( 0,size-1 );                        // 'B' が削除された文字列
624                        size--;
625                }
626
627                long rtn = -1L;
628
629                long tani = -1L;                                                                // 変換されたかどうかの判定も兼ねる。
630                if( size > 0 ) {
631                        char ch = buf.charAt( size-1 );                         // 'K' , 'M' , 'G' のチェック
632                        switch( ch ) {
633                                case 'K' : tani=1024L; break;
634                                case 'M' : tani=1024L * 1024L ; break;
635                                case 'G' : tani=1024L * 1024L * 1024L ; break;
636                                default  : break;
637                        }
638                        if( tani > 0L ) {    // つまり、単位換算が行われた場合。
639                                buf = buf.substring( 0,size-1 );                // 'K','M','G' が削除された文字列
640                                size--;                                                                 // ここで空文字列になる可能性がある。
641                        }
642                        else {
643                                tani = 1L;              // 単位換算がない場合は、1倍。
644                        }
645                }
646
647                if( size > 0 ) {
648                        // 先の単位換算で、1L(=1倍)を設定して、if を無くしたが、long の掛け算なので、なんとなく抵抗がある。
649                        rtn = tani * Long.parseLong( buf );                     // buf はすでに数字だけになっているハズ。
650                }
651
652                return rtn ;
653        }
654
655        /**
656         * 内部判定フィルタ: 指定の大きさより大きいファイルの場合、スルー(選択)されます。
657         *
658         * 指定はバイト単位ですが、**KB , **MB , **GB などの単位を付ける事も可能です。
659         * 現時点では、K , KB , M , MB , G , GB のみ指定可能です。
660         *
661         * @og.rev 5.7.4.3 (2014/03/28) isLarger,isSmaller属性を文字列に変更
662         *
663         * @param       slen    ファイルの大きさ(バイト単位)。同値を含む
664         */
665//      public void isLarger( final int len ) {
666//              if( len >= 0 ) {
667//                      list.add( new IsLargerFilter( len ) );
668//              }
669//      }
670        public void isLarger( final String slen ) {
671                long len = getByteSize( slen );
672
673                if( len >= 0L ) {
674                        list.add( new IsLargerFilter( len ) );
675                }
676        }
677
678        /**
679         * 指定の大きさより大きいファイルの場合に選択される FileFilter インターフェースの実装内部クラスです。
680         *
681         * @version  4.0
682         * @author   Kazuhiko Hasegawa
683         * @since    JDK5.0,
684         */
685        private static class IsLargerFilter implements FileFilter {
686                private final long size ;
687
688                /**
689                 * 大きいファイルフィルターオブジェクトを作成します。
690                 *
691                 * @og.rev 5.7.4.3 (2014/03/28) isLarger,isSmaller属性をlongに変更
692                 *
693                 * @param       len     ファイルの大きさ(バイト単位)。同値を含む
694                 */
695//              IsLargerFilter( int len ) {
696                IsLargerFilter( final long len ) {
697                        size = len ;
698                }
699
700                /**
701                 * FileFilter インターフェースの accept( File ) メソッド
702                 *
703                 * @param       pathname        ファイルオブジェクト
704                 * @return      true:処理対象 / false:処理非対象
705                 * @see java.io.FileFilter#accept( File )
706                 */
707                public boolean accept( final File pathname ) {
708                        return pathname.length() >= size;
709                }
710        }
711
712        /**
713         * 内部判定フィルタ: 指定の大きさより小さいファイルの場合、スルー(選択)されます。
714         * 引数が 0以下(マイナス) の場合は、追加しません。
715         *
716         * @og.rev 5.7.4.3 (2014/03/28) isLarger,isSmaller属性を文字列に変更
717         *
718         * @param    slen ファイルの大きさ(バイト単位)。同値を含まない。
719         */
720//      public void isSmaller( final int len ) {
721//              if( len >= 0 ) {
722//                      list.add( new IsSmallerFilter( len ) );
723//              }
724//      }
725        public void isSmaller( final String slen ) {
726                long len = getByteSize( slen );
727
728                if( len >= 0L ) {
729                        list.add( new IsSmallerFilter( len ) );
730                }
731        }
732
733        /**
734         * 指定の大きさより小さいファイルの場合選択される FileFilter インターフェースの実装内部クラスです。
735         *
736         * @version  4.0
737         * @author   Kazuhiko Hasegawa
738         * @since    JDK5.0,
739         */
740        private static class IsSmallerFilter implements FileFilter {
741                private final long size ;
742
743                /**
744                 * 小さいファイルフィルターオブジェクトを作成します。
745                 *
746                 * @og.rev 5.7.4.3 (2014/03/28) isLarger,isSmaller属性をlongに変更
747                 *
748                 * @param    len ファイルの大きさ(バイト単位)。同値を含まない。
749                 */
750//              IsSmallerFilter( int len ) {
751                IsSmallerFilter( final long len ) {
752                        size = len ;
753                }
754
755                /**
756                 * FileFilter インターフェースの accept( File ) メソッド
757                 *
758                 * @param       pathname        ファイルオブジェクト
759                 * @return      true:処理対象 / false:処理非対象
760                 * @see java.io.FileFilter#accept( File )
761                 */
762                public boolean accept( final File pathname ) {
763                        return pathname.length() < size;
764                }
765        }
766
767        /**
768         * 内部判定フィルタ: ファイルが hidden の場合、スルー(選択)されます。
769         * 引数がtrueの場合は、hiddenファイルのみを選択します。
770         * falseの場合は、hiddenファイル以外を選択します。(つまり hiddenファイルをブロックします。)
771         * hidden をブロックしたい場合は、false を設定し、すべて選択したい場合は、filter設定をしない事になります。
772         * 引数が null の場合は、追加しません。
773         *
774         * @og.rev 5.7.5.0 (2014/04/04) 新規追加
775         *
776         * @param       flag [true:/false]
777         */
778        public void isHidden( final String flag ) {
779                isHidden( flag, false );                                // 反転しない
780        }
781
782        /**
783         * 内部判定フィルタ: ファイルが hidden の場合、スルー(選択)されます。
784         * 引数がtrueの場合は、hiddenファイルのみを選択します。
785         * falseの場合は、hiddenファイル以外を選択します。(つまり hiddenファイルをブロックします。)
786         * hidden をブロックしたい場合は、false を設定し、すべて選択したい場合は、filter設定をしない事になります。
787         * reverse = true に設定すると、結果を反転させます。
788         *
789         * @og.rev 5.7.5.0 (2014/04/04) 新規追加
790         *
791         * @param       flag [true:/false]
792         * @param       reverse true:結果を反転する
793         */
794        public void isHidden( final String flag,final boolean reverse ) {
795                if( flag != null ) {
796                        list.add( new IsHiddenFilter( flag,reverse ) );
797                }
798        }
799
800        /**
801         * ファイルが hidden の場合に選択される FileFilter インターフェースの実装内部クラスです。
802         * 引数がtrueの場合は、hiddenファイルのみを選択します。
803         * falseの場合は、hiddenファイル以外を選択します。(つまり hiddenファイルをブロックします。)
804         * hidden をブロックしたい場合は、false を設定し、すべて選択したい場合は、filter設定をしない事になります。
805         *
806         * @og.rev 5.7.5.0 (2014/04/04) 新規追加
807         *
808         * @version  6.0
809         * @author   Kazuhiko Hasegawa
810         * @since    JDK6.0,
811         */
812        private static class IsHiddenFilter implements FileFilter {
813                private final boolean  flg  ;
814                private final boolean  rvse ;
815
816                /**
817                 * hiddenフィルターオブジェクトを作成します。
818                 *
819                 * @param       flag    true:hiddenのみ / false:
820                 * @param       reverse true:結果を反転する
821                 */
822                IsHiddenFilter( final String flag,final boolean reverse ) {
823                        flg  = Boolean.parseBoolean( flag );
824                        rvse = reverse;
825                }
826
827                /**
828                 * FileFilter インターフェースの accept( File ) メソッド
829                 *
830                 * @param       pathname        ファイルオブジェクト
831                 * @return      true:処理対象 / false:処理非対象
832                 * @see java.io.FileFilter#accept( File )
833                 */
834                public boolean accept( final File pathname ) {
835                        return (pathname.isHidden()  ^  !flg) ^ rvse ;
836                                //  isHidden()          flg             !flg    rvse    ⇒ 結果
837                                // ======================================================
838                                //      true(hidden)    true    false   false   ⇒ true   選択
839                                //      true(hidden)    false   true    false   ⇒ false 除外
840                                //      false(normal)   true    false   false   ⇒ false 除外
841                                //      false(normal)   false   true    false   ⇒ true   選択
842
843                                //      true(hidden)    true    false   true    ⇒ false 除外
844                                //      true(hidden)    false   true    true    ⇒ true   選択
845                                //      false(normal)   true    false   true    ⇒ true   選択
846                                //      false(normal)   false   true    true    ⇒ false 除外
847                }
848        }
849
850        /**
851         * このオブジェクトの文字列表現を返します。
852         * 基本的にデバッグ目的に使用します。
853         *
854         * @return このクラスの文字列表現
855         */
856        @Override
857        public String toString() {
858                StringBuilder buf = new StringBuilder();
859                int size = list.size();
860                for( int i=0; i<size; i++ ) {
861                        buf.append( "no[" ).append( i ).append( "]=" );
862                        buf.append( list.get(i) ).append( "\n" );
863                }
864
865                return buf.toString();
866        }
867}
868
869/**
870 * ModifyFileFilter.java は、最終変更日付けのフィルタークラスです。
871 *
872 * FileFilter インターフェースを継承し、コンストラクタで指定の日付けよりも
873 * 最終変更日付け が新しいファイルを、選択します。
874 * このクラスでは、ディレクトリは、変更日付けに無関係に選択します。
875 *
876 * 日付けの指定に、YYYYMMDD 形式の 8文字数字文字列以外に、TODAY や YESTERDAY なども使用できます。
877 * TODAY は、実行日の 00:00:00 を基準時刻とし、YESTERDAY は、その前日になります。
878 * バッチ処理等で、前日分の再編成や、先月分を再編成する場合に、実日付けを指定せずに
879 * 使用できます。
880 *
881 * この実装は同期化されません。
882 *
883 * @version  4.0
884 * @author   Kazuhiko Hasegawa
885 * @since    JDK5.0,
886 */
887class ModifyFileFilter implements FileFilter {
888        private final long modify ;
889
890        /**
891         * コンストラクター
892         *
893         * 日付けの指定方法には、実日付け(YYYYMMDD形式 例:20040323)と
894         * 仮想日付け(TODAY,YESTERDAY など)が指定できます。
895         *
896         *     YYYYMMDD   YYYYMMDD形式の指定日の 00:00:00 を基準時刻
897         *     TODAY      実行日の 00:00:00 を基準時刻
898         *     YESTERDAY  実行日前日の 00:00:00 を基準時刻
899         *     LAST_WEEK  実行日の先週(7日前) 00:00:00 を基準時刻
900         *     MONTH      実行月の 1日 00:00:00 を基準時刻
901         *     LAST_MONTH 実行前月の 同日 00:00:00 を基準時刻
902         *     LAST_YEAR  実行前年の 同月同日 00:00:00 を基準時刻
903         *
904         * @og.rev 5.3.5.0 (2011/05/01) 「時」のクリアミスの修正
905         *
906         * @param value 指定日付け
907         */
908        public ModifyFileFilter( final String value ) {
909                if( value != null ) {
910                        Calendar cal = Calendar.getInstance();
911
912//                      cal.clear( Calendar.HOUR_OF_DAY );
913                        cal.set( Calendar.HOUR_OF_DAY, 0 );             // 5.3.5.0 (2011/05/01) 時間の解決規則が適用されるため、「時」だけは、setメソッドで 0 にセットする。
914                        cal.clear( Calendar.MINUTE );
915                        cal.clear( Calendar.SECOND );
916                        cal.clear( Calendar.MILLISECOND );
917
918                        if( value.equalsIgnoreCase( "YESTERDAY" ) ) {
919                                cal.add( Calendar.DATE, -1 );
920                        }
921                        else if( value.equalsIgnoreCase( "LAST_WEEK" ) ) {
922                                cal.add( Calendar.DATE, -7 );
923                        }
924                        else if( value.equalsIgnoreCase( "MONTH" ) ) {
925                                cal.set( Calendar.DATE, 1 );
926                        }
927                        else if( value.equalsIgnoreCase( "LAST_MONTH" ) ) {
928                                cal.add( Calendar.MONTH, -1 );
929                        }
930                        else if( value.equalsIgnoreCase( "LAST_YEAR" ) ) {
931                                cal.add( Calendar.YEAR, -1 );
932                        }
933                        else if( value.length() == 8 ) {
934                                cal.set( Integer.parseInt( value.substring( 0,4 ) ) ,
935                                                 Integer.parseInt( value.substring( 4,6 ) ) - 1,
936                                                 Integer.parseInt( value.substring( 6,8 ) ) );
937                        }
938                        else if( ! value.equalsIgnoreCase( "TODAY" ) ) {
939                                String errMsg = "ModifyFileFilter Error! modify Format [" + value + "]\n"
940                                                 + "日付けの指定方法には、実日付け(YYYYMMDD形式 例:20040323)と \n"
941                                                 + "仮想日付け(TODAY,YESTERDAY など)が指定できます。\n"
942                                                 + "    YYYYMMDD   YYYYMMDD形式の指定日の 00:00:00 を基準時刻 \n"
943                                                 + "    TODAY      実行日の 00:00:00 を基準時刻 \n"
944                                                 + "    YESTERDAY  実行日前日の 00:00:00 を基準時刻 \n"
945                                                 + "    LAST_WEEK  実行日の先週(7日前) 00:00:00 を基準時刻 \n"
946                                                 + "    MONTH      実行月の 1日 00:00:00 を基準時刻 \n"
947                                                 + "    LAST_MONTH 実行前月の 同日 00:00:00 を基準時刻 \n"
948                                                 + "    LAST_YEAR  実行前年の 同月同日 00:00:00 を基準時刻 \n" ;
949                                throw new RuntimeException( errMsg );
950                        }
951                        modify = cal.getTimeInMillis() ;
952                }
953                else {
954                        throw new RuntimeException( "ModifyFileFilter Error! modify valus is not null" );
955                }
956        }
957
958        /**
959         * FileFilter インターフェースの accept( File ) メソッド
960         *
961         * @param       file    ファイルオブジェクト
962         *
963         * @return      true:処理対象 / false:処理非対象
964         * @see java.io.FileFilter#accept( File )
965         */
966        public boolean accept( final File file ) {
967                return file.isDirectory() || ( file.lastModified() >= modify ) ;
968        }
969}