1 /*
2 * Copyright 2001-2013 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.lang.annotation.Annotation;
19 import java.lang.reflect.Type;
20 import java.util.List;
21 import java.util.NoSuchElementException;
22
23 import org.joda.convert.StringConvert;
24
25 /**
26 * A meta-property, defining those aspects of a property which are not specific
27 * to a particular bean, such as the property type and name.
28 *
29 * @param <P> the type of the property content
30 * @author Stephen Colebourne
31 */
32 public interface MetaProperty<P> extends BeanQuery<P> {
33
34 /**
35 * Creates a property that binds this meta-property to a specific bean.
36 *
37 * @param bean the bean to create the property for, not null
38 * @return the property, not null
39 */
40 Property<P> createProperty(Bean bean);
41
42 //-----------------------------------------------------------------------
43 /**
44 * Gets the meta-bean which owns this meta-property.
45 * <p>
46 * Each meta-property is fully owned by a single bean.
47 *
48 * @return the meta-bean, not null
49 */
50 MetaBean metaBean();
51
52 /**
53 * Gets the property name.
54 * <p>
55 * The JavaBean style methods getFoo() and setFoo() will lead to a property
56 * name of 'foo' and so on.
57 *
58 * @return the name of the property, not empty
59 */
60 String name();
61
62 /**
63 * Get the type that declares the property, represented as a {@code Class}.
64 *
65 * @return the type declaring the property, not null
66 */
67 Class<?> declaringType();
68
69 /**
70 * Get the type of the property represented as a {@code Class}.
71 *
72 * @return the type of the property, not null
73 */
74 Class<P> propertyType();
75
76 /**
77 * Gets the generic types of the property.
78 * <p>
79 * This provides access to the generic type declared in the source code.
80 *
81 * @return the full generic type of the property, unmodifiable, not null
82 */
83 Type propertyGenericType();
84
85 /**
86 * Gets whether the property is read-only, read-write or write-only.
87 *
88 * @return the property read-write type, not null
89 */
90 PropertyReadWrite readWrite();
91
92 //-----------------------------------------------------------------------
93 /**
94 * Gets the annotations of the property.
95 *
96 * @return the annotations, unmodifiable, not null
97 */
98 List<Annotation> annotations();
99
100 /**
101 * Gets a specified annotation of the property.
102 *
103 * @param <A> the annotation type
104 * @param annotation the annotation class to find, not null
105 * @return the annotation, not null
106 * @throws NoSuchElementException if the annotation is not specified
107 */
108 <A extends Annotation> A annotation(Class<A> annotation);
109
110 //-----------------------------------------------------------------------
111 /**
112 * Gets the value of the property for the specified bean.
113 * <p>
114 * For a standard JavaBean, this is equivalent to calling <code>getFoo()</code> on the bean.
115 * Alternate implementations may perform any logic to obtain the value.
116 *
117 * @param bean the bean to query, not null
118 * @return the value of the property on the specified bean, may be null
119 * @throws ClassCastException if the bean is of an incorrect type
120 * @throws UnsupportedOperationException if the property is write-only
121 */
122 P get(Bean bean);
123
124 /**
125 * Sets the value of the property on the specified bean.
126 * <p>
127 * The value must be of the correct type for the property.
128 * For a standard JavaBean, this is equivalent to calling <code>setFoo()</code> on the bean.
129 * Alternate implementations may perform any logic to change the value.
130 *
131 * @param bean the bean to update, not null
132 * @param value the value to set into the property on the specified bean, may be null
133 * @throws ClassCastException if the bean is of an incorrect type
134 * @throws ClassCastException if the value is of an invalid type for the property
135 * @throws UnsupportedOperationException if the property is read-only
136 * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
137 */
138 void set(Bean bean, Object value);
139
140 /**
141 * Sets the value of the property on the associated bean and returns the previous value.
142 * <p>
143 * The value must be of the correct type for the property.
144 * This is a combination of the {@code get} and {@code set} methods that matches the definition
145 * of {@code put} in a {@code Map}.
146 *
147 * @param bean the bean to update, not null
148 * @param value the value to set into the property on the specified bean, may be null
149 * @return the old value of the property, may be null
150 * @throws ClassCastException if the bean is of an incorrect type
151 * @throws ClassCastException if the value is of an invalid type for the property
152 * @throws UnsupportedOperationException if the property is read-only
153 * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
154 */
155 P put(Bean bean, Object value);
156
157 //-----------------------------------------------------------------------
158 /**
159 * Gets the value of the property for the specified bean converted to a string.
160 * <p>
161 * This converts the result of {@link #get(Bean)} to a standard format string.
162 * Conversion uses Joda-Convert.
163 * Not all object types can be converted to a string, see Joda-Convert.
164 * <p>
165 * For a standard JavaBean, this is equivalent to calling <code>getFoo()</code> on the bean.
166 * Alternate implementations may perform any logic to obtain the value.
167 *
168 * @param bean the bean to query, not null
169 * @return the value of the property on the specified bean, may be null
170 * @throws ClassCastException if the bean is of an incorrect type
171 * @throws UnsupportedOperationException if the property is write-only
172 * @throws RuntimeException if the value cannot be converted to a string (use appropriate subclasses)
173 */
174 String getString(Bean bean);
175
176 /**
177 * Gets the value of the property for the specified bean converted to a string.
178 * <p>
179 * This converts the result of {@link #get(Bean)} to a standard format string using the supplied converter.
180 * Not all object types can be converted to a string, see Joda-Convert.
181 * <p>
182 * For a standard JavaBean, this is equivalent to calling <code>getFoo()</code> on the bean.
183 * Alternate implementations may perform any logic to obtain the value.
184 *
185 * @param bean the bean to query, not null
186 * @param stringConvert the converter to use, not null
187 * @return the value of the property on the specified bean, may be null
188 * @throws ClassCastException if the bean is of an incorrect type
189 * @throws UnsupportedOperationException if the property is write-only
190 * @throws RuntimeException if the value cannot be converted to a string (use appropriate subclasses)
191 */
192 String getString(Bean bean, StringConvert stringConvert);
193
194 /**
195 * Sets the value of the property on the specified bean from a string by conversion.
196 * <p>
197 * This converts the string to the correct type for the property and then sets it
198 * using {@link #set(Bean, Object)}. Conversion uses Joda-Convert.
199 *
200 * @param bean the bean to update, not null
201 * @param value the value to set into the property on the specified bean, may be null
202 * @throws ClassCastException if the bean is of an incorrect type
203 * @throws ClassCastException if the value is of an invalid type for the property
204 * @throws UnsupportedOperationException if the property is read-only
205 * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
206 */
207 void setString(Bean bean, String value);
208
209 /**
210 * Sets the value of the property on the specified bean from a string by conversion.
211 * <p>
212 * This converts the string to the correct type for the property using the supplied converter and then sets it
213 * using {@link #set(Bean, Object)}.
214 *
215 * @param bean the bean to update, not null
216 * @param value the value to set into the property on the specified bean, may be null
217 * @param stringConvert the converter, not null
218 * @throws ClassCastException if the bean is of an incorrect type
219 * @throws ClassCastException if the value is of an invalid type for the property
220 * @throws UnsupportedOperationException if the property is read-only
221 * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
222 */
223 void setString(Bean bean, String value, StringConvert stringConvert);
224
225 //-----------------------------------------------------------------------
226 /**
227 * Checks if this meta-property equals another.
228 * <p>
229 * This compares the property name and declaring type.
230 * It does not compare the property or bean types.
231 *
232 * @param obj the other meta-property, null returns false
233 * @return true if equal
234 */
235 @Override
236 boolean equals(Object obj);
237
238 /**
239 * Returns a suitable hash code.
240 *
241 * @return the hash code
242 */
243 @Override
244 int hashCode();
245
246 }