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 の3タイプが指定できます。 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 /** 8つ分のスペースです。 */ 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<T> で指定するオブジェクトです。 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}