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.text.DateFormat;
019    // import java.text.SimpleDateFormat;
020    // import java.util.Locale;
021    // import java.util.Calendar;
022    import java.util.ArrayList;
023    import java.util.Map;
024    import java.util.HashMap;
025    
026    /**
027     * SystemParameter は、{@XXXX} æ–?­—å?をå?ç�?�™るクラスですã?
028     * こã?クラスでは、{@XXXX} æ–?­—å?を別のæ–?­—å?と置き換えることã‚??
029     * 予め予ç´?�•れてã�?‚‹予ç´?ª?{@SYS.XXXX} æ–?­—å?を置き換えますã?
030     * 通常の {@XXXX} æ–?­—å?の置き換えã?、キーと値のペアをã?HybsEntry オブジェクトに
031     * セãƒ?ƒˆして、その配å?を受け取って処ç�?�—ますã?
032     *
033     * 以下ã?値はあらかじめã?動的に作æ?されますã?
034     * ・SYS.YMD       ?˜byte の今日のシスãƒ?ƒ 日ä»?yyyyMMdd)
035     * ・SYS.YMDH    ?‘4byte の今日のシスãƒ?ƒ 日æ™?yyyyMMddHHmmss)
036     * ・SYS.HMS       ?–byte の今日のシスãƒ?ƒ 時間(HHmmss)
037     *
038     * @og.group ユーãƒ?‚£リãƒ?‚£
039     *
040     * @version  4.0
041     * @author   Kazuhiko Hasegawa
042     * @since    JDK5.0,
043     */
044    public final class SystemParameter {
045    
046    //      private final Map<String,String> sysMap = new HashMap<String,String>();
047            /** 改行コーãƒ?*/
048            public static final String CR = System.getProperty("line.separator");   // 5.1.9.0 (2010/08/01) 追åŠ?
049    
050            //      5.5.7.2 (2012/10/09) HybsDateUtil を利用するため、削除しますã?
051    //      private static final Map<String,String>   DATE_FORMAT = new HashMap<String,String>();       // 5.3.4.0 (2011/04/01)
052    //      static {
053    //              DATE_FORMAT.put( "SYS.YMD"              ,"yyyyMMdd"                             );
054    //              DATE_FORMAT.put( "SYS.YMDH"     ,"yyyyMMddHHmmss"               );
055    //              DATE_FORMAT.put( "SYS.HMS"              ,"HHmmss"                               );
056    //              DATE_FORMAT.put( "DATE.YMD"     ,"yyyyMMdd"                     );
057    //              DATE_FORMAT.put( "DATE.Y2MD"    ,"yyMMdd"                               );
058    //              DATE_FORMAT.put( "DATE.YM"              ,"yyyyMM"                               );
059    //              DATE_FORMAT.put( "DATE.HMS"     ,"HHmmss"                               );
060    //              DATE_FORMAT.put( "DATE.YMDHMS"  ,"yyyyMMddHHmmss"               );
061    //              DATE_FORMAT.put( "DATE.YMDF"    ,"yyyy/MM/dd"                   );
062    //              DATE_FORMAT.put( "DATE.Y2MDF"   ,"yy/MM/dd"                     );
063    //              DATE_FORMAT.put( "DATE.YMF"     ,"yyyy/MM"                              );
064    //              DATE_FORMAT.put( "DATE.HMSF"    ,"HH:mm:ss"                     );
065    //              DATE_FORMAT.put( "DATE.YMDHMSF" ,"yyyy/MM/dd/ HH:mm:ss" );
066    //              DATE_FORMAT.put( "DATE.EEE"     ,"EEE"                                  );
067    //      }
068    
069            private final String    original ;
070            // 5.5.7.2 (2012/10/09) Calendarオブジェクトからã?String時刻に変更ã€?
071    //      private final Calendar  rightNow;                                                                       // 5.3.4.0 (2011/04/01)
072            private final String    RIGHT_NOW = HybsDateUtil.getDate( "yyyyMMdd" );
073    
074            private final String[] clms;
075            private final String[] formats;
076    
077            /**
078             *  {&#064;XXXX} の特殊文字を含ã‚?–‡字å?をã?置き換えますã?
079             * 対象外ã?æ–?­—å?は、そのまま、残されますã?
080             *
081             * @og.rev 5.1.8.0 (2010/07/01) パã?ス方法見直ã�?StringTokenizerでは、{&#064;XXXX}がé?続してある場合に対応できなã�?
082             * @og.rev 5.3.2.0 (2011/02/01) original ãƒ??タをã?パã?ス結果を利用するように修正するã€?
083             * @og.rev 5.3.4.0 (2011/04/01) {&#064;DATE.XXXX} をå?ç�?�§きるように機è?追åŠ?
084             * @og.rev 5.3.5.0 (2011/05/01) {&#064;SYS.XXXX} は、å»?­¢
085             * @og.rev 5.5.7.2 (2012/10/09) rightNow をCalendarオブジェクãƒ?ではなくã?String時刻としますã?
086             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正しますã?
087             *
088             * @param       orig    変換するæ–?­—å?(オリジナル)
089             */
090            public SystemParameter( final String orig ) {
091    //              rightNow = Calendar.getInstance();
092    
093                    if( orig == null || orig.length() == 0 || orig.indexOf( "{@" ) < 0 ) {
094                            clms     = null;
095                            formats  = null;
096                            original = orig;                // 5.3.2.0 (2011/02/01)
097                    }
098                    else {
099                            StringBuilder buf = new StringBuilder(orig.length());           // 5.3.2.0 (2011/02/01)
100    
101                            ArrayList<String> fmtList = new ArrayList<String>();
102                            ArrayList<String> clmList = new ArrayList<String>();
103    
104                            // 5.1.8.0 (2010/07/01) パã?ス方法見直ã�?
105                            int start = 0;
106                            int index = orig.indexOf( "{@" );
107                            String val ;
108                            while( index >= 0 ) {
109    //                              buf.append(  orig.substring( start, index ) );          // 5.3.2.0 (2011/02/01)
110    //                              fmtList.add( orig.substring( start, index ) );
111                                    val = orig.substring( start, index );                                   // 5.3.4.0 (2011/04/01)
112                                    buf.append(  val );
113                                    fmtList.add( val );
114                                    int end = orig.indexOf( '}',index );
115                                    if( end < 0 ) {
116                                            String errMsg = "{@ と } との対応関係がずれてã�?�¾すã?" + CR
117                                                                    + "str=[" + orig + "] : index=" + index ;
118                                            throw new RuntimeException( errMsg );
119                                    }
120                                    String param = orig.substring( index+2,end );
121    //                              if( param.startsWith( "SYS." ) || param.startsWith( "DATE." ) ) {
122                                    if( param.startsWith( "DATE." ) ) {             // 5.3.5.0 (2011/05/01) {&#064;SYS.XXXX} は、å»?­¢
123    //                                      val = getDateFormat( param );
124                                            val = getDateFormat( param.substring( 5 ) );    // 5.5.7.2 (2012/10/09) HybsDateUtil を利用時に "DATE." は不è¦?
125                                            clmList.add( null );            // パã?ス下å?合ã?、clmList は、使用しなã�??
126                                            buf.append( val );
127                                    }
128                                    else {
129                                            clmList.add( param );
130                                            buf.append( "{@" ).append( param ).append( "}" );               // å…??ままのæ–?­—å?を生æˆ?
131                                    }
132                                    start = end+1;
133                                    index = orig.indexOf( "{@",start );
134                            }
135    //                      buf.append(  orig.substring( start, orig.length() ) );          // 5.3.2.0 (2011/02/01)
136    //                      fmtList.add( orig.substring( start, orig.length() ) );
137                            val = orig.substring( start, orig.length() );                           // 5.3.4.0 (2011/04/01)
138                            buf.append(  val );
139                            fmtList.add( val );
140    
141                            original = buf.toString();              // 5.3.2.0 (2011/02/01)
142                            if( original.indexOf( "{@" ) < 0 ) {
143                                    clms     = null;
144                                    formats  = null;
145                            }
146                            else {
147                                    clms    = clmList.toArray( new String[clmList.size()] );
148                                    formats = fmtList.toArray( new String[fmtList.size()] );
149                            }
150                    }
151            }
152    
153            /**
154             * 日付関係ã?æƒ??を簡易的に取り出すå?ç�?‚’行いますã?
155             *
156             * これは、{&#064;DATE.XXXX AA BB} 引数処ç�?‚’おこなã�?�Ÿめã?、サポã?トメソãƒ?ƒ‰ですã?
157             * 引数はã€?DATE.XXXX AA BB" とã�?�†状態で受け取りますã?
158             * "XXXX" は、日付å?ç�?‚’行うキーæ–?­—å?で予ç´?ªžになってã�?�¾すã?
159             * ・YMDã€???š8文字ã?日付データ(200X年XXæœ?X日)を扱ã�?�¾すã?
160             * ・Y2MDã€??š6文字ã?日付データ(0X年XXæœ?X日)を扱ã�?�¾すã?
161             * ・YMã€?? ?š6文字ã?日付データ(200X年XXæœ?を扱ã�?�¾すã?
162             * ・HMSã€???š6文字ã?時刻ãƒ??タ(XX時XXåˆ?Xç§?を扱ã�?�¾すã?
163             * ・YMDHMS ?š14文字ã?日付データ(200X年XXæœ?X日XX時XXåˆ?Xç§?を扱ã�?�¾すã?
164             * ・EEEã€???š曜日をデフォルトロケールで表示しますã?
165             *
166             * F付きは、フォーマットされた日付を返しますã?
167             * ・YMDFã€??š10文字ã?日付表現(yyyy/MM/dd)を扱ã�?�¾すã?
168             * ・Y2MDFã€?¼š8文字ã?日付表現(yy/MM/dd)を扱ã�?�¾すã?
169             * ・YMFã€???š7文字ã?日付表現(yyyy/MM)を扱ã�?�¾すã?
170             * ・HMSFã€??š8文字ã?時刻表現(HH:mm:ss)を扱ã�?�¾すã?
171             * ・YMDHMSF?š19文字ã?日付表現(yyyy/MM/dd HH:mm:ss)を扱ã�?�¾すã?
172             * ・MDFã€???š5文字ã?月日表現(MM/dd)を扱ã�?�¾すã?
173             * ・MDEFã€??š5文字+曜日の月日表現(MM/dd(EEE))を扱ã�?�¾すã?
174             * ・MD2Fã€??š和暦の月日表現(MMæœ?d日)を扱ã�?�¾すã?(5.5.5.2 追åŠ?
175             * ・GYMDFã€?¼š和暦の年月日表現(GGGGyyyy年MMæœ?d日)を扱ã�?�¾すã?
176             * ・G2YMDF ?š和暦の日付表現(Gyyyy/MM/dd)を扱ã�?�¾すã?
177             * ・GYMFã€??š和暦の年月表現(GGGGyyyy年MMæœ?を扱ã�?�¾すã?
178             * ・GYFã€???š和暦の年表現(GGGGyyyy)を扱ã�?�¾すã?
179             *
180             * AA 引数は、基準となる日付を、YYYYMMDD形式でæŒ?®šしますã?無æŒ?®šã?場合ã?ã€?
181             * 処ç�?™‚刻を基準にした、同ä¸?‚¿グå†?�§の同ä¸?—¥ä»?年月日時å?ç§?を使用して値を取得しますã?
182             * æŒ?®šできる日付ã?、å¿?�š、YYYYMMDD形式としã?時å?秒ã? ゼロにリセãƒ?ƒˆされた状態になりますã?
183             * AA には、数字で始まã‚?20050701など)実日付と@で始まるパラメータが使用できますã?
184             * こã?パラメータの値は、YYYYMMDD形式ã?数字か、null(またã?ゼロストリング)ですã?nullの
185             * 場合ã?、なにも指定されてã�?�ªã�?�¨判断して、å?ç�?™‚刻を使用しますã?
186             * 第?’引数はã€?数字か、@)以外ã?場合ã?、省略されたと判断されますã?
187             *
188             * BB 引数は、日付につã�?�¦のåŠ?¸›算å?ç�?‚’行いますã?
189             * 省略すると、なにも加減算å?ç�?‚’行いませんã€?
190             * ・SD ?š当月のæœ??の日付にセãƒ?ƒˆしますã?(当月?‘日)
191             * ・ED ?š当月のæœ?¾Œã?日付にセãƒ?ƒˆしますã?(当月月末)
192             * ・SW ?š日付å?ç�??週初め(月曜日)にセãƒ?ƒˆしますã?日付ã?当日より前に移動しますã?
193             * ・EW ?š日付å?ç�??週末(日曜日)にセãƒ?ƒˆしますã?日付ã?当日より後ろに移動しますã?
194             * ・H1 ??HXXX ?š時を指定ã?åˆ?� けé?めますã?H1なら1時間後ã?H24 なら24時間å¾?5.5.5.6 (2012/08/31) 追åŠ?
195             * ・D1 ??DXXX ?š日を指定ã?åˆ?� けé?めますã?D1なら翌日、D200 なã‚?00日å¾?
196             * ・M1 ??MXXX ?š月を指定ã?åˆ?� けé?めますã?M1なら翌月、M6 なら半年å¾?
197             * ・BSD ?šå?月ã?æœ??の日付にセãƒ?ƒˆしますã?(先月?‘日)(5.5.5.2 追åŠ?
198             * ・BED ?šå?月ã?æœ?¾Œã?日付にセãƒ?ƒˆしますã?(先月月末)(5.5.5.2 追åŠ?
199             * ・ASD ?š翌月のæœ??の日付にセãƒ?ƒˆしますã?(翌月?‘日)(5.5.5.2 追åŠ?
200             * ・AED ?š翌月のæœ?¾Œã?日付にセãƒ?ƒˆしますã?(翌月月末)(5.5.5.2 追åŠ?
201             *
202             * @og.rev 5.3.4.0 (2011/04/01) 新規追åŠ?
203             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正しますã?
204             * @og.rev 5.5.8.2 (2012/11/09) prmA の判定に、null と ゼロæ–?­—å?を判定するã?
205             *
206             * @param   value パラメータ(引数はã€?DATE.XXXX AA BB" などとã�?�†状æ…?
207             *
208             * @return   メãƒ?‚»ージæƒ??
209             */
210            private String getDateFormat( final String value ) {
211    //              Calendar now = (Calendar)rightNow.clone();
212    
213                    String[] vals = StringUtil.csv2Array( value,' ' );
214    
215                    String key = vals[0].trim() ;
216    
217                    String prmA = null;                             // 5.5.7.2 (2012/10/09) 引数として渡すã?で上位で初期化しておくã€?
218                    String prmB = null;
219                    if( vals.length == 3 ) { prmB = vals[2].trim(); }
220    
221                    if( vals.length > 1 ) {
222    //                      String prmA = vals[1].trim();
223                            prmA = vals[1].trim();
224                            if( prmA.startsWith( "@" ) ) {
225                                    prmA = getDateFormat( prmA.substring(1) );
226                            }
227    
228                            // prmA の@解析後ã??˜ケタ以下ã?場合ã?、コマンドとみなしã?prmB にセãƒ?ƒˆしã?自身は、null をセãƒ?ƒˆするã€?
229                            if( prmA != null && prmA.length() < 8 ) {
230                                    prmB = prmA;
231                                    prmA = null;
232                            }
233    //                      if( prmA != null && prmA.length() > 0 ) {
234    //                              if( prmA.length() == 8 && prmA.charAt(0) >= '0' && prmA.charAt(0) <= '9' ) {
235    //                                      int yy  = Integer.parseInt( prmA.substring( 0,4 ) );
236    //                                      int mm  = Integer.parseInt( prmA.substring( 4,6 ) ) - 1;
237    //                                      int dd  = Integer.parseInt( prmA.substring( 6,8 ) );
238    //                                      now.clear();
239    //                                      now.set( yy,mm,dd );
240    //                              }
241    //                              else {
242    //                                      prmB = prmA;
243    //                              }
244    //                      }
245                    }
246    
247    //              if( prmA == null ) { prmA = RIGHT_NOW; }                                                // 5.5.7.2 (2012/10/09) 初期値として、設定するã?
248                    if( prmA == null || prmA.isEmpty() ) { prmA = RIGHT_NOW; }              // 5.5.8.2 (2012/11/09) null と ゼロæ–?­—å?を判定するã?
249                    return HybsDateUtil.getDateFormat( key,prmA,prmB );                             // 5.5.7.2 (2012/10/09) HybsDateUtil を利用する
250    
251    //              if( prmB != null ) {
252    //                      if( "SD".equals( prmB ) ) { now.set( Calendar.DATE,1 ); }
253    //                      else if( "ED".equals( prmB ) ) { now.set( Calendar.DATE,now.getActualMaximum( Calendar.DATE ) ); }
254    //                      else if( "SM".equals( prmB ) ) { now.set( Calendar.MONTH,Calendar.JANUARY  ); }
255    //                      else if( "EM".equals( prmB ) ) { now.set( Calendar.MONTH,Calendar.DECEMBER  ); }
256    //                      else if( "SW".equals( prmB ) ) {
257    //                              // 日付型æ–?­—å?入力データの開始日を月曜日にセãƒ?ƒˆしますã?
258    //                              // SUNDAY=1 , MONDAY=2 になりますã?月曜日との差ã�?�‘、前に戻しますã?
259    //                              // æŒ?®š日が日曜日の場合ã?、月曜日まで戻しますã?
260    //                              int shu = now.get( Calendar.DAY_OF_WEEK ) - Calendar.MONDAY ;
261    // 
262    //                              if(      shu > 0 ) { now.add( Calendar.DATE, -shu ); }
263    //                              else if( shu < 0 ) { now.add( Calendar.DATE, -6 );   }       // 日曜日の処ç�?
264    // 
265    //                      }
266    //                      else if( "EW".equals( prmB ) ) {
267    //                              // 日付型æ–?­—å?入力データの終äº?—¥を日曜日にセãƒ?ƒˆしますã?
268    //                              // SUNDAY=1 , MONDAY=2 になりますã?日曜日になるよã�?�«、å?に進めますã?
269    //                              int shu = now.get( Calendar.DAY_OF_WEEK ) ;
270    // 
271    //                              if( shu != Calendar.SUNDAY ) { now.add( Calendar.DATE, 8-shu ); }
272    //                      }
273    //                      else if( prmB.startsWith( "D" ) && prmB.length() > 1 ) {
274    //                              int day = Integer.parseInt( prmB.substring( 1 ) );
275    //                              now.add( Calendar.DATE, day );
276    //                      }
277    //                      else if( prmB.startsWith( "M" ) && prmB.length() > 1 ) {
278    //                              int month = Integer.parseInt( prmB.substring( 1 ) );
279    //                              now.add( Calendar.MONTH , month );
280    //                      }
281    //                      else {
282    //                              String errMsg = "日付変数パラメータに、不正な値が指定されました。以下ã?中からæŒ?®šしなおしてくださいã€?
283    //                                                      + "æŒ?®š可能?š[SD,ED,SM,EM,SW,EW,D1?žDXXX,M1?žMXXX]"
284    //                                                      + " value=[" + prmB + "]" ;
285    //                              throw new RuntimeException( errMsg );
286    //                      }
287    //              }
288    // 
289    //              String format = DATE_FORMAT.get( key );
290    //              if( format == null ) {
291    //                      String errMsg = "日付変数キーに、不正な値が指定されました。以下ã?中からæŒ?®šしなおしてくださいã€?
292    //                                              + "æŒ?®š可能?š[" + DATE_FORMAT.keySet().toString() + "] , "
293    //                                              + " key=[" + value + "]" ;
294    //                      throw new RuntimeException( errMsg );
295    //              }
296    // 
297    //              DateFormat formatter = new SimpleDateFormat( format,Locale.JAPAN );
298    // 
299    //              return formatter.format( now.getTime() );
300            }
301    
302            /**
303             *  {&#064;XXXX} の特殊文字を含ã‚?–‡字å?をã?置き換えますã?
304             * 対象外ã?æ–?­—å?は、そのまま、残されますã?
305             *
306             * @og.rev 5.3.4.0 (2011/04/01) 判定方æ³?修正
307             *
308             * @param       entry   置換文字å?のキーと値のペアを管ç�?�—てã�?‚‹Entryオブジェクトã?配å?
309             *
310             * @return      置換後ã?æ–?­—å?
311             */
312            public String replace( final HybsEntry[] entry ) {
313    //              if( orginal == null ) { return null; }
314    //              int index = orginal.indexOf( "{@" );
315    //              if( index < 0 ) { return orginal; }
316    //              if( formats == null || clms == null ) { return original; }
317                    if( formats == null ) { return original; }              // 5.3.4.0 (2011/04/01) 判定方æ³?修正
318                    if( entry == null || entry.length == 0 ) { return original; }
319    
320                    // HybsEntry[] ãƒ??タをã?Mapにマッピングしますã?
321                    Map<String, String> sysMap = new HashMap<String, String>();
322    //              if( entry != null ) {
323                            int size = entry.length;
324                            for( int i=0; i<size; i++ ) {
325                                    sysMap.put( entry[i].getKey(),entry[i].getValue() );
326                            }
327    //              }
328                    return replace( sysMap );
329            }
330    
331            /**
332             *  {&#064;XXXX} の特殊文字を含ã‚?–‡字å?をã?置き換えますã?
333             * 対象外ã?æ–?­—å?は、そのまま、残されますã?
334             *
335             * @param  map  置換文字å?のキーと値のペアを管ç�?�—てã�?‚‹Mapオブジェクãƒ?
336             *
337             * @return      置換後ã?æ–?­—å?
338             */
339            public String replace( final Map<String,String> map ) {
340    //              if( formats == null || clms == null ) { return original; }
341                    if( formats == null ) { return original; }              // 5.3.4.0 (2011/04/01) 判定方æ³?修正
342    //              if( map == null || map.size() == 0 ) { return original; }
343                    if( map == null || map.isEmpty() ) { return original; }
344    
345                    StringBuilder sb = new StringBuilder();
346                    for( int i=0; i<formats.length; i++ ) {
347                            sb.append( formats[i] );
348                            if( i < clms.length && clms[i] != null ) {           // 5.3.4.0 (2011/04/01) nullチェãƒ?‚¯追åŠ?
349                                    sb.append(  StringUtil.nval( map.get( clms[i] ), "" ) );
350                            }
351                    }
352    
353                    return sb.toString();
354            }
355    
356            /**
357             * フォーマットをパã?スした結果から、カラãƒ?¸?¦§をé?列形式で返しますã?
358             *
359             * @og.rev 5.1.7.0 (2010/06/01) 新規作æ?
360             *
361             * @return カラãƒ??åˆ?
362             */
363            public String[] getColumns() {
364                    if( clms == null ) { return new String[0]; }
365                    return clms.clone();
366            }
367    
368            /**
369             * フォーマットをパã?スした結果から、フォーマットä¸?¦§をé?列形式で返しますã?
370             *
371             * @og.rev 5.1.7.0 (2010/06/01) 新規作æ?
372             *
373             * @return フォーマットé?åˆ?
374             */
375            public String[] getFormats() {
376                    if( formats == null ) { return new String[0]; }
377                    return formats.clone();
378            }
379    }