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