    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.Map ;
    019import java.util.LinkedHashMap ;
    020import java.util.Locale;
    021import java.util.Iterator;
    022
    023/**
    024 * EnumType.java は、共通的に使用される 文字型選択フィールドを簡素化するクラスです。
    025 * JDK5.0 より導入された enum に類似の機能を提供しますが、内部的により特化した
    026 * 機能を提供します。
    027 * 具体的には、デバッグ情報の簡易出力や、文字列入力時の包含関係チェック、
    028 * デフォルト値(初期値)の登録などです。
    029 * 初期値には、String,int,boolean の３タイプが指定できます。
    030 *
    031 * @version  4.0
    032 * @author       Kazuhiko Hasegawa
    033 * @since    JDK5.0,
    034 */
    035public final class EnumType<T extends Comparable<T>> {  // 4.3.3.6 (2008/11/15) Generics警告対応
    036        /** システム依存の改行記号をセットします。 */
    037        private static final String CR = System.getProperty("line.separator");
    038
    039        /** ８つ分のスペースです。 */
    040        private static final String SPACE = "    " ;
    041
    042        private final Map<String,Types<T>> typemap = new LinkedHashMap<String,Types<T>>();
    043
    044        private final String title  ;
    045        private final T      defVal ;
    046
    047        /**
    048         * タイトルと初期値を指定して構築する コンストラクター
    049         * nval メソッドを使用する場合に、利用します。
    050         *
    051         * @param title タイトル
    052         * @param val 初期値
    053         */
    054        public EnumType( final String title,final T val ) {
    055                this.title = title ;
    056                defVal = val ;
    057        }
    058
    059        /**
    060         * キーとその説明(メッセージ)を追加します。
    061         * 内部キャッシュ(Map)に追加します。
    062         * 通常のメソッド名なら、put か add ですが、return に
    063         * 自分自身を記述できるため、初期設定(コンストラクタ)＋値設定を
    064         * 連続して記述することが出来る append メソッドにちなんで命名しています。
    065         *
    066         * @param key キー
    067         * @param msg メッセージ
    068         *
    069         * @return      自分自身
    070         */
    071        public EnumType<T> append( final T key, final String msg ) {
    072                typemap.put( String.valueOf( key ).toUpperCase( Locale.JAPAN ),new Types<T>( key,msg ) );
    073                return this ;
    074        }
    075
    076        /**
    077         * 文字列相当の設定値より、対応する T オブジェクトを返します。
    078         * T は、インスタンス作成時に、new EnumType&lt;T&gt; で指定するオブジェクトです。
    079         * 引数の文字列は、 String.valueOf( T ) で得られる文字列です。
    080         * 引数が、null か、長さゼロの文字列の場合は、コンストラクタで指定した
    081         * 初期値が返されます。
    082         * T に Boolean や Integer を指定している場合は、アンボクシング機能により、
    083         * boolean や int に自動的にキャストされます。
    084         *
    085         * @param       strKey 文字列相当の設定値
    086         *
    087         * @return      strKeyに対応するオブジェクト
    088         * @throws IllegalArgumentException 引数がMapに存在しなかった場合(nullはOK)
    089         */
    090        public T nval( final String strKey ) {
    091                if( strKey != null && strKey.length() > 0 ) {
    092                        String upKey = strKey.toUpperCase( Locale.JAPAN );
    093                        if( typemap.containsKey( upKey ) ) {
    094                                Types<T> type = typemap.get( upKey );
    095                                return type.getKey();
    096                        }
    097                        else {
    098                                String errMsg = title + " 範囲設定エラー"
    099                                                        + CR + "引数 [" + strKey + "] は、内部にマップされていません。"
    100                                                        + CR + toString() ;
    101                                throw new IllegalArgumentException( errMsg );
    102                        }
    103                }
    104                return defVal ;
    105        }
    106
    107        /**
    108         * 初期値を返します。
    109         * T に Boolean や Integer を指定している場合は、アンボクシング機能により、
    110         * boolean や int に自動的にキャストされます。
    111         *
    112         * @return      初期値オブジェクト
    113         */
    114        public T getDefault() {
    115                return defVal ;
    116        }
    117
    118        /**
    119         * 設定した T が存在しているかどうかを返します。
    120         * 内部に値を取り込んだ後で使用する、存在チェックです。
    121         * 通常、nval で 取り込んだ後は、チェック不要です。
    122         * 引数が null の場合は、false を返します。
    123         *
    124         * @param key T 設定した Tオブジェクト
    125         *
    126         * @return      存在する:true / 存在しない:false
    127         */
    128        public boolean contains( final T key ) {
    129                if( key == null ) {
    130                        return false;
    131                }
    132                return typemap.containsKey( String.valueOf( key ).toUpperCase( Locale.JAPAN ) );
    133        }
    134
    135        /**
    136         * 内部の文字列表現を返します。
    137         *
    138         * @return      内部の文字列表現
    139         */
    140        @Override
    141        public String toString() {
    142                // 4.3.3.6 (2008/11/15) Generics警告対応 , toArray から、Iterator に、変更
    143                Iterator<Types<T>> ite = typemap.values().iterator();
    144                StringBuilder buf = new StringBuilder();
    145                buf.append( CR );
    146                while( ite.hasNext() ) {
    147                        buf.append( SPACE ).append( ite.next() ).append( CR );
    148                }
    149                return buf.toString();
    150        }
    151
    152        /**
    153         * 内部オブジェクトを管理する為の インナークラス
    154         * キーオブジェクトとその説明のペアを管理します。
    155         *
    156         * @version  4.0
    157         * @author       Kazuhiko Hasegawa
    158         * @since    JDK5.0,
    159         */
    160        private static class Types<T> {
    161                private final T key ;
    162                private final String msg ;
    163
    164                /**
    165                 * キーと説明を指定したコンストラクタ
    166                 *
    167                 * @param key T キーオブジェクト
    168                 * @param       msg     説明
    169                 * @throws IllegalArgumentException キーオブジェクトがnullの場合
    170                 */
    171                public Types( final T key,final String msg ) {
    172                        if( key == null ) {
    173                                String errMsg = "key には null をセットできません。" ;
    174                                throw new IllegalArgumentException( errMsg );
    175                        }
    176
    177                        this.key = key;
    178                        this.msg = msg;
    179                }
    180
    181                /**
    182                 * キーオブジェクトを返します。
    183                 *
    184                 * @return key T キーオブジェクト
    185                 */
    186                public T getKey() { return key; }
    187
    188                /**
    189                 * 説明を返します。
    190                 *
    191                 * @return msg String 説明
    192                 */
    193                public String getMsg() { return msg; }
    194
    195                /**
    196                 * 内部の文字列表現を返します。
    197                 *
    198                 * @return      内部の文字列表現
    199                 */
    200                @Override
    201                public String toString() {
    202                        return key + " : " + msg ;
    203                }
    204        }
    205}