1 /*
2 * Copyright 2001-2010 Stephen Colebourne
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.joda.beans;
17
18 import java.util.Map;
19
20 /**
21 * A meta-property using a {@code Map} for storage.
22 * <p>
23 * This meta-property uses a {@code Map} instead of a JavaBean to store the property.
24 *
25 * @author Stephen Colebourne
26 */
27 public class MapMetaProperty<T> implements MetaProperty<Map<String, T>, T> {
28
29 /** The map key, also known as the property name. */
30 private final String key;
31
32 /**
33 * Constructor.
34 *
35 * @param propertyName the property name
36 */
37 public MapMetaProperty(String propertyName) {
38 super();
39 if (propertyName == null || propertyName.length() == 0) {
40 throw new IllegalArgumentException("Invalid property name: " + propertyName);
41 }
42 key = propertyName;
43 }
44
45 //-----------------------------------------------------------------------
46 /**
47 * Creates a property that binds this meta property to a specific bean.
48 *
49 * @param bean the bean to create the bound property for
50 * @return the bound property
51 */
52 public Property<Map<String, T>, T> createProperty(Map<String, T> bean) {
53 return StandardProperty.of(bean, this);
54 }
55
56 /**
57 * Gets the property name.
58 *
59 * @return the name of the property
60 */
61 public String name() {
62 return key;
63 }
64
65 /**
66 * Get the type of the property represented as a Class.
67 *
68 * @return the type of the property
69 */
70 public Class<T> propertyClass() {
71 // isn't erasure horrible
72 return null;
73 }
74
75 /**
76 * Get the type of the bean represented as a Class.
77 *
78 * @return the type of the bean
79 */
80 @SuppressWarnings("unchecked")
81 public Class<Map<String, T>> beanClass() {
82 // if you think erasure is great, try fixing this
83 return (Class<Map<String, T>>) (Class) Map.class;
84 }
85
86 /**
87 * Gets whether the property is read-write, read-only or write-only.
88 *
89 * @return the property read-write type
90 */
91 public ReadWriteProperty readWrite() {
92 return ReadWriteProperty.READ_WRITE;
93 }
94
95 //-----------------------------------------------------------------------
96 /**
97 * Gets the value of the bound property for the provided bean.
98 * <p>
99 * This is the equivalent to calling <code>getFoo()</code> on the bean itself.
100 * However some implementations of this interface may not require an actual get method.
101 *
102 * @param bean the bean to query, not null
103 * @return the value of the property on the bound bean
104 * @throws UnsupportedOperationException if the property is write-only
105 */
106 public T get(Map<String, T> bean) {
107 return bean.get(key);
108 }
109
110 /**
111 * Sets the value of the bound property on the provided bean.
112 * <p>
113 * This is the equivalent to calling <code>setFoo()</code> on the bean itself.
114 * However some implementations of this interface may not require an actual set method.
115 *
116 * @param bean the bean to update, not null
117 * @param value the value to set into the property on the bound bean
118 * @throws UnsupportedOperationException if the property is read-only
119 */
120 public void set(Map<String, T> bean, T value) {
121 bean.put(key, value);
122 }
123
124 //-----------------------------------------------------------------------
125 /**
126 * Returns a debugging string.
127 *
128 * @return a debugging string
129 */
130 @Override
131 public String toString() {
132 return "MetaProperty:" + name();
133 }
134
135 }