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 018// import java.text.DateFormat; 019// import java.text.SimpleDateFormat; 020// import java.util.Locale; 021// import java.util.Calendar; 022import java.util.ArrayList; 023import java.util.Map; 024import java.util.HashMap; 025 026/** 027 * SystemParameter は、{@XXXX} 文字列を処理するクラスです。 028 * このクラスでは、{@XXXX} 文字列を別の文字列と置き換えることや、 029 * 予め予約されている予約語 {@DATE.XXXX} 文字列を置き換えます。 030 * 通常の {@XXXX} 文字列の置き換えは、キーと値のペアを、HybsEntry オブジェクトに 031 * セットして、その配列を受け取って処理します。 032 * 033 * 以下の値はあらかじめ、動的に作成されます。 034 * ・DATE.YMD 8byte の今日のシステム日付(yyyyMMdd) 035 * ・DATE.YMDH 14byte の今日のシステム日時(yyyyMMddHHmmss) 036 * ・DATE.HMS 6byte の今日のシステム時間(HHmmss) 037 * 038 * @og.group ユーティリティ 039 * 040 * @version 4.0 041 * @author Kazuhiko Hasegawa 042 * @since JDK5.0, 043 */ 044public 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" ); // 5.7.4.1 (2014/03/14) 廃止 073 074 private final String[] clms; 075 private final String[] formats; 076 077 /** 078 * {@XXXX} の特殊文字を含む文字列を、置き換えます。 079 * 対象外の文字列は、そのまま、残されます。 080 * 081 * @og.rev 5.1.8.0 (2010/07/01) パース方法見直し(StringTokenizerでは、{@XXXX}が連続してある場合に対応できない) 082 * @og.rev 5.3.2.0 (2011/02/01) original データを、パース結果を利用するように修正する。 083 * @og.rev 5.3.4.0 (2011/04/01) {@DATE.XXXX} を処理できるように機能追加 084 * @og.rev 5.3.5.0 (2011/05/01) {@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) {@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 * 引数は、"XXXX AA BB CC" という状態で受け取ります。 157 * 158 * 処理の詳細は、{@link org.opengion.fukurou.util.HybsDateUtil#getDateFormat( String,String,String,int ) } 159 * または、{@link org.opengion.hayabusa.taglib.CommonTagSupport#getDateFormat( String ) } を 160 * 参照してください。 161 * 162 * @og.rev 5.3.4.0 (2011/04/01) 新規追加 163 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 164 * @og.rev 5.5.8.2 (2012/11/09) prmA の判定に、null と ゼロ文字列を判定する。 165 * @og.rev 5.7.4.1 (2014/03/14) AA 引数の@解析後のコマンド判定方法を、8ケタ以下から先頭が数字以外に変更します。 166 * @og.rev 5.7.4.1 (2014/03/14) taglib.CommonTagSupport#getDateFormat( String ) と処理を合わせます。 167 * @og.rev 5.7.4.2 (2014/03/20) リクエストパラメータ(@で始まる引数)は使えません。 168 * 169 * @param value パラメータ(引数は、"DATE.XXXX AA BB" などという状態) 170 * 171 * @return メッセージ情報 172 * @see org.opengion.fukurou.util.HybsDateUtil#getDateFormat( String,String,String,int ) 173 * @see org.opengion.hayabusa.taglib.CommonTagSupport#getDateFormat( String ) 174 */ 175 private String getDateFormat( final String value ) { 176 // 5.7.4.1 (2014/03/14) taglib.CommonTagSupport#getDateFormat( String ) と処理を合わせます。 177 String[] vals = StringUtil.csv2Array( value,' ' ); 178 179 String key = vals[0] ; 180 181 String prmA = (vals.length >= 2) ? vals[1] : null ; 182 String prmB = (vals.length >= 3) ? vals[2] : null ; 183 String prmC = (vals.length >= 4) ? vals[vals.length-1] : null ; // 互換性。最後の値が、CC引数 184 185 // 5.7.4.2 (2014/03/20) 現時点では、SystemParameter 処理にはリクエスト変数は使えないので、@変数も使えない。 186 if( prmA != null && prmA.startsWith( "@" ) ) { 187// prmA = getDateFormat( prmA.substring(1) ); // getRequestValue ではなく、自身を再呼出し 188 String errMsg = "AA引数に、リクエストパラメータ(@で始まる引数)は使えません。value=[" + value + "]" ; 189 throw new RuntimeException( errMsg ); 190 } 191 192 if( prmB != null && prmB.startsWith( "@" ) ) { 193// prmB = getDateFormat( prmB.substring(1) ); // getRequestValue ではなく、自身を再呼出し 194 String errMsg = "BB引数に、リクエストパラメータ(@で始まる引数)は使えません。value=[" + value + "]" ; 195 throw new RuntimeException( errMsg ); 196 } 197 198 if( prmC != null && prmC.startsWith( "@" ) ) { 199// prmC = getDateFormat( prmC.substring(1) ); // getRequestValue ではなく、自身を再呼出し 200 String errMsg = "CC引数に、リクエストパラメータ(@で始まる引数)は使えません。value=[" + value + "]" ; 201 throw new RuntimeException( errMsg ); 202 } 203 204 // 5.7.4.1 (2014/03/14) AA 引数の@解析後のコマンド判定方法を、8ケタ以下から先頭が数字以外に変更します。 205 if( prmA != null && prmA.length() > 0 ) { 206 char chA = prmA.charAt(0); 207 if( chA < '0' || chA > '9' ) { // 先頭が、数字以外の場合は、コマンドなので、一つずつずらす。 208 prmC = prmB; 209 prmB = prmA; 210 prmA = null; 211 } 212 } 213 214 // 5.7.4.1 (2014/03/14) CC 引数を、"H" , "D" , "M" 以外でも使用できるように拡張します。 215 int intC = 0; 216 if( prmC != null && prmC.length() > 0 ) { 217 try { 218 intC = Integer.parseInt( prmC ); 219 } 220 catch( NumberFormatException ex ) { 221 String errMsg = "CC引数が数字ではありません。value=[" + value + "]" 222 + ex.getMessage() ; 223 System.err.println( errMsg ); 224 } 225 } 226 227 // prmA が null か、isEmpty() の場合は、現在時刻が使用される。 228 return HybsDateUtil.getDateFormat( key,prmA,prmB,intC ); // 5.7.4.1 (2014/03/14) CC 引数を拡張します。 229 230// 5.7.4.1 (2014/03/14) taglib.CommonTagSupport#getDateFormat( String ) と処理を合わせます。 231// String[] vals = StringUtil.csv2Array( value,' ' ); 232// 233// String key = vals[0].trim() ; 234// 235// String prmA = null; // 5.5.7.2 (2012/10/09) 引数として渡すので上位で初期化しておく。 236// String prmB = null; 237// if( vals.length == 3 ) { prmB = vals[2].trim(); } 238// 239// if( vals.length > 1 ) { 240// prmA = vals[1].trim(); 241// if( prmA.startsWith( "@" ) ) { 242// prmA = getDateFormat( prmA.substring(1) ); 243// } 244// 245// // prmA の@解析後、8ケタ以下の場合は、コマンドとみなし、prmB にセットし、自身は、null をセットする。 246// if( prmA != null && prmA.length() < 8 ) { 247// prmB = prmA; 248// prmA = null; 249// } 250// } 251// 252// if( prmA == null || prmA.isEmpty() ) { prmA = RIGHT_NOW; } // 5.5.8.2 (2012/11/09) null と ゼロ文字列を判定する。 253// return HybsDateUtil.getDateFormat( key,prmA,prmB ); // 5.5.7.2 (2012/10/09) HybsDateUtil を利用する 254 } 255 256 /** 257 * {@XXXX} の特殊文字を含む文字列を、置き換えます。 258 * 対象外の文字列は、そのまま、残されます。 259 * 260 * @og.rev 5.3.4.0 (2011/04/01) 判定方法 修正 261 * 262 * @param entry 置換文字列のキーと値のペアを管理しているEntryオブジェクトの配列 263 * 264 * @return 置換後の文字列 265 */ 266 public String replace( final HybsEntry[] entry ) { 267// if( orginal == null ) { return null; } 268// int index = orginal.indexOf( "{@" ); 269// if( index < 0 ) { return orginal; } 270// if( formats == null || clms == null ) { return original; } 271 if( formats == null ) { return original; } // 5.3.4.0 (2011/04/01) 判定方法 修正 272 if( entry == null || entry.length == 0 ) { return original; } 273 274 // HybsEntry[] データを、Mapにマッピングします。 275 Map<String, String> sysMap = new HashMap<String, String>(); 276// if( entry != null ) { 277 int size = entry.length; 278 for( int i=0; i<size; i++ ) { 279 sysMap.put( entry[i].getKey(),entry[i].getValue() ); 280 } 281// } 282 return replace( sysMap ); 283 } 284 285 /** 286 * {@XXXX} の特殊文字を含む文字列を、置き換えます。 287 * 対象外の文字列は、そのまま、残されます。 288 * 289 * @param map 置換文字列のキーと値のペアを管理しているMapオブジェクト 290 * 291 * @return 置換後の文字列 292 */ 293 public String replace( final Map<String,String> map ) { 294// if( formats == null || clms == null ) { return original; } 295 if( formats == null ) { return original; } // 5.3.4.0 (2011/04/01) 判定方法 修正 296// if( map == null || map.size() == 0 ) { return original; } 297 if( map == null || map.isEmpty() ) { return original; } 298 299 StringBuilder sb = new StringBuilder(); 300 for( int i=0; i<formats.length; i++ ) { 301 sb.append( formats[i] ); 302 if( i < clms.length && clms[i] != null ) { // 5.3.4.0 (2011/04/01) nullチェック追加 303 sb.append( StringUtil.nval( map.get( clms[i] ), "" ) ); 304 } 305 } 306 307 return sb.toString(); 308 } 309 310 /** 311 * フォーマットをパースした結果から、カラム一覧を配列形式で返します。 312 * 313 * @og.rev 5.1.7.0 (2010/06/01) 新規作成 314 * 315 * @return カラム配列 316 */ 317 public String[] getColumns() { 318 if( clms == null ) { return new String[0]; } 319 return clms.clone(); 320 } 321 322 /** 323 * フォーマットをパースした結果から、フォーマット一覧を配列形式で返します。 324 * 325 * @og.rev 5.1.7.0 (2010/06/01) 新規作成 326 * 327 * @return フォーマット配列 328 */ 329 public String[] getFormats() { 330 if( formats == null ) { return new String[0]; } 331 return formats.clone(); 332 } 333}