001: /*
002: * Copyright 2004-2007 the original author or authors.
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, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.springframework.webflow.core.collection;
017:
018: import java.io.IOException;
019: import java.io.ObjectInputStream;
020: import java.io.ObjectOutputStream;
021: import java.io.Serializable;
022: import java.util.Collection;
023: import java.util.HashMap;
024: import java.util.Map;
025:
026: import org.springframework.binding.collection.MapAccessor;
027: import org.springframework.core.style.StylerUtils;
028: import org.springframework.util.Assert;
029:
030: /**
031: * A generic, mutable attribute map with string keys.
032: *
033: * @author Keith Donald
034: */
035: public class LocalAttributeMap implements MutableAttributeMap,
036: Serializable {
037:
038: /**
039: * The backing map storing the attributes.
040: */
041: private Map attributes;
042:
043: /**
044: * A helper for accessing attributes. Marked transient and restored on
045: * deserialization.
046: */
047: private transient MapAccessor attributeAccessor;
048:
049: /**
050: * Creates a new attribute map, initially empty.
051: */
052: public LocalAttributeMap() {
053: initAttributes(createTargetMap());
054: }
055:
056: /**
057: * Creates a new attribute map, initially empty.
058: * @param size the initial size
059: * @param loadFactor the load factor
060: */
061: public LocalAttributeMap(int size, int loadFactor) {
062: initAttributes(createTargetMap(size, loadFactor));
063: }
064:
065: /**
066: * Creates a new attribute map with a single entry.
067: */
068: public LocalAttributeMap(String attributeName, Object attributeValue) {
069: initAttributes(createTargetMap(1, 1));
070: put(attributeName, attributeValue);
071: }
072:
073: /**
074: * Creates a new attribute map wrapping the specified map.
075: */
076: public LocalAttributeMap(Map map) {
077: Assert.notNull(map, "The target map is required");
078: initAttributes(map);
079: }
080:
081: // implementing attribute map
082:
083: public Map asMap() {
084: return attributeAccessor.asMap();
085: }
086:
087: public int size() {
088: return attributes.size();
089: }
090:
091: public Object get(String attributeName) {
092: return attributes.get(attributeName);
093: }
094:
095: public boolean isEmpty() {
096: return attributes.isEmpty();
097: }
098:
099: public boolean contains(String attributeName) {
100: return attributes.containsKey(attributeName);
101: }
102:
103: public boolean contains(String attributeName, Class requiredType)
104: throws IllegalArgumentException {
105: return attributeAccessor.containsKey(attributeName,
106: requiredType);
107: }
108:
109: public Object get(String attributeName, Object defaultValue) {
110: return attributeAccessor.get(attributeName, defaultValue);
111: }
112:
113: public Object get(String attributeName, Class requiredType)
114: throws IllegalArgumentException {
115: return attributeAccessor.get(attributeName, requiredType);
116: }
117:
118: public Object get(String attributeName, Class requiredType,
119: Object defaultValue) throws IllegalStateException {
120: return attributeAccessor.get(attributeName, requiredType,
121: defaultValue);
122: }
123:
124: public Object getRequired(String attributeName)
125: throws IllegalArgumentException {
126: return attributeAccessor.getRequired(attributeName);
127: }
128:
129: public Object getRequired(String attributeName, Class requiredType)
130: throws IllegalArgumentException {
131: return attributeAccessor.getRequired(attributeName,
132: requiredType);
133: }
134:
135: public String getString(String attributeName)
136: throws IllegalArgumentException {
137: return attributeAccessor.getString(attributeName);
138: }
139:
140: public String getString(String attributeName, String defaultValue)
141: throws IllegalArgumentException {
142: return attributeAccessor.getString(attributeName, defaultValue);
143: }
144:
145: public String getRequiredString(String attributeName)
146: throws IllegalArgumentException {
147: return attributeAccessor.getRequiredString(attributeName);
148: }
149:
150: public Collection getCollection(String attributeName)
151: throws IllegalArgumentException {
152: return attributeAccessor.getCollection(attributeName);
153: }
154:
155: public Collection getCollection(String attributeName,
156: Class requiredType) throws IllegalArgumentException {
157: return attributeAccessor.getCollection(attributeName,
158: requiredType);
159: }
160:
161: public Collection getRequiredCollection(String attributeName)
162: throws IllegalArgumentException {
163: return attributeAccessor.getRequiredCollection(attributeName);
164: }
165:
166: public Collection getRequiredCollection(String attributeName,
167: Class requiredType) throws IllegalArgumentException {
168: return attributeAccessor.getRequiredCollection(attributeName,
169: requiredType);
170: }
171:
172: public Object[] getArray(String attributeName, Class requiredType)
173: throws IllegalArgumentException {
174: return attributeAccessor.getArray(attributeName, requiredType);
175: }
176:
177: public Object[] getRequiredArray(String attributeName,
178: Class requiredType) throws IllegalArgumentException {
179: return attributeAccessor.getRequiredArray(attributeName,
180: requiredType);
181: }
182:
183: public Number getNumber(String attributeName, Class requiredType)
184: throws IllegalArgumentException {
185: return attributeAccessor.getNumber(attributeName, requiredType);
186: }
187:
188: public Number getNumber(String attributeName, Class requiredType,
189: Number defaultValue) throws IllegalArgumentException {
190: return attributeAccessor.getNumber(attributeName, requiredType,
191: defaultValue);
192: }
193:
194: public Number getRequiredNumber(String attributeName,
195: Class requiredType) throws IllegalArgumentException {
196: return attributeAccessor.getRequiredNumber(attributeName,
197: requiredType);
198: }
199:
200: public Integer getInteger(String attributeName)
201: throws IllegalArgumentException {
202: return attributeAccessor.getInteger(attributeName);
203: }
204:
205: public Integer getInteger(String attributeName, Integer defaultValue)
206: throws IllegalArgumentException {
207: return attributeAccessor
208: .getInteger(attributeName, defaultValue);
209: }
210:
211: public Integer getRequiredInteger(String attributeName)
212: throws IllegalArgumentException {
213: return attributeAccessor.getRequiredInteger(attributeName);
214: }
215:
216: public Long getLong(String attributeName)
217: throws IllegalArgumentException {
218: return attributeAccessor.getLong(attributeName);
219: }
220:
221: public Long getLong(String attributeName, Long defaultValue)
222: throws IllegalArgumentException {
223: return attributeAccessor.getLong(attributeName, defaultValue);
224: }
225:
226: public Long getRequiredLong(String attributeName)
227: throws IllegalArgumentException {
228: return attributeAccessor.getRequiredLong(attributeName);
229: }
230:
231: public Boolean getBoolean(String attributeName)
232: throws IllegalArgumentException {
233: return attributeAccessor.getBoolean(attributeName);
234: }
235:
236: public Boolean getBoolean(String attributeName, Boolean defaultValue)
237: throws IllegalArgumentException {
238: return attributeAccessor
239: .getBoolean(attributeName, defaultValue);
240: }
241:
242: public Boolean getRequiredBoolean(String attributeName)
243: throws IllegalArgumentException {
244: return attributeAccessor.getRequiredBoolean(attributeName);
245: }
246:
247: public AttributeMap union(AttributeMap attributes) {
248: if (attributes == null) {
249: return new LocalAttributeMap(getMapInternal());
250: } else {
251: Map map = createTargetMap();
252: map.putAll(getMapInternal());
253: map.putAll(attributes.asMap());
254: return new LocalAttributeMap(map);
255: }
256: }
257:
258: // implementing MutableAttributeMap
259:
260: public Object put(String attributeName, Object attributeValue) {
261: return getMapInternal().put(attributeName, attributeValue);
262: }
263:
264: public MutableAttributeMap putAll(AttributeMap attributes) {
265: if (attributes == null) {
266: return this ;
267: }
268: getMapInternal().putAll(attributes.asMap());
269: return this ;
270: }
271:
272: public Object remove(String attributeName) {
273: return getMapInternal().remove(attributeName);
274: }
275:
276: public MutableAttributeMap clear()
277: throws UnsupportedOperationException {
278: getMapInternal().clear();
279: return this ;
280: }
281:
282: public MutableAttributeMap replaceWith(AttributeMap attributes)
283: throws UnsupportedOperationException {
284: clear();
285: putAll(attributes);
286: return this ;
287: }
288:
289: // helpers for subclasses
290:
291: /**
292: * Initializes this attribute map.
293: * @param attributes the attributes
294: */
295: protected void initAttributes(Map attributes) {
296: this .attributes = attributes;
297: attributeAccessor = new MapAccessor(this .attributes);
298: }
299:
300: /**
301: * Returns the wrapped, modifiable map implementation.
302: */
303: protected Map getMapInternal() {
304: return attributes;
305: }
306:
307: // helpers
308:
309: /**
310: * Factory method that returns the target map storing the data in this
311: * attribute map.
312: * @return the target map
313: */
314: protected Map createTargetMap() {
315: return new HashMap();
316: }
317:
318: /**
319: * Factory method that returns the target map storing the data in this
320: * attribute map.
321: * @param size the initial size of the map
322: * @param loadFactor the load factor
323: * @return the target map
324: */
325: protected Map createTargetMap(int size, int loadFactor) {
326: return new HashMap(size, loadFactor);
327: }
328:
329: public boolean equals(Object o) {
330: if (!(o instanceof LocalAttributeMap)) {
331: return false;
332: }
333: LocalAttributeMap other = (LocalAttributeMap) o;
334: return getMapInternal().equals(other.getMapInternal());
335: }
336:
337: public int hashCode() {
338: return getMapInternal().hashCode();
339: }
340:
341: // custom serialization
342:
343: private void writeObject(ObjectOutputStream out) throws IOException {
344: out.defaultWriteObject();
345: }
346:
347: private void readObject(ObjectInputStream in) throws IOException,
348: ClassNotFoundException {
349: in.defaultReadObject();
350: attributeAccessor = new MapAccessor(attributes);
351: }
352:
353: public String toString() {
354: return StylerUtils.style(attributes);
355: }
356: }
|