001 /*
002 * Copyright 2001-2010 Stephen Colebourne
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.joda.beans;
017
018 import java.util.Map;
019
020 /**
021 * A meta-property using a {@code Map} for storage.
022 * <p>
023 * This meta-property uses a {@code Map} instead of a JavaBean to store the property.
024 *
025 * @author Stephen Colebourne
026 */
027 public class MapMetaProperty<T> implements MetaProperty<Map<String, T>, T> {
028
029 /** The map key, also known as the property name. */
030 private final String key;
031
032 /**
033 * Constructor.
034 *
035 * @param propertyName the property name
036 */
037 public MapMetaProperty(String propertyName) {
038 super();
039 if (propertyName == null || propertyName.length() == 0) {
040 throw new IllegalArgumentException("Invalid property name: " + propertyName);
041 }
042 key = propertyName;
043 }
044
045 //-----------------------------------------------------------------------
046 /**
047 * Creates a property that binds this meta property to a specific bean.
048 *
049 * @param bean the bean to create the bound property for
050 * @return the bound property
051 */
052 public Property<Map<String, T>, T> createProperty(Map<String, T> bean) {
053 return StandardProperty.of(bean, this);
054 }
055
056 /**
057 * Gets the property name.
058 *
059 * @return the name of the property
060 */
061 public String name() {
062 return key;
063 }
064
065 /**
066 * Get the type of the property represented as a Class.
067 *
068 * @return the type of the property
069 */
070 public Class<T> propertyClass() {
071 // isn't erasure horrible
072 return null;
073 }
074
075 /**
076 * Get the type of the bean represented as a Class.
077 *
078 * @return the type of the bean
079 */
080 @SuppressWarnings("unchecked")
081 public Class<Map<String, T>> beanClass() {
082 // if you think erasure is great, try fixing this
083 return (Class<Map<String, T>>) (Class) Map.class;
084 }
085
086 /**
087 * Gets whether the property is read-write, read-only or write-only.
088 *
089 * @return the property read-write type
090 */
091 public ReadWriteProperty readWrite() {
092 return ReadWriteProperty.READ_WRITE;
093 }
094
095 //-----------------------------------------------------------------------
096 /**
097 * Gets the value of the bound property for the provided bean.
098 * <p>
099 * 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 }