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 }