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