001 /*
002 * Copyright 2001-2013 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.lang.annotation.Annotation;
019 import java.lang.reflect.Type;
020 import java.util.List;
021 import java.util.NoSuchElementException;
022
023 /**
024 * A meta-property, defining those aspects of a property which are not specific
025 * to a particular bean, such as the property type and name.
026 *
027 * @param <P> the type of the property content
028 * @author Stephen Colebourne
029 */
030 public interface MetaProperty<P> extends BeanQuery<P> {
031
032 /**
033 * Creates a property that binds this meta-property to a specific bean.
034 *
035 * @param bean the bean to create the property for, not null
036 * @return the property, not null
037 */
038 Property<P> createProperty(Bean bean);
039
040 //-----------------------------------------------------------------------
041 /**
042 * Gets the meta-bean which owns this meta-property.
043 * <p>
044 * Each meta-property is fully owned by a single bean.
045 *
046 * @return the meta-bean, not null
047 */
048 MetaBean metaBean();
049
050 /**
051 * Gets the property name.
052 * <p>
053 * The JavaBean style methods getFoo() and setFoo() will lead to a property
054 * name of 'foo' and so on.
055 *
056 * @return the name of the property, not empty
057 */
058 String name();
059
060 /**
061 * Get the type that declares the property, represented as a {@code Class}.
062 *
063 * @return the type declaring the property, not null
064 */
065 Class<?> declaringType();
066
067 /**
068 * Get the type of the property represented as a {@code Class}.
069 *
070 * @return the type of the property, not null
071 */
072 Class<P> propertyType();
073
074 /**
075 * Gets the generic types of the property.
076 * <p>
077 * This provides access to the generic type declared in the source code.
078 *
079 * @return the full generic type of the property, unmodifiable, not null
080 */
081 Type propertyGenericType();
082
083 /**
084 * Gets whether the property is read-only, read-write or write-only.
085 *
086 * @return the property read-write type, not null
087 */
088 PropertyReadWrite readWrite();
089
090 //-----------------------------------------------------------------------
091 /**
092 * Gets the annotations of the property.
093 *
094 * @return the annotations, unmodifiable, not null
095 */
096 List<Annotation> annotations();
097
098 /**
099 * Gets a specified annotation of the property.
100 *
101 * @return the annotation, not null
102 * @throws NoSuchElementException if the annotation is not specified
103 */
104 <A extends Annotation> A annotation(Class<A> annotation);
105
106 //-----------------------------------------------------------------------
107 /**
108 * Gets the value of the property for the specified bean.
109 * <p>
110 * For a standard JavaBean, this is equivalent to calling <code>getFoo()</code> on the bean.
111 * Alternate implementations may perform any logic to obtain the value.
112 *
113 * @param bean the bean to query, not null
114 * @return the value of the property on the specified bean, may be null
115 * @throws ClassCastException if the bean is of an incorrect type
116 * @throws UnsupportedOperationException if the property is write-only
117 */
118 P get(Bean bean);
119
120 /**
121 * Sets the value of the property on the specified bean.
122 * <p>
123 * The value must be of the correct type for the property.
124 * For a standard JavaBean, this is equivalent to calling <code>setFoo()</code> on the bean.
125 * Alternate implementations may perform any logic to change the value.
126 *
127 * @param bean the bean to update, not null
128 * @param value the value to set into the property on the specified bean, may be null
129 * @throws ClassCastException if the bean is of an incorrect type
130 * @throws ClassCastException if the value is of an invalid type for the property
131 * @throws UnsupportedOperationException if the property is read-only
132 * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
133 */
134 void set(Bean bean, Object value);
135
136 /**
137 * Sets the value of the property on the associated bean and returns the previous value.
138 * <p>
139 * The value must be of the correct type for the property.
140 * This is a combination of the {@code get} and {@code set} methods that matches the definition
141 * of {@code put} in a {@code Map}.
142 *
143 * @param bean the bean to update, not null
144 * @param value the value to set into the property on the specified bean, may be null
145 * @return the old value of the property, may be null
146 * @throws ClassCastException if the bean is of an incorrect type
147 * @throws ClassCastException if the value is of an invalid type for the property
148 * @throws UnsupportedOperationException if the property is read-only
149 * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
150 */
151 P put(Bean bean, Object value);
152
153 //-----------------------------------------------------------------------
154 /**
155 * Gets the value of the property for the specified bean converted to a string.
156 * <p>
157 * This converts the result of {@link #get(Bean)} to a standard format string.
158 * Conversion uses Joda-Convert.
159 * Not all object types can be converted to a string, see Joda-Convert.
160 * <p>
161 * For a standard JavaBean, this is equivalent to calling <code>getFoo()</code> on the bean.
162 * Alternate implementations may perform any logic to obtain the value.
163 *
164 * @param bean the bean to query, not null
165 * @return the value of the property on the specified bean, may be null
166 * @throws ClassCastException if the bean is of an incorrect type
167 * @throws UnsupportedOperationException if the property is write-only
168 * @throws RuntimeException if the value cannot be converted to a string (use appropriate subclasses)
169 */
170 String getString(Bean bean);
171
172 /**
173 * Sets the value of the property on the specified bean from a string by conversion.
174 * <p>
175 * This converts the string to the correct type for the property and then sets it
176 * using {@link #set(Bean, Object)}. Conversion uses Joda-Convert.
177 *
178 * @param bean the bean to update, not null
179 * @param value the value to set into the property on the specified bean, may be null
180 * @throws ClassCastException if the bean is of an incorrect type
181 * @throws ClassCastException if the value is of an invalid type for the property
182 * @throws UnsupportedOperationException if the property is read-only
183 * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
184 */
185 void setString(Bean bean, String value);
186
187 //-----------------------------------------------------------------------
188 /**
189 * Checks if this meta-property equals another.
190 * <p>
191 * This compares the property name and declaring type.
192 * It does not compare the property or bean types.
193 *
194 * @param obj the other meta-property, null returns false
195 * @return true if equal
196 */
197 @Override
198 boolean equals(Object obj);
199
200 /**
201 * Returns a suitable hash code.
202 *
203 * @return the hash code
204 */
205 @Override
206 int hashCode();
207
208 }