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.util;
017    
018    import java.io.FileInputStream;
019    import java.io.FileOutputStream;
020    
021    // import java.util.Date;
022    // import java.util.Locale;
023    // import java.text.DateFormat;
024    // import java.text.SimpleDateFormat;
025    
026    /**
027     * DateSet.java は、å?力ファイルの日付,時刻キーワードを実行時の日時で変換して,出力しますã?
028     *
029     * 変換には,$(yyyy)の形式でæŒ?®šし,カãƒ?‚³のæ–?­—å?は,java.text.SimpleDateFormat で使用する??
030     * 時刻フォーマット構文を用ã�?�¾すã?
031     * またã?引数に keys,vals を渡すことでã€?(KEY1) æ–?­—å?ã‚?VAL1 æ–?­—å?と置き換えますã?
032     *
033     *  サンプルファイル
034     *  $(yyyy/MM/dd)        年?�月?�日を表しますã?
035     *  $(yy)                年ã�?�‘を2桁で表しますã?
036     *  $(MM)                月を?’æ¡?(02,03など)で表しますã?
037     *  $(dd)                日を2æ¡?(02,03など)で表しますã?
038     *  $(HH:mm:ss)          時:å??š秒を表しますã?
039     *  $(MMMMMMMM)          月をフルスペルで表しますã?
040     *  $(MMM)               月を?“桁固å®?Mar?ŒAplなど)で表しますã?
041     *  $(EEEEEEEE)          曜日をフルスペルで表しますã?
042     *  $(EEE)               曜日を3桁固å®?Sun,Monなど)で表しますã?
043     *
044     *   時刻フォーマット構文
045     *
046     *   記号     意味                    表示                ä¾?
047     *   ------   -------                 ------------        -------
048     *   G        年号                    (ãƒ?‚­スãƒ?          AD
049     *   y        年                      (数値)              1996
050     *   M        æœ?                     (ãƒ?‚­スãƒ?& 数値)  July & 07
051     *   d        日                      (数値)              10
052     *   h        午前/午後ã?æ™?(1~12)    (数値)              12
053     *   H        ä¸?—¥における時 (0~23)   (数値)              0
054     *   m        åˆ?                     (数値)              30
055     *   s        ç§?                     (数値)              55
056     *   S        ミリç§?                 (数値)              978
057     *   E        曜日                    (ãƒ?‚­スãƒ?          火曜日
058     *   D        年における日            (数値)              189
059     *   F        月における曜日          (数値)              2 (7月ã?第2水曜日)
060     *   w        年におけるé?            (数値)              27
061     *   W        月におけるé?            (数値)              2
062     *   a        午前/午å¾?              (ãƒ?‚­スãƒ?          PM
063     *   k        ä¸?—¥における時 (1~24)   (数値)              24
064     *   K        午前/午後ã?æ™?(0~11)    (数値)              0
065     *   z        時間帯                  (ãƒ?‚­スãƒ?          PDT
066     *   '        ãƒ?‚­スト用エスケーãƒ?
067     *   ''       単ä¸?¼•用符                                  '
068     *
069     *  パターンæ–?­—ã?カウントによって、そのフォーマットが決まりますã?
070     *  (ãƒ?‚­スãƒ?: 4以ä¸? フル形式を使用しますã?4以ä¸? 短ã�?�¾たã?省力された形式があれば、それを使用しますã?
071     *
072     *  (数値): æœ?°�桁数。これより短ã�?•°値は、この桁数までゼロが追åŠ?�•れますã?年には特別な処ç�?�Œありますã?
073     *  つまりã?'y'のカウントが2ならã?年は2桁に短縮されますã?
074     *
075     *  (ãƒ?‚­スãƒ???数値): 3以上ならテキストを、それ以外なら数値を使用しますã?
076     *
077     *  パターンのæ–?­—が['a'..'z']と['A'..'Z']のç¯?›²になければ、そのæ–?­—ã?引用ãƒ?‚­ストとして扱われますã?
078     *  たとえã?ã€?:'ã€?.'ã€? 'ã€?#'ã€?@'などのæ–?­—ã?、単ä¸?¼•用符に囲まれてã�?�ªくてもã?
079     *  結果の時刻ãƒ?‚­ストに使用されますã?
080     *
081     *  無効なパターンæ–?­—がパターンに入ってã�?‚‹と、フォーマットや解析で例外がスローされますã?
082     *
083     *  USロケールを使ったä¾?
084     *
085     *   フォーマットパターン                   結果
086     *   --------------------                   ----
087     *   "yyyy.MM.dd G 'at' hh:mm:ss z"    � 1996.07.10 AD at 15:08:56 PDT
088     *   "EEE, MMM d, ''yy"                � Wed, July 10, '96
089     *   "h:mm a"                          � 12:08 PM
090     *   "hh 'o''''clock' a, zzzz"         � 12 o'clock PM, Pacific Daylight Time
091     *   "K:mm a, z"                       � 0:00 PM, PST
092     *   "yyyyy.MMMMM.dd GGG hh:mm aaa"    � 1996.July.10 AD 12:08 PM
093     *
094     * @version  0.9.0  1999/03/09
095     * @author   Kazuhiko Hasegawa
096     * @since    JDK1.1,
097     */
098    public class DateSet {
099            private String[] keys = null;
100            private String[] vals = null;
101    
102            /**
103             * フォーマット解析時に置き換える キーと値の配å?を設定しますã?
104             *
105             * $(KEY1) æ–?­—å?ã‚?VAL1 æ–?­—å?と置き換える処ç�?‚’行いますã?これにより日付以外ã?
106             * æ–?­—å?を置き換える処ç�?‚’実行できますã?
107             *
108             * @param       inkeys  置き換えå?キー配å?
109             * @param       invals  置き換えå?値配å?
110             */
111            public void setKeysVals( final String[] inkeys, final String[] invals ) {
112                    if( inkeys != null && invals != null && inkeys.length == invals.length ) {
113                            int size = inkeys.length ;
114                            keys = new String[size];
115                            vals = new String[size];
116                            System.arraycopy( inkeys,0,keys,0,size );
117                            System.arraycopy( invals,0,vals,0,size );
118                    }
119            }
120    
121            /**
122             * 現在日付ã?時刻をフォーマット指定å?æ‰?�«埋め込みますã?
123             * フォーマットã?æŒ?®š方法ã?、java.text.SimpleDateFormat のæŒ?®š方法と同ä¸?�§すã?
124             *
125             * @param       inByte  変換å…?ƒ�イトé?åˆ?
126             *
127             * @return      変換後ã?バイトé?åˆ?
128             */
129            public byte[] change( final byte[] inByte ) {
130                    byte[] outByte = new byte[ inByte.length+100 ];
131                    int add = 0;
132                    for( int i=0; i<inByte.length; i++) {
133                            if( inByte[i] == '$' && i<inByte.length-1 && inByte[i+1] == '(' ) {
134                                    int j = 0;
135                                    while( inByte[i+j+2] != ')') { j++; }
136    //                              String str = changeForm( new String( inByte,i+2,j ) );
137    //                              byte[] byteDate = str.getBytes() ;
138                                    String str = changeForm( new String( inByte,i+2,j,StringUtil.DEFAULT_CHARSET ) );       // 5.5.2.6 (2012/05/25) findbugs対å¿?
139                                    byte[] byteDate = str.getBytes( StringUtil.DEFAULT_CHARSET ) ;                                          // 5.5.2.6 (2012/05/25) findbugs対å¿?
140                                    for( int k = 0; k<byteDate.length; k++) {
141                                            outByte[add] = byteDate[k];
142                                            add++;
143                                    }
144                                    i += j+2;
145                            }
146                            else {
147                                    outByte[add] = inByte[i];
148                                    add++;
149                            }
150                    }
151                    byte[] rtnByte = new byte[ add ];
152                    System.arraycopy( outByte,0,rtnByte,0,add );
153                    return rtnByte;
154            }
155    
156            /**
157             * keys,vals の変換、およã?、現在日付ã?時刻のフォーマット変換を行いますã?
158             *
159             * 先に、keys,vals の変換を行いますã?form がã?keys にマッチすれã?、vals ã‚?
160             * 返しますã?æœ?¾Œまでマッチしなければ、時刻のフォーマット変換を行いますã?
161             * フォーマットã?æŒ?®š方法ã?、java.text.SimpleDateFormat のæŒ?®š方法と同ä¸?�§すã?
162             *
163             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正しますã?
164             *
165             * @param       form フォーãƒ?–‡字å? ( ä¾?"yyyy/MM/dd HH:mm:ss" )
166             *
167             * @return      フォーマット変換結果
168             */
169            public String changeForm( final String form ) {
170                    if( keys != null ) {
171                            for( int i=0; i<keys.length; i++ ) {
172                                    if( form.equals( keys[i] ) ) {
173                                            return vals[i];
174                                    }
175                            }
176                    }
177    
178    //              DateFormat formatter = new SimpleDateFormat( form, Locale.JAPAN );
179    //              return formatter.format(new Date());
180    
181                    return HybsDateUtil.getDate( form );
182            }
183    
184            /**
185             * keys,vals の変換、およã?、現在日付ã?時刻のフォーマット変換を行いますã?
186             *
187             * 先に、keys,vals の変換を行いますã?form がã?keys にマッチすれã?、vals ã‚?
188             * 返しますã?æœ?¾Œまでマッチしなければ、時刻のフォーマット変換を行いますã?
189             * フォーマットã?æŒ?®š方法ã?、java.text.SimpleDateFormat のæŒ?®š方法と同ä¸?�§すã?
190             *
191             * @param       form フォーãƒ?–‡字å? ( ä¾?"yyyy/MM/dd HH:mm:ss" )
192             *
193             * @return      フォーマット変換結果
194             */
195            public String changeString( final String form ) {
196                    StringBuilder buf = new StringBuilder( 200 );
197                    int bkst = 0;
198                    int st = form.indexOf( "$(" );
199                    while( st >= 0 ) {
200                            buf.append( form.substring( bkst,st ) );
201                            int ed = form.indexOf( ")",st+2 );
202                            buf.append( changeForm( form.substring( st+2,ed ) ) );
203                            bkst = ed + 1;
204                            st = form.indexOf( "$(",bkst );
205                    }
206                    buf.append( form.substring( bkst ) );
207    
208                    return buf.toString();
209            }
210    
211            /**
212             * 現在日付ã?時刻をフォーマットをæŒ?®šして、所得しますã?
213             * フォーマットã?æŒ?®š方法ã?、java.text.SimpleDateFormat のæŒ?®š方法と同ä¸?�§すã?
214             *
215             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するため、削除ã€?
216             *
217             * @param       form フォーãƒ?–‡字å? ( ä¾?"yyyy/MM/dd HH:mm:ss" )
218             *
219             * @return      現在日付ã?時刻
220             */
221    //      public static String getDate( final String form ) {
222    //              DateFormat formatter = new SimpleDateFormat( form, Locale.JAPAN );
223    //              return formatter.format(new Date());
224    //      }
225    
226            /**
227             * 入力ファイルの時刻フォーマットを変換して出力ファイルに書き込みますã?
228             *
229             * 引数に &lt;key1&gt; &lt;val1&gt; のペアæƒ??を渡すことが可能ですã?
230             * 先に、keys,vals の変換を行いますã?form がã?keys にマッチすれã?、vals ã‚?
231             * 返しますã?æœ?¾Œまでマッチしなければ、時刻のフォーマット変換を行いますã?
232             * フォーマットã?æŒ?®š方法ã?、java.text.SimpleDateFormat のæŒ?®š方法と同ä¸?�§すã?
233             * フォーãƒ?–‡字å?ä¾?(  "yyyy/MM/dd HH:mm:ss" )
234             *
235             * @param       args 引数配å?( 入力ファイル 出力ファイル キー??値???¥?¥?¥
236             * @throws Throwable なんらかã?エラーが発生したå?合ã?
237             */
238            public static void main( final String[] args ) throws Throwable {
239                    if( args.length > 2 && ( args.length % 2 != 0 ) ) {
240    //                      LogWriter.log("Usage: java DateSet <inputFile> <outputFile> [<key1> <val1> ?¥?¥?¥]" );
241                            System.err.println( "Usage: java DateSet <inputFile> <outputFile> [<key1> <val1> ?¥?¥?¥]" );
242                            return ;
243                    }
244    
245                    String[] keys = new String[ (args.length-2)/2 ];
246                    String[] vals = new String[ (args.length-2)/2 ];
247                    for( int i=1; i<=keys.length; i++ ) {
248                            keys[i-1] = args[i*2];
249                            vals[i-1] = args[i*2+1];
250                    }
251    
252                    FileInputStream filein = new FileInputStream( args[0] );
253                    byte[] byteIn = new byte[ filein.available() ];
254                    int len = filein.read( byteIn );
255                    if( len != byteIn.length ) {
256                            String errMsg = "読み取りファイルのãƒ??タがå?り捨てられましたã€? +
257                                                            "File=" + args[0] + " Length=" + len  + " Input=" + byteIn.length ;
258    //                      LogWriter.log( errMsg );
259                            System.err.println( errMsg );
260                    }
261                    filein.close();
262    
263                    DateSet dateSet = new DateSet();
264                    dateSet.setKeysVals( keys,vals );
265                    byte[] byteout = dateSet.change( byteIn );
266    
267                    FileOutputStream fileout = new FileOutputStream( args[1] );
268                    fileout.write( byteout );
269                    fileout.close();
270            }
271    }