    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.plugin.column;
    017
    018import org.opengion.fukurou.util.ErrorMessage;
    019import org.opengion.fukurou.util.StringUtil;
    020import org.opengion.hayabusa.db.AbstractDBType;
    021import org.opengion.hayabusa.db.DBTypeCheckUtil;
    022
    023import java.util.Locale ;
    024
    025/**
    026 * 半角文字＋半角カタカナの大文字のみに制限された文字列を扱う為の、カラム属性を定義します。
    027 *
    028 * ホスト送信用なので、半角カタカナ小文字を半角カタカナ大文字に変換します。
    029 * 通常の半角文字や半角カタカナを入力すると、大文字に変換後に、チェックを行います。
    030 * 半角カタカナの小文字とは、「ｧ,ｨ,ｩ,ｪ,ｫ,ｬ,ｭ,ｮ,ｯ」のことで、これらの文字列を、
    031 * 「ｱ,ｲ,ｳ,ｴ,ｵ,ﾔ,ﾕ,ﾖ,ｼ」に置き換えます。
    032 *
    033 * タイプチェックとして、以下の条件を判定します。
    034 * ・文字列長は、Byte換算での文字数との比較
    035 * ・半角文字＋半角カタカナチェック
    036 * ・文字パラメータの 正規表現チェック
    037 * ・クロスサイトスクリプティングチェック
    038 *
    039 * @og.group データ属性
    040 *
    041 * @version  4.0
    042 * @author   Kazuhiko Hasegawa
    043 * @since    JDK5.0,
    044 */
    045public class DBType_XHU extends AbstractDBType {
    046        /** このプログラムのVERSION文字列を設定します。   {@value} */
    047        private static final String VERSION = "6.4.2.0 (2016/01/29)" ;
    048
    049        /**
    050         * デフォルトコンストラクター
    051         *
    052         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    053         */
    054        public DBType_XHU() { super(); }                // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    055
    056        /**
    057         * エディターで編集されたデータを登録する場合に、データそのものを
    058         * 変換して、実登録データを作成します。
    059         * 例えば,大文字のみのフィールドなら、大文字化します。
    060         * 実登録データの作成は、DBType オブジェクトを利用しますので,
    061         * これと Editor とがアンマッチの場合は、うまくデータ変換
    062         * されない可能性がありますので、注意願います。
    063         *
    064         * @og.rev 3.3.3.0 (2003/07/09) 前後のスペースを取り除いておく。
    065         * @og.rev 3.3.3.1 (2003/07/18) 後ろスペースを取り除く。(StringUtil#rTrim)
    066         * @og.rev 3.4.0.0 (2003/09/01) 半角カナ文字化け対策(ｱ,ｴ,ｶ,ｰ,ﾗ)の変換処理の廃止
    067         *
    068         * @param       value   (一般に編集データとして登録されたデータ)
    069         *
    070         * @return  修正後の文字列(一般にデータベースに登録するデータ)
    071         */
    072        @Override
    073        public String valueSet( final String value ) {
    074                if( value == null ) { return null; }
    075                String rtnVal = StringUtil.rTrim( value );
    076                char[] ch = rtnVal.toCharArray();               // 3.3.3.1 (2003/07/18)
    077
    078                boolean flag = false;
    079                for( int i=0; i<ch.length; i++ ) {
    080                        switch( ch[i] ) {
    081        // 3.4.0.0 (2003/09/01) 半角カナ文字化け対策(ｱ,ｴ,ｶ,ｰ,ﾗ)の変換処理の廃止
    082        //                      case '±' : ch[i] = 'ｱ'; flag = true; break;
    083        //                      case '´' : ch[i] = 'ｴ'; flag = true; break;
    084        //                      case '¶' : ch[i] = 'ｶ'; flag = true; break;
    085        //                      case '°' : ch[i] = 'ｰ'; flag = true; break;
    086        //                      case '×' : ch[i] = 'ﾗ'; flag = true; break;
    087                                case 'ｧ'  : ch[i] = 'ｱ'; flag = true; break;
    088                                case 'ｨ'  : ch[i] = 'ｲ'; flag = true; break;
    089                                case 'ｩ'  : ch[i] = 'ｳ'; flag = true; break;
    090                                case 'ｪ'  : ch[i] = 'ｴ'; flag = true; break;
    091                                case 'ｫ'  : ch[i] = 'ｵ'; flag = true; break;
    092                                case 'ｬ'  : ch[i] = 'ﾔ'; flag = true; break;
    093                                case 'ｭ'  : ch[i] = 'ﾕ'; flag = true; break;
    094                                case 'ｮ'  : ch[i] = 'ﾖ'; flag = true; break;
    095                                case 'ｯ'  : ch[i] = 'ｼ'; flag = true; break;
    096                                default   : break;
    097                        }
    098                }
    099                if( flag ) {
    100                        rtnVal = new String( ch );
    101                }
    102                return rtnVal.toUpperCase(Locale.JAPAN);
    103        }
    104
    105        /**
    106         * データが登録可能かどうかをチェックします。
    107         * データがエラーの場合は、そのエラー内容を返します。
    108         *
    109         * @og.rev 3.0.1.3 (2003/03/11) DBTypeCheckUtilクラスを利用するように修正
    110         * @og.rev 3.6.0.0 (2004/09/22) dbType パラメータ(文字パラメータ)を引数に追加
    111         * @og.rev 3.6.1.0 (2005/01/05) 半角カタカナに、『､』を含めます。(0xff65 以上 → 0xff64以上)
    112         * @og.rev 5.2.2.0 (2010/11/01) 厳密にチェック(isStrict=true)するフラグを追加
    113         *
    114         * @param   key         キー
    115         * @param   value       値
    116         * @param   sizeX       整数部分の文字列の長さ
    117         * @param   sizeY       小数部分の文字列の長さ
    118         * @param   typeParam   dbType パラメータ(文字パラメータ)
    119         * @param   isStrict    厳密にチェックするかどうか[true:する/false:標準的]
    120         *
    121         * @return  エラー内容
    122         * @og.rtnNotNull
    123         */
    124        @Override
    125        public ErrorMessage valueCheck( final String key ,final String value ,
    126                                                                        final int sizeX ,final int sizeY ,final String typeParam ,final boolean isStrict) {
    127
    128                // 6.3.9.1 (2015/11/27) Found 'DD'-anomaly for variable(PMD)
    129                final ErrorMessage msg = new ErrorMessage();
    130                if( value == null || value.isEmpty() ) { return msg; }
    131
    132                final int len = (sizeY == 0) ? sizeX : sizeX + sizeY + 1;
    133                String check = DBTypeCheckUtil.byteLengthCheck( value,len );
    134                if( check != null ) {
    135                        // 文字列の長さが指定の長さよりも長いです。
    136                        msg.addMessage( 0,ErrorMessage.NG,"ERR0006",key,value,check,String.valueOf( len ) );
    137                }
    138
    139                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    140                boolean isError = false;
    141                for( int i=0; i<value.length(); i++ ) {
    142                        final char ch = value.charAt( i );
    143                        // 半角カタカナの小文字(ｧ ｨ ｩ ｪ ｫ ｬ ｭ ｮ ｯ)も、NG
    144                        if(             ch < 0x20                                                                                               // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
    145                                ||      ch > 0x7e   && ch < 0xff64
    146                                ||      ch > 0xff66 && ch < 0xff70
    147                                ||      ch >= 0xffa0 ) {
    148                                        buf.append( "<span class=\"NG\">" ).append( ch ).append( "</span>" );
    149                                        isError = true;
    150                        }
    151                        else {
    152                                buf.append( ch );
    153                        }
    154                }
    155                if( isError ) {
    156                        // 指定の文字以外の文字が使われています。
    157                        msg.addMessage( 0,ErrorMessage.NG,"ERR0009", key,buf.toString() );
    158                }
    159
    160                // 3.6.0.0 (2004/09/22) dbType パラメータ(文字パラメータ)を使用したマッチチェック
    161                check = DBTypeCheckUtil.matcheCheck( value,typeParam );
    162                if( check != null ) {
    163                        // 指定の文字以外の文字が使われています。
    164                        msg.addMessage( 0,ErrorMessage.NG,"ERR0009", key,check );
    165                }
    166
    167                // クロスサイトスクリプティング対策：'<', '>' は登録させない。
    168                // 6.3.9.1 (2015/11/27) Found 'DD'-anomaly for variable(PMD)
    169                return xssCheck( key ,value, msg );
    170        }
    171}