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.fukurou.process;
017    
018    import org.opengion.fukurou.util.FileUtil;
019    import org.opengion.fukurou.util.Closer;
020    import org.opengion.fukurou.util.HybsDateUtil;
021    import org.opengion.fukurou.util.CommentLineParser;
022    
023    import org.opengion.fukurou.security.HybsCryptography ;         // 5.7.2.1 (2014/01/17)
024    
025    import java.io.File;
026    import java.io.BufferedReader;
027    import java.io.IOException;
028    // import java.util.Date;
029    // import java.util.Locale;
030    // import java.text.DateFormat;
031    // import java.text.SimpleDateFormat;
032    
033    /**
034     * FileLineModel は、LineModel を継承した ファイルリスト専用の
035     * LineModel の実?ラスです?
036     *
037     * FileLineModel オブジェクトには、ファイル属?(Level,File,Length,Modify,LineCnt,Biko,MD5)
038     * が設定されます?
039     * LineCnt と、MD5 は、それぞれ?計算するかど?のフラグを設定する?があります?
040     *
041     * ※ useLineCnt=false の場合?Length(?数)は、File#length() メソ?で求めます?
042     *    ?、useLineCnt=true にすると、行単位に、String#length() を加算するため?
043     *    先?Length(?数)値とは異なります?でご注意く???
044     *
045     * omitCmnt=true にすると、コメント部?削除した行数と?数を求めます?
046     * これは?* から */ の間?// から改行までです?
047     * ただし?"(二重引用符)で囲まれた??は、コメントとみなしません?
048     *
049     * ??タの?行??FileLineModel に割り当てます?
050     * カラ?号は? から始まります?カラ?よりカラ?号を求める?合に?
051     * 存在しな??合??1 を返します?
052     * カラ?号?-1 の場合?、??行いません?
053     *
054     * 注意:このクラスは、同期??れて?せん?
055     *
056     * @version  4.0
057     * @author   Kazuhiko Hasegawa
058     * @since    JDK5.0,
059     */
060    public class FileLineModel extends LineModel {
061            // 5.7.2.1 (2014/01/17) MD5 ?追?
062    //      private static final String[] KEYS = new String[] { "Level","File","Length","Modify","LineCnt","Biko" };
063            private static final String[] KEYS = new String[] { "Level","File","Length","Modify","LineCnt","Biko","MD5" };
064    
065            private static final int LEVEL    = 0;
066            private static final int FILE     = 1;
067            private static final int LENGTH   = 2;
068            private static final int MODIFY   = 3;
069            private static final int LINECNT  = 4;
070            private static final int BIKO     = 5;
071            private static final int MD5      = 6;          // 5.7.2.1 (2014/01/17)
072    
073    //      private final DateFormat formatter = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss",Locale.JAPAN );
074    
075            private final boolean useLineCnt ;
076            private final boolean useMD5 ;                          // 5.7.2.1 (2014/01/17) MD5 ?追?
077            private final boolean omitCmnt ;                        // 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?
078            private String encode = "JISAutoDetect";        // 5.7.4.0 (2014/03/07) コメント削除時??数計算で利用するファイルのエンコー?
079    
080            /**
081             * コンストラクターです?
082             * useLineCnt=false , useMD5=false , omitCmnt=false で初期化されます?
083             *
084             * @og.rev 5.7.2.1 (2014/01/17) MD5対?
085             * @og.rev 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?対?
086             *
087             */
088            public FileLineModel() {
089    //              this( false,false );                                    // 5.7.2.1 (2014/01/17)
090                    this( false,false,false );                              // 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?
091            }
092    
093            /**
094             * ラインカウント?有無を指定した?コンストラクターです?
095             * useMD5=false , omitCmnt=false で初期化されます?
096             *
097             * @og.rev 4.2.2.0 (2008/05/10) 行数カウント?使用有無
098             * @og.rev 5.7.2.1 (2014/01/17) MD5対?
099             * @og.rev 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?対?
100             *
101             * @param       isLineCnt       行数カウント?使用有無
102             */
103            public FileLineModel( final boolean isLineCnt ) {
104    //              this( isLineCnt,false );                                // 5.7.2.1 (2014/01/17)
105                    this( isLineCnt,false,false );                  // 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?
106            }
107    
108            /**
109             * ラインカウント?有無と、MD5計算?有無を指定した?コンストラクターです?
110             * omitCmnt=false で初期化されます?
111             *
112             * @og.rev 5.7.2.1 (2014/01/17) 新規追?MD5対?
113             * @og.rev 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?対?
114             *
115             * @param       isLineCnt       行数カウント?使用有無
116             * @param       isMD5           ファイルのMD5の使用有無
117             */
118            public FileLineModel( final boolean isLineCnt,final boolean isMD5 ) {
119                    this( isLineCnt,isMD5,false );                          // 5.7.4.0 (2014/03/07) コメント除?
120            }
121    
122            /**
123             * ラインカウント?有無と、MD5計算?有無と、コメント除外?可否を指定した?コンストラクターです?
124             *
125             * @og.rev 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?
126             *
127             * @param       isLineCnt       行数カウント?使用有無
128             * @param       isMD5           ファイルのMD5の使用有無
129             * @param       isOmit          コメント除外?可否(true:除外す?
130             */
131            public FileLineModel( final boolean isLineCnt,final boolean isMD5,final boolean isOmit ) {
132                    // 4.3.4.4 (2009/01/01)
133    //              super();
134                    useLineCnt = isLineCnt;
135                    useMD5     = isMD5;                             // 5.7.2.1 (2014/01/17)
136                    omitCmnt   = isOmit;                    // 5.7.4.0 (2014/03/07)
137                    init( KEYS );
138            }
139    
140            /**
141             * LineModel を?に、FileLineModel を構築します?
142             * これは、?ファイル等にセーブされた FileLineModel 形式を
143             * ?戻す簡易コンストラクタです?
144             *
145             * @og.rev 4.2.3.0 (2008/05/26) 新規追?
146             * @og.rev 5.7.2.1 (2014/01/17) MD5の設定???
147             *
148             * @param       model   ??LineModel
149             */
150            public FileLineModel( final LineModel model ) {
151                    // 4.3.4.4 (2009/01/01)
152    //              super();
153                    init( model.getNames() );
154    
155                    Object[] obj = model.getValues();
156    
157                    setValue( LEVEL   ,Integer.valueOf( (String)obj[LEVEL] ) );
158                    setValue( FILE    ,new File((String)obj[FILE]) );
159                    setValue( LENGTH  ,Long.valueOf( (String)obj[LENGTH] ) );
160                    setValue( MODIFY  ,(String)obj[MODIFY] );
161    
162                    String cnt = (String)obj[LINECNT] ;
163    //              useLineCnt = ( cnt != null && cnt.length() > 0 && ! "null".equals( cnt ) );
164                    useLineCnt = ( cnt != null && cnt.length() > 0 && ! "null".equalsIgnoreCase( cnt ) );
165                    if( useLineCnt ) { setValue( LINECNT ,cnt ); }
166    
167                    setValue( BIKO  ,(String)obj[BIKO] );
168    
169                    // 5.7.2.1 (2014/01/17) 
170                    String md5Data = (String)obj[MD5] ;
171                    useMD5 = ( md5Data != null && md5Data.length() > 0 && ! "null".equalsIgnoreCase( md5Data ) );
172                    if( useMD5 ) { setValue( MD5 ,md5Data ); }
173    
174                    omitCmnt   = false;                     // 5.7.4.0 (2014/03/07) 既存? LineModel から取得できな??で、強制設定します?
175            }
176    
177            /**
178             * File属?値をセ?します?
179             * LEVEL,FILE,LENGTH,MODIFY,LINECNT,MD5 の??を設定します?
180             *
181             * @og.rev 4.2.2.0 (2008/05/10) 行数カウント?使用有無
182             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します?
183             * @og.rev 5.7.2.1 (2014/01/17) MD5計算???追?
184             * @og.rev 5.7.4.0 (2014/03/07) コメント除外?可否(true:除外す?対?
185             *
186             * @param       level   ファイルの?レクトリ階層
187             * @param       file    ファイルオブジェク?
188             */
189            public void setFileVals( final int level, final File file ) {
190                    setValue( LEVEL  ,Integer.valueOf( level ) );
191                    setValue( FILE   ,file );
192    //              setValue( LENGTH ,Long.valueOf( file.length() ) );      // 5.7.4.0 (2014/03/07) useLineCnt に応じて値が異なる?
193    //              setValue( MODIFY ,formatter.format( new Date( file.lastModified() ) ) );
194                    setValue( MODIFY ,HybsDateUtil.getDate( file.lastModified(),"yyyy/MM/dd HH:mm:ss" ) );          // 5.5.7.2 (2012/10/09) HybsDateUtil を利用する
195                    if( useLineCnt || omitCmnt ) {
196    //                      setValue( LINECNT ,getLineCnt( file ) );                // 5.7.4.0 (2014/03/07) 
197                            long[] cntVals = getLineCnt( file );
198                            setValue( LINECNT ,String.valueOf( cntVals[0] ) );
199                            setValue( LENGTH  ,Long.valueOf(   cntVals[1] ) );
200                    }
201                    else {
202                            setValue( LENGTH  ,Long.valueOf( file.length() ) );
203                    }
204    
205                    // 5.7.2.1 (2014/01/17) MD5計算がtrue で、かつ、ファイルの場合?MD5 計算を行います?
206                    if( useMD5 && file.isFile() ) {
207                            setValue( MD5 ,HybsCryptography.getMD5( file ) );
208                    }
209            }
210    
211            /**
212             * コメント削除時??数計算で利用するファイルのエンコードをセ?します?
213             * 初期値:JISAutoDetect
214             *
215             * @og.rev 5.7.4.0 (2014/03/07) 新規追?
216             *
217             * @param       encode  コメント削除時??数計算で利用するファイルのエンコー?
218             */
219            public void setEncode( final String encode ) {
220                    this.encode = encode;
221            }
222    
223            /**
224             * File属?値をセ?します?
225             *
226             * @param       file    ファイルオブジェク?
227             */
228            public void setFile( final File file ) {
229                    setValue( FILE,file );
230            }
231    
232            /**
233             * 備???属?値をセ?します?
234             *
235             * @og.rev 4.2.2.0 (2008/05/10) 行数カウント?使用有無
236             *
237             * @param       biko    備???
238             */
239            public void setBiko( final String biko ) {
240                    setValue( BIKO,biko );
241            }
242    
243            /**
244             * レベル File属?値を取得します?
245             *
246             * @return      ファイルの?レクトリ階層
247             */
248            public int getLebel() {
249                    return ((Integer)getValue( LEVEL )).intValue();
250            }
251    
252            /**
253             * ファイルを取得します?
254             *
255             * @return      ファイル
256             */
257            public File getFile() {
258                    return (File)getValue( FILE );
259            }
260    
261            /**
262             * ファイルサイズ File属?値を取得します?
263             *
264             * @return      ファイルサイズ
265             */
266            public long getLength() {
267                    return ((Long)getValue( LENGTH )).longValue();
268            }
269    
270            /**
271             * 更新日?File属?値を取得します?
272             *
273             * @return      更新日?yyyy/MM/dd HH:mm:ss)
274             */
275            public String getModify() {
276                    return (String)getValue( MODIFY );
277            }
278    
279            /**
280             * MD5 File属?値を取得します?
281             * ただし?useMD5 ?true でな?値は返しません?
282             *
283             * @og.rev 5.7.2.1 (2014/01/17) 新規追?MD5対?
284             *
285             * @return      MD5の値
286             */
287            public String getMD5() {
288                    return (String)getValue( MD5 );
289            }
290    
291            /**
292             * 行数と?数を取得します?
293             * 行数カウントとファイルの?数カウン?バイト数ではありません)を行います?
294             * ※ useLineCnt=false の場合?Length(?数)は、File#length() メソ?で求めます?
295             *    ?、useLineCnt=true にすると、行単位に、String#length() を加算するため?
296             *    先?Length(?数)値とは異なります?でご注意く???
297             *
298             * 結果は、long型?配?で返します?[0]が行数で、[1]が文字数です?
299             * omitCmnt 属?を使用した場合?、コメント部?削除した行数と?数を求めます?
300             * これは?* から */ の間?// から改行までです?
301             * ただし?"(二重引用符)で囲まれた??は、コメントとみなしません?
302             *
303             * @og.rev 5.7.4.0 (2014/03/07) 行数カウントとファイルの?数カウントを行う?
304             *
305             * @param       file    行数を数えるファイルオブジェク?
306             *
307             * @return  long型?配?([0]が行数で、[1]が文字数)
308             */
309    //      private String getLineCnt( final File file ) {
310            private long[] getLineCnt( final File file ) {
311                    long lineCnt = 0L;              // 行数
312                    long charCnt = 0L;              // ?数
313    
314    //              BufferedReader reader = FileUtil.getBufferedReader( file,"JISAutoDetect" );
315                    BufferedReader reader = FileUtil.getBufferedReader( file,encode );
316    
317                    CommentLineParser clp = ( omitCmnt ) ? new CommentLineParser() : null;
318                    try {
319                            if( ! file.isDirectory() ) {
320                                    String line ;
321                                    while((line = reader.readLine()) != null) {
322                                            if( omitCmnt ) {
323                                                    line = clp.line( line );
324                                                    if( line == null ) { continue; }        // 戻り??null の場合?、行として不??
325                                            }
326    
327                                            lineCnt++;
328                                            charCnt += line.length();
329                                    }
330                            }
331                    }
332                    catch( IOException ex ) {
333                            String errMsg = "ファイルカウント中に例外が発生しました?" + file + "]" ;
334                            throw new RuntimeException( errMsg,ex );
335                    }
336                    finally {
337                            Closer.ioClose( reader ) ;
338                    }
339    
340                    return new long[] { lineCnt,charCnt };
341            }
342    }