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.fukurou.util;
017    
018    import java.util.Map ;
019    import java.util.LinkedHashMap ;
020    import java.util.Locale;
021    import 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     */
035    public 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    //              Types<T>[] types = typemap.values().toArray( new Types[typemap.size()] );
143    //              StringBuilder buf = new StringBuilder();
144    //              buf.append( CR );
145    //              for( int i=0; i<types.length; i++ ) {
146    //                      buf.append( SPACE ).append( types[i].toString() ).append( CR );
147    //              }
148    //              return buf.toString();
149    
150                    // 4.3.3.6 (2008/11/15) Generics警告対å¿?, toArray から、Iterator に、変更
151                    Iterator<Types<T>> ite = typemap.values().iterator();
152                    StringBuilder buf = new StringBuilder();
153                    buf.append( CR );
154                    while( ite.hasNext() ) {
155                            buf.append( SPACE ).append( ite.next() ).append( CR );
156                    }
157                    return buf.toString();
158            }
159    
160            /**
161             * å†?ƒ¨オブジェクトを管ç�?�™る為の インナã?クラス
162             * キーオブジェクトとそã?説明ã?ペアを管ç�?�—ますã?
163             *
164             * @version  4.0
165             * @author       Kazuhiko Hasegawa
166             * @since    JDK5.0,
167             */
168            private static class Types<T> {
169                    private final T key ;
170                    private final String msg ;
171    
172                    /**
173                     * キーと説明をæŒ?®šしたコンストラクタ
174                     *
175                     * @param key T キーオブジェクãƒ?
176                     * @param       msg     説æ˜?
177                     * @throws IllegalArgumentException キーオブジェクトがnullの場å�?
178                     */
179                    public Types( final T key,final String msg ) {
180                            if( key == null ) {
181                                    String errMsg = "key には null をセãƒ?ƒˆできませんã€? ;
182                                    throw new IllegalArgumentException( errMsg );
183                            }
184    
185                            this.key = key;
186                            this.msg = msg;
187                    }
188    
189                    /**
190                     * キーオブジェクトを返しますã?
191                     *
192                     * @return key T キーオブジェクãƒ?
193                     */
194                    public T getKey() { return key; }
195    
196                    /**
197                     * 説明を返しますã?
198                     *
199                     * @return msg String 説æ˜?
200                     */
201                    public String getMsg() { return msg; }
202    
203                    /**
204                     * å†?ƒ¨のæ–?­—å?表現を返しますã?
205                     *
206                     * @return      å†?ƒ¨のæ–?­—å?表現
207                     */
208                    public String toString() {
209                            return key + " : " + msg ;
210                    }
211            }
212    }