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.Set;
019 import java.util.Map;
020 import java.util.HashMap;
021 import java.util.Arrays;
022 import java.util.Locale;
023
024 /**
025 * Attributes.java は、String 型キーにString型??Map するクラスです?
026 *
027 * HTMLのPOST/GET等?受け渡しや、String型?引数が多い場合に効果があります?
028 * 特に、getAttributes( String[] param ) による属?リスト作?は?
029 * HTMLタグの属?定義を行う上で?非常に便利に利用できます?
030 *
031 * こ?実??同期化されません?
032 *
033 * @version 4.0
034 * @author Kazuhiko Hasegawa
035 * @since JDK5.0,
036 */
037 public final class Attributes {
038 private final Map<String,String> attri ;
039
040 /**
041 * ?ォルトコンストラクター
042 *
043 */
044 public Attributes() {
045 attri = new HashMap<String,String>();
046 }
047
048 /**
049 * Attributesオブジェク?を与えて新しく作?するコンストラクター
050 *
051 * @param att Attributesオブジェク?
052 */
053 public Attributes( final Attributes att ) {
054 attri = new HashMap<String,String>( att.attri );
055 }
056
057 /**
058 * マップから??ングをすべて削除しま??
059 *
060 */
061 public void clear() {
062 attri.clear() ;
063 }
064
065 /**
066 * マップが??キーを???する値を返します?
067 * マップがこ?キーのマッピングを保持して???合? null
068 * を返します?戻り?の null は、???がキーのマッピング?
069 * 保持して??とを示すとはかぎりません。つまり?マップが
070 * 明示?キー?null にマップすることもあります?
071 *
072 * @param key 関連付けられた?が返されるキー(大?小文字?同?)
073 *
074 * @return マップが、指定されたキーにマッピングして?値?
075 * こ?キーに対するマッピングが???にな??合? null
076 */
077 public String get( final String key ) {
078 return attri.get( key.toLowerCase( Locale.JAPAN ) ) ;
079 }
080
081 /**
082 * ?された値と?されたキーをこのマップに関連付けま?
083 * ?されたキーに、null を関連付けることはできません?
084 * (もちろん?"?ゼロストリング は登録できます?)
085 * なぜなら?getAttribute( String[] keys ) 等で値?null の
086 * キーは、取得できな?です?
087 * また?すでに何らか?値がセ?されて???null をセ?した
088 * 場合??前?値をなにも変更しません?
089 * 通常、?をクリアした??合?? remove( String key ) を利用してください?
090 *
091 * @param key ?される値が関連付けられるキー(大?小文字?同?)
092 * @param value ?されるキーに関連付けられる?
093 */
094 public void set( final String key,final String value ) {
095 if( value != null ) {
096 attri.put( key.toLowerCase( Locale.JAPAN ),value ) ;
097 }
098 }
099
100 /**
101 * ?された値と?されたキーをこのマップに関連付けま?
102 * set( String key,String value ) との違いは?value ?null
103 * の場合に、def を代わりにセ?することです?
104 * ただし?value ?null で、def ?null の場合??
105 * なにもセ?されません?
106 *
107 * @param key ?される値が関連付けられるキー(大?小文字?同?)
108 * @param value ?されるキーに関連付けられる?
109 * @param def value ?null の場合にキーに関連付けられる?
110 */
111 public void set( final String key,final String value,final String def ) {
112 if( value != null ) { attri.put( key.toLowerCase( Locale.JAPAN ),value ) ; }
113 else if( def != null ) { attri.put( key.toLowerCase( Locale.JAPAN ),def ) ; }
114 }
115
116 /**
117 * ?された値と?されたキーをこのマップに追?ま?
118 *
119 * マップ?身のキーは、ユニ?クである為、既存?値に対して?
120 * 新しく値を追?ます?
121 * 追?る方法?、?の??の結合です?こ?メソ?では?
122 * ?ォルト?スペ?スで結合します?
123 *
124 * 値?null また?、すでにそ?キーに同??値が関連付けられて?場合??
125 * 何もしません?
126 *
127 * @param key ?される値が関連付けられるキー(大?小文字?同?)
128 * @param value ?されるキーの値に、追?れる値
129 */
130 public void add( final String key,final String value ) {
131 add( key,value," " ) ;
132 }
133
134 /**
135 * ?された値と?されたキーをこのマップに追?ま?
136 *
137 * マップ?身のキーは、ユニ?クである為、既存?値に対して?
138 * 新しく値を追?ます?
139 * 追?る方法?、?の??の結合です?こ?メソ?では?
140 * 引数 sepa で??を結合します?
141 *
142 * 値?null また?、sepa ?null また?、すでにそ?キーに
143 * 同??値が関連付けられて?場合?、何もしません?
144 *
145 * @param key ?される値が関連付けられるキー(大?小文字?同?)
146 * @param value ?されるキーの値に、追?れる値
147 * @param sepa 値を?結するとき???
148 */
149 public void add( final String key,final String value,final String sepa ) {
150 if( value != null && sepa != null ) {
151 String lkey = key.toLowerCase( Locale.JAPAN );
152 String temp = attri.get( lkey );
153 if( temp != null ) {
154 temp = temp.trim();
155 if( temp.indexOf( value ) < 0 || // 存在しな?また??
156 ( ! temp.equals( value ) && // ??しな?
157 ! temp.startsWith( value + sepa ) && // 先?にな?
158 ! temp.endsWith( sepa + value ) && // ?にな?
159 temp.indexOf( sepa + value + sepa ) < 0 ) ) { // 途中にな?
160 if( temp.endsWith( sepa ) ) {
161 attri.put( lkey,temp + value );
162 }
163 else {
164 attri.put( lkey,temp + sepa + value );
165 }
166 }
167 }
168 else {
169 attri.put( lkey,value );
170 }
171 }
172 }
173
174 /**
175 * Attributes 属?を?既存?属?に追?ます?
176 * すでに同?ーの属?が存在して?場合??上書きで
177 * 置き換えます?
178 * 引数 att ?null の場合??何もしません?
179 *
180 * @param att Attributes属?
181 */
182 public void addAttributes( final Attributes att ) {
183 if( att != null ) {
184 String[] keys = att.getKeyArray();
185 for( int i=0; i<keys.length; i++ ) {
186 set( keys[i],att.get( keys[i] ) );
187 }
188 }
189 }
190
191 /**
192 * こ?キーにマッピングがある?合に、そのマッピングを???から削除しま?
193 *
194 * @param key マッピングが???から削除されるキー(大?小文字?同?)
195 *
196 * @return こ?キーにマッピングがある?合に、そのマッピングを???から削除しま?
197 * ?されたキーに関連した以前?値。key にマッピングがなかった?合? null?
198 */
199 public String remove( final String key ) {
200 return attri.remove( key.toLowerCase( Locale.JAPAN ) );
201 }
202
203 /**
204 * マップ?のキーと値のマッピングの数を返します?
205 *
206 * @return インタフェース Map ?? size
207 *
208 */
209 public int size() {
210 return attri.size() ;
211 }
212
213 /**
214 * マップに含まれて?キーの配?を返します?
215 * ここでは、キーの配?はソートして返します?
216 *
217 * @return マップに含まれて?キーの配?
218 *
219 */
220 public String[] getKeyArray() {
221 Set<String> keyset = attri.keySet();
222 String[] rtn = keyset.toArray( new String[keyset.size()] ) ;
223 Arrays.sort( rtn );
224 return rtn ;
225 }
226
227 /**
228 * マップに含まれて?キーと属?のペア?タグの属?リスト?形式で返します?
229 * key1="value1" key2="value2" key3="value3" .... の形式で、value ?null の
230 * 場合??key そ?も?のペアを?力しません?
231 * value が空?? "" の場合??key="" で出力します?
232 *
233 * 引数には?key として出力したい値を?列文字?で渡します?
234 * これは、拡張性に乏し?すべて出せ??属??の追?対応できる?
235 * 方法ですが、タグ毎に異なる属?のみを管?るには?厳格に出?
236 * タグ属?を定義した??思いから?導?しました?
237 *
238 * @param keys ??key の配???(大?小文字?同?)
239 *
240 * @return キーと属?のペアをタグの属?リスト?形式で返しま?
241 *
242 */
243 public String getAttribute( final String[] keys ) {
244 StringBuilder buf = new StringBuilder( 200 );
245
246 for( int i=0; i<keys.length; i++ ) {
247 String value = get( keys[i].toLowerCase( Locale.JAPAN ) );
248 if( value != null ) {
249 buf.append( keys[i] ).append("=");
250 buf.append("\"").append( value ).append("\" ");
251 }
252 }
253 return buf.toString();
254 }
255
256 /**
257 * マップに含まれて?キーと属?のペア?タグの属?リスト?形式ですべて返します?
258 * なお?value ?null の場合??key そ?も?のペアを?力しません?
259 * value が空?? "" の場合??key="" で出力します?
260 *
261 * @return キーと属?のペアをタグの属?リスト?形式で返しま?
262 *
263 */
264 public String getAttribute() {
265 return getAttribute( getKeyArray() );
266 }
267
268 /**
269 * こ?オブジェクト???表現を返します?
270 * 基本???目?使用します?
271 *
272 * @return オブジェクト???表現
273 */
274 @Override
275 public String toString() {
276 return( getAttribute() );
277 }
278 }