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.hayabusa.db;
017    
018    import org.opengion.fukurou.model.NativeType;
019    import org.opengion.fukurou.util.ErrorMessage;
020    import org.opengion.fukurou.util.StringUtil;
021    
022    /**
023     * ä¸?ˆ¬çš?�ª半角文字å?を扱ã�?‚ºの、カラãƒ?±žæ?を定義しますã?
024     *
025     * 半角文字å?とは、ã? c < 0x20 || c > 0x7e 以外ã?でのみ
026     * 構æ?された文字å?のことですã?
027     *
028     * タイプチェãƒ?‚¯として、以下ã?条件を判定しますã?
029     * ・æ–?­—å?長は、Byte換算でのæ–?­—数との比è¼?
030     * ・半角文字å?チェãƒ?‚¯ã€?c < 0x20 || c > 0x7e 以外ã?エラー
031     * ・æ–?­—パラメータの 正規表現チェãƒ?‚¯
032     * ・クロスサイトスクリプティングチェãƒ?‚¯
033     *
034     * @og.group ãƒ??タ属æ?
035     *
036     * @version  4.0
037     * @author   Kazuhiko Hasegawa
038     * @since    JDK5.0,
039     */
040    public abstract class AbstractDBType implements DBType {
041    
042            private final String defValue ;         // ãƒ??タのãƒ?ƒ•ォルトå?
043    
044            /**
045             * ãƒ?ƒ•ォルトコンストラクター
046             *
047             * @og.rev 4.0.0.0 (2005/01/31) type å»?­¢
048             */
049            public AbstractDBType() {
050                    this( "" );             // ãƒ??タのãƒ?ƒ•ォルトå?
051            }
052    
053            /**
054             * コンストラクター
055             *
056             * å�?‚µブクラスのタイプå?とãƒ?ƒ•ォルトå?を設定して、オブジェクトを構築しますã?
057             *
058             * @og.rev 4.0.0.0 (2005/01/31) type å»?­¢
059             *
060             * @param  defValue ãƒ??タのãƒ?ƒ•ォルトå?
061             */
062            public AbstractDBType( final String defValue ) {
063                    this.defValue = defValue;
064            }
065    
066            /**
067             * NATIVEの型ã?識別コードを返しますã?
068             *
069             * @og.rev 3.5.4.7 (2004/02/06) 新規作æ?
070             * @og.rev 4.1.1.2 (2008/02/28) Enumåž?fukurou.model.NativeType)に変更
071             *
072             * @return  NATIVEの型ã?識別コーãƒ?DBType で規å®?
073             * @see org.opengion.fukurou.model.NativeType
074             */
075            public NativeType getNativeType() {
076    //              return NATIVE_STRING;
077                    return NativeType.STRING;
078            }
079    
080            /**
081             * 半角スペã?スで固定長(半角換算ã?数)に変換したæ–?­—å?を返しますã?
082             *
083             * 半角スペã?ス埋めは、文字が半角ã?全角混在でもかまã�?�¾せんã€?
084             * なおã?エラーチェãƒ?‚¯は行われませんã€?
085             * 実行前に、å¿?�š valueCheck( String value ,int len ) を行うå¿?¦�がありますã?
086             *
087             * @og.rev 3.5.4.5 (2004/01/23) エンコード指定に変更しますã?
088             *
089             * @param   value    ?¦?©?¬?¬埋めするæ–?­—å?
090             * @param   sizeX    整数部åˆ??æ–?­—å?の長ã�?
091             * @param   sizeY    少数部åˆ??æ–?­—å?の長ã�?
092             * @param   encode   固定長で変換するæ–?­—エンコーãƒ?
093             *
094             * @return  ?¦?©?¬?¬埋めした新しいæ–?­—å?
095             */
096            public String valueFill( final String value ,final int sizeX ,final int sizeY,final String encode ) {
097                    int len = (sizeY == 0) ? sizeX : sizeX + sizeY + 1;
098    
099                    return StringUtil.stringFill( value,len,encode );
100            }
101    
102            /**
103             * そã?DBTypeの,ãƒ?ƒ•ォルトã?値(物ç�?š„初期設定å?)を返しますã?
104             *
105             * ä¸?ˆ¬に、文字å?の場合ã?,ゼロストリング""  数字ã?場合ã? "0" ですã?
106             *
107             * @return  物ç�?š„初期設定å?
108             */
109            public String getDefault() {
110                    return defValue;
111            }
112    
113            /**
114             * String引数のæ–?­—å?を+1した文字å?を返しますã?
115             *
116             * これは、英字ã?場å�?A,B,C など)は、B,C,D のように,æœ?µ‚桁ã?æ–?­—コードを
117             * ?‹ï¼?しますã?
118             * æ–?­—å?が数字タイプã?場合ã?, 数字に変換してã€?1 しますã?
119             * æœ?µ‚桁がã€?9","z","Z" および、その全角文字ã?場合ã?"0","a","Z" および、その全角文字に
120             * 変換後ã?ひとつ上ã?桁で、同様ã? ?‹ï¼?操作を行いますã?
121             * æœ?‚‚上位ã?桁が、これらの繰り上がり桁ã?場合ã?、すべての桁が初期化された状態に戻りますã?
122             * 例ï¼?23 â‡?124 , ABC â‡?ABD , 789 â‡?790 , XYZ â‡?XXZ ,
123             *     ABC123 �ABC124 , AB99 �AC00 , 12ZZ99 �13AA00 , ZZZZ �AAAA
124             * 引数ã�?null の場合と、ゼロæ–?­—å?("")の場合ã?,物ç�?š„初期設定å?(String getDefault())
125             * の値を返しますã?
126             *
127             * @og.rev 4.0.0.0 (2005/01/31)  ?¡??½??方法を変更(汎用çš?�ª?¡??½?
128             *
129             * @param   value  String引数
130             *
131             * @return  引数のæ–?­—å?を+1した文字å?ã€?
132             */
133            public String valueAdd( final String value ) {
134                    if( value == null || value.length() == 0 ) { return getDefault(); }
135    
136                    char[] chs = value.toCharArray() ;
137    
138                    for( int i=chs.length-1; i>=0; i-- ) {
139                            boolean over = true;
140                            switch( chs[i] ) {
141                                    case '9'  : chs[i] = '0' ; break;
142                                    case 'z'  : chs[i] = 'a' ; break;
143                                    case 'Z'  : chs[i] = 'A' ; break;
144                                    case '?? : chs[i] = '??; break;
145                                    case '?? : chs[i] = '??; break;
146                                    case '?º' : chs[i] = '?¡'; break;
147                                    default   : chs[i]++; over=false; break;
148                            }
149                            if( !over ) { break; }          // キャリーオーバã?してã�?�ªければ、終äº?
150                    }
151    
152                    return new String( chs );
153            }
154    
155            /**
156             * String引数のæ–?­—å?に、第?’引数にæŒ?®šã?æ–?­—å?(数字ã?日付ç­?を加算して返しますã?
157             *
158             * これは、valueAdd( String ) と本質çš?�«は同じ動きをしますが、任意ã?æ–?­—å?を加算すã‚?
159             * ため、主として、数字系ã‚?—¥付系の DBType にのみ実è£?�—ますã?
160             * 実è£?�Œなã�??合ã?、UnsupportedOperationException ã‚?throw しますã?
161             * 
162             * 第?’引数 がã?null の場合ã?ã€?¼‹ï¼?する valueAdd( String )が呼ばれますã?
163             * これは、å°?�¥çš?�«は、valueAdd( String ) を無くすことを意味しますã?
164             *
165             * @og.rev 5.6.0.3 (2012/01/24) ADD に、引数の値を加算する機è?を追åŠ?�—ますã?
166             *
167             * @param   value  String引数
168             * @param   add    åŠ?®—する文字å?(null の場合ã?、従来と同じã€?1 しますã?)
169             *
170             * @return  引数のæ–?­—å?第?’引数にæŒ?®šã?æ–?­—å?(数字ã?日付ç­?を加算した文字å?ã€?
171             * @throws UnsupportedOperationException 実è£?�Œ存在しなã�??å�?
172             */
173            public String valueAdd( final String value,final String add ) {
174                    if( add == null || add.isEmpty()  ) { return valueAdd( value ); }
175    
176                    String errMsg = "こã?クラスでは、引数付ã?任意ã?åŠ?®—ã?実è£?�•れてã�?�¾せんã€?
177                                                            + getClass().getName() + " Action=[ADD]"
178                                                            + " oldValue=[" + value + "] newValue=[" + add + "]" ;
179                    throw new UnsupportedOperationException( errMsg );
180            }
181    
182            /**
183             * エãƒ?‚£ターで編é›?�•れたãƒ??タを登録する場合に、データそã?もã?を変換して、実登録ãƒ??タを作æ?しますã?
184             *
185             * 例えば,大æ–?­—ã?みのフィールドならã?大æ–?­—化しますã?
186             * 実登録ãƒ??タの作æ?は、DBType オブジェクトを利用しますã?で,
187             * これと CellEditor とがアンマッチã?場合ã?、うまくデータ変換
188             * されなã�?�¯能性がありますã?で、注意願いますã?
189             *
190             * @og.rev 3.3.3.0 (2003/07/09) 前後ã?スペã?スを取り除ã�?�¦おくã€?
191             * @og.rev 3.3.3.1 (2003/07/18) 後ろスペã?スを取り除くã?(StringUtil#rTrim)
192             *
193             * @param       value   (ä¸?ˆ¬に編é›?ƒ‡ータとして登録されたデータ)
194             *
195             * @return  修正後ã?æ–?­—å?(ä¸?ˆ¬にãƒ??タベã?スに登録するãƒ??タ)
196             */
197            public String valueSet( final String value ) {
198                    return StringUtil.rTrim( value );
199            }
200    
201            /**
202             * action でæŒ?®šされたコマンドを実行して、å?の変換を行いますã?
203             *
204             * oldValue(旧ãƒ??タ)は、å?のDBTableModelに設定されてã�?�Ÿ値ですã?通常はã€?
205             * こã?値を使用してカラãƒ?¯Žに変換を行いますã?newValue(新ãƒ??タ)は、引数で
206             * æŒ?®šされた新しい値ですã?こã?値には、パラメータを指定して変換方法を
207             * 制御することも可能ですã?
208             * æŒ?®šã?アクションがカラãƒ?�§処ç�?�§きなã�??合ã?、エラーになりますã?
209             *
210             * @param   action アクションコマンãƒ?
211             * @param   oldValue 入力データ(旧ãƒ??タ)
212             * @param   newValue 入力データ(新ãƒ??タ)
213             *
214             * @return      実行後ã?ãƒ??タ
215             */
216            public String valueAction( final String action,final String oldValue,final String newValue ) {
217                    String errMsg = "こã?クラスでは、このアクションは実è£?�•れてã�?�¾せんã€?
218                                                            + getClass().getName() + " Action=[" + action + "]"
219                                                            + " oldValue=[" + oldValue + "] newValue=[" + newValue + "]" ;
220                    throw new UnsupportedOperationException( errMsg );
221            }
222    
223            /**
224             * ãƒ??タが登録可能かどã�?�‹[true/false]をチェãƒ?‚¯しますã?
225             *
226             * ãƒ??タがエラーの場合ã?、そのエラーå†?®¹を返しますã?
227             *
228             * @og.rev 2.1.1.1 (2002/11/15) HTMLタグチェãƒ?‚¯のメソãƒ?ƒ‰の共有化ã€?
229             * @og.rev 3.0.1.3 (2003/03/11) DBTypeCheckUtilクラスを利用するように修正
230             * @og.rev 3.6.0.0 (2004/09/22) dbType パラメータを引数に追åŠ?
231             * @og.rev 5.2.2.0 (2010/11/01) 厳å¯?�«チェãƒ?‚¯(isStrict=true)するフラグを追åŠ?
232             *
233             * @param   key   キー
234             * @param   value 値
235             * @param   sizeX 整数部åˆ??æ–?­—å?の長ã�?
236             * @param   sizeY 少数部åˆ??æ–?­—å?の長ã�?
237             * @param   typeParam  dbType パラメータ
238             * @param   isStrict     厳å¯?�«チェãƒ?‚¯するかどã�?�‹ [true:する/false:標準的]
239             *
240             * @return  エラーå†?®¹
241             */
242    //      public ErrorMessage valueCheck( final String key ,final String value ,
243    //                                                                      final int sizeX ,final int sizeY ,final String typeParam ) {
244            public ErrorMessage valueCheck( final String key ,final String value ,
245                                                                            final int sizeX ,final int sizeY ,final String typeParam ,final boolean isStrict) {
246    
247                    ErrorMessage msg = new ErrorMessage();
248                    if( value == null || value.length() == 0 ) { return msg; }
249    
250                    int len = (sizeY == 0) ? sizeX : sizeX + sizeY + 1;
251                    if( len < value.length() ) {
252                            // æ–?­—å?の長さがæŒ?®šã?長さよりも長ã�?�§すã?
253                            msg.addMessage( 0,ErrorMessage.NG,"ERR0006",key,value,
254                                                                            String.valueOf( value.length() ),String.valueOf( len ) );
255                    }
256    
257                    StringBuilder val = new StringBuilder();
258                    boolean isError = false;
259                    for( int i=0; i<value.length(); i++ ) {
260                            char ch = value.charAt( i );
261                            if( ch < 0x20 || ch > 0x7e ) {
262                                    val.append( "<span class=\"NG\">" ).append( ch ).append( "</span>" );
263                                    isError = true;
264                            }
265                            else {
266                                    val.append( ch );
267                            }
268                    }
269                    if( isError ) {
270                            // æŒ?®šã?æ–?­—以外ã?æ–?­—が使われてã�?�¾すã?
271                            msg.addMessage( 0,ErrorMessage.NG,"ERR0009", key,val.toString() );
272                    }
273    
274                    // 3.6.0.0 (2004/09/22) dbType パラメータを使用したマッチチェãƒ?‚¯
275                    String check = DBTypeCheckUtil.matcheCheck( value,typeParam );
276                    if( check != null ) {
277                            // æŒ?®šã?æ–?­—以外ã?æ–?­—が使われてã�?�¾すã?
278                            msg.addMessage( 0,ErrorMessage.NG,"ERR0009", key,check );
279                    }
280    
281                    // クロスサイトスクリプティング対策ï¼?<', '>' は登録させなã�??
282                    msg = xssCheck( key ,value, msg );
283                    return msg;
284            }
285    
286            /**
287             * HTMLタグかどã�?�‹をチェãƒ?‚¯しますã?
288             *
289             * クロスサイトスクリプティング対策としてã€?&lt;', '&gt;' は登録させなã�??
290             *
291             * @og.rev 2.1.1.1 (2002/11/15) HTMLタグチェãƒ?‚¯のメソãƒ?ƒ‰の共有化ã€?
292             *
293             * @param   key         タグのキー
294             * @param   value       対象の値
295             * @param   msg         ErrorMessageオブジェクãƒ?
296             *
297             * @return  エラーå†?®¹(エラーを追åŠ?�—たã?ErrorMessageオブジェクãƒ?
298             */
299            protected ErrorMessage xssCheck( final String key ,final String value, final ErrorMessage msg ) {
300                    StringBuilder val = new StringBuilder();
301                    boolean isError = false;
302                    for( int i=0; i<value.length(); i++ ) {
303                            char ch = value.charAt( i );
304                            if( ch == '<' || ch == '>' ) {
305                                    val.append( "<span class=\"NG\">" ).append( ch ).append( "</span>" );
306                                    isError = true;
307                            }
308                            else {
309                                    val.append( ch );
310                            }
311                    }
312                    if( isError ) {
313                            // HTMLタグは登録できませんã€?
314                            msg.addMessage( 0,ErrorMessage.NG,"ERR0010", key,val.toString() );
315                    }
316                    return msg;
317            }
318    }