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 018import java.util.ArrayList; 019import java.util.Map; 020import java.util.HashMap; 021 022/** 023 * SystemParameter は、{@XXXX} 文字列を処理するクラスです。 024 * このクラスでは、{@XXXX} 文字列を別の文字列と置き換えることや、 025 * 予め予約されている予約語 {@DATE.XXXX} 文字列を置き換えます。 026 * 通常の {@XXXX} 文字列の置き換えは、キーと値のペアを、HybsEntry オブジェクトに 027 * セットして、その配列を受け取って処理します。 028 * 029 * 以下の値はあらかじめ、動的に作成されます。 030 * ・DATE.YMD 8byte の今日のシステム日付(yyyyMMdd) 031 * ・DATE.YMDH 14byte の今日のシステム日時(yyyyMMddHHmmss) 032 * ・DATE.HMS 6byte の今日のシステム時間(HHmmss) 033 * 034 * @og.group ユーティリティ 035 * 036 * @version 4.0 037 * @author Kazuhiko Hasegawa 038 * @since JDK5.0, 039 */ 040public final class SystemParameter { 041 042 /** 改行コード */ 043 public static final String CR = System.getProperty("line.separator"); // 5.1.9.0 (2010/08/01) 追加 044 045 private final String original ; 046 047 private final String[] clms; 048 private final String[] formats; 049 050 /** 051 * {@XXXX} の特殊文字を含む文字列を、置き換えます。 052 * 対象外の文字列は、そのまま、残されます。 053 * 054 * @og.rev 5.1.8.0 (2010/07/01) パース方法見直し(StringTokenizerでは、{@XXXX}が連続してある場合に対応できない) 055 * @og.rev 5.3.2.0 (2011/02/01) original データを、パース結果を利用するように修正する。 056 * @og.rev 5.3.4.0 (2011/04/01) {@DATE.XXXX} を処理できるように機能追加 057 * @og.rev 5.3.5.0 (2011/05/01) {@SYS.XXXX} は、廃止 058 * @og.rev 5.5.7.2 (2012/10/09) rightNow をCalendarオブジェクト ではなく、String時刻とします。 059 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 060 * 061 * @param orig 変換する文字列(オリジナル) 062 */ 063 public SystemParameter( final String orig ) { 064 if( orig == null || orig.length() == 0 || orig.indexOf( "{@" ) < 0 ) { 065 clms = null; 066 formats = null; 067 original = orig; // 5.3.2.0 (2011/02/01) 068 } 069 else { 070 StringBuilder buf = new StringBuilder(orig.length()); // 5.3.2.0 (2011/02/01) 071 072 ArrayList<String> fmtList = new ArrayList<String>(); 073 ArrayList<String> clmList = new ArrayList<String>(); 074 075 // 5.1.8.0 (2010/07/01) パース方法見直し 076 int start = 0; 077 int index = orig.indexOf( "{@" ); 078 String val ; 079 while( index >= 0 ) { 080 val = orig.substring( start, index ); // 5.3.4.0 (2011/04/01) 081 buf.append( val ); 082 fmtList.add( val ); 083 int end = orig.indexOf( '}',index ); 084 if( end < 0 ) { 085 String errMsg = "{@ と } との対応関係がずれています。" + CR 086 + "str=[" + orig + "] : index=" + index ; 087 throw new RuntimeException( errMsg ); 088 } 089 String param = orig.substring( index+2,end ); 090 if( param.startsWith( "DATE." ) ) { // 5.3.5.0 (2011/05/01) {@SYS.XXXX} は、廃止 091 val = getDateFormat( param.substring( 5 ) ); // 5.5.7.2 (2012/10/09) HybsDateUtil を利用時に "DATE." は不要 092 clmList.add( null ); // パースした場合は、clmList は、使用しない。 093 buf.append( val ); 094 } 095 else { 096 clmList.add( param ); 097 buf.append( "{@" ).append( param ).append( "}" ); // 元のままの文字列を生成 098 } 099 start = end+1; 100 index = orig.indexOf( "{@",start ); 101 } 102 val = orig.substring( start, orig.length() ); // 5.3.4.0 (2011/04/01) 103 buf.append( val ); 104 fmtList.add( val ); 105 106 original = buf.toString(); // 5.3.2.0 (2011/02/01) 107 if( original.indexOf( "{@" ) < 0 ) { 108 clms = null; 109 formats = null; 110 } 111 else { 112 clms = clmList.toArray( new String[clmList.size()] ); 113 formats = fmtList.toArray( new String[fmtList.size()] ); 114 } 115 } 116 } 117 118 /** 119 * 日付関係の情報を簡易的に取り出す処理を行います。 120 * 121 * 引数は、"XXXX AA BB CC" という状態で受け取ります。 122 * 123 * 処理の詳細は、{@link org.opengion.fukurou.util.HybsDateUtil#getDateFormat( String,String,String,int ) } 124 * または、{@link org.opengion.hayabusa.taglib.CommonTagSupport#getDateFormat( String ) } を 125 * 参照してください。 126 * 127 * @og.rev 5.3.4.0 (2011/04/01) 新規追加 128 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 129 * @og.rev 5.5.8.2 (2012/11/09) prmA の判定に、null と ゼロ文字列を判定する。 130 * @og.rev 5.7.4.1 (2014/03/14) AA 引数の@解析後のコマンド判定方法を、8ケタ以下から先頭が数字以外に変更します。 131 * @og.rev 5.7.4.1 (2014/03/14) taglib.CommonTagSupport#getDateFormat( String ) と処理を合わせます。 132 * @og.rev 5.7.4.2 (2014/03/20) リクエストパラメータ(@で始まる引数)は使えません。 133 * 134 * @param value パラメータ(引数は、"DATE.XXXX AA BB" などという状態) 135 * 136 * @return メッセージ情報 137 * @see org.opengion.fukurou.util.HybsDateUtil#getDateFormat( String,String,String,int ) 138 * @see org.opengion.hayabusa.taglib.CommonTagSupport#getDateFormat( String ) 139 */ 140 private String getDateFormat( final String value ) { 141 // 5.7.4.1 (2014/03/14) taglib.CommonTagSupport#getDateFormat( String ) と処理を合わせます。 142 String[] vals = StringUtil.csv2Array( value,' ' ); 143 144 String key = vals[0] ; 145 146 String prmA = (vals.length >= 2) ? vals[1] : null ; 147 String prmB = (vals.length >= 3) ? vals[2] : null ; 148 String prmC = (vals.length >= 4) ? vals[vals.length-1] : null ; // 互換性。最後の値が、CC引数 149 150 // 5.7.4.2 (2014/03/20) 現時点では、SystemParameter 処理にはリクエスト変数は使えないので、@変数も使えない。 151 if( prmA != null && prmA.startsWith( "@" ) ) { 152 String errMsg = "AA引数に、リクエストパラメータ(@で始まる引数)は使えません。value=[" + value + "]" ; 153 throw new RuntimeException( errMsg ); 154 } 155 156 if( prmB != null && prmB.startsWith( "@" ) ) { 157 String errMsg = "BB引数に、リクエストパラメータ(@で始まる引数)は使えません。value=[" + value + "]" ; 158 throw new RuntimeException( errMsg ); 159 } 160 161 if( prmC != null && prmC.startsWith( "@" ) ) { 162 String errMsg = "CC引数に、リクエストパラメータ(@で始まる引数)は使えません。value=[" + value + "]" ; 163 throw new RuntimeException( errMsg ); 164 } 165 166 // 5.7.4.1 (2014/03/14) AA 引数の@解析後のコマンド判定方法を、8ケタ以下から先頭が数字以外に変更します。 167 if( prmA != null && prmA.length() > 0 ) { 168 char chA = prmA.charAt(0); 169 if( chA < '0' || chA > '9' ) { // 先頭が、数字以外の場合は、コマンドなので、一つずつずらす。 170 prmC = prmB; 171 prmB = prmA; 172 prmA = null; 173 } 174 } 175 176 // 5.7.4.1 (2014/03/14) CC 引数を、"H" , "D" , "M" 以外でも使用できるように拡張します。 177 int intC = 0; 178 if( prmC != null && prmC.length() > 0 ) { 179 try { 180 intC = Integer.parseInt( prmC ); 181 } 182 catch( NumberFormatException ex ) { 183 String errMsg = "CC引数が数字ではありません。value=[" + value + "]" 184 + ex.getMessage() ; 185 System.err.println( errMsg ); 186 } 187 } 188 189 // prmA が null か、isEmpty() の場合は、現在時刻が使用される。 190 return HybsDateUtil.getDateFormat( key,prmA,prmB,intC ); // 5.7.4.1 (2014/03/14) CC 引数を拡張します。 191 } 192 193 /** 194 * {@XXXX} の特殊文字を含む文字列を、置き換えます。 195 * 対象外の文字列は、そのまま、残されます。 196 * 197 * @og.rev 5.3.4.0 (2011/04/01) 判定方法 修正 198 * 199 * @param entry 置換文字列のキーと値のペアを管理しているEntryオブジェクトの配列 200 * 201 * @return 置換後の文字列 202 */ 203 public String replace( final HybsEntry[] entry ) { 204 if( formats == null ) { return original; } // 5.3.4.0 (2011/04/01) 判定方法 修正 205 if( entry == null || entry.length == 0 ) { return original; } 206 207 // HybsEntry[] データを、Mapにマッピングします。 208 Map<String, String> sysMap = new HashMap<String, String>(); 209 int size = entry.length; 210 for( int i=0; i<size; i++ ) { 211 sysMap.put( entry[i].getKey(),entry[i].getValue() ); 212 } 213 214 return replace( sysMap ); 215 } 216 217 /** 218 * {@XXXX} の特殊文字を含む文字列を、置き換えます。 219 * 対象外の文字列は、そのまま、残されます。 220 * 221 * @param map 置換文字列のキーと値のペアを管理しているMapオブジェクト 222 * 223 * @return 置換後の文字列 224 */ 225 public String replace( final Map<String,String> map ) { 226 if( formats == null ) { return original; } // 5.3.4.0 (2011/04/01) 判定方法 修正 227 if( map == null || map.isEmpty() ) { return original; } 228 229 StringBuilder sb = new StringBuilder(); 230 for( int i=0; i<formats.length; i++ ) { 231 sb.append( formats[i] ); 232 if( i < clms.length && clms[i] != null ) { // 5.3.4.0 (2011/04/01) nullチェック追加 233 sb.append( StringUtil.nval( map.get( clms[i] ), "" ) ); 234 } 235 } 236 237 return sb.toString(); 238 } 239 240 /** 241 * フォーマットをパースした結果から、カラム一覧を配列形式で返します。 242 * 243 * @og.rev 5.1.7.0 (2010/06/01) 新規作成 244 * 245 * @return カラム配列 246 */ 247 public String[] getColumns() { 248 if( clms == null ) { return new String[0]; } 249 return clms.clone(); 250 } 251 252 /** 253 * フォーマットをパースした結果から、フォーマット一覧を配列形式で返します。 254 * 255 * @og.rev 5.1.7.0 (2010/06/01) 新規作成 256 * 257 * @return フォーマット配列 258 */ 259 public String[] getFormats() { 260 if( formats == null ) { return new String[0]; } 261 return formats.clone(); 262 } 263}