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 */ 016package org.joda.beans; 017 018import java.lang.annotation.Annotation; 019import java.lang.reflect.Type; 020import java.util.List; 021import java.util.NoSuchElementException; 022 023import org.joda.convert.StringConvert; 024 025/** 026 * A meta-property, defining those aspects of a property which are not specific 027 * to a particular bean, such as the property type and name. 028 * 029 * @param <P> the type of the property content 030 * @author Stephen Colebourne 031 */ 032public interface MetaProperty<P> extends BeanQuery<P> { 033 034 /** 035 * Creates a property that binds this meta-property to a specific bean. 036 * 037 * @param bean the bean to create the property for, not null 038 * @return the property, not null 039 */ 040 Property<P> createProperty(Bean bean); 041 042 //----------------------------------------------------------------------- 043 /** 044 * Gets the meta-bean which owns this meta-property. 045 * <p> 046 * Each meta-property is fully owned by a single bean. 047 * 048 * @return the meta-bean, not null 049 */ 050 MetaBean metaBean(); 051 052 /** 053 * Gets the property name. 054 * <p> 055 * The JavaBean style methods getFoo() and setFoo() will lead to a property 056 * name of 'foo' and so on. 057 * 058 * @return the name of the property, not empty 059 */ 060 String name(); 061 062 /** 063 * Get the type that declares the property, represented as a {@code Class}. 064 * 065 * @return the type declaring the property, not null 066 */ 067 Class<?> declaringType(); 068 069 /** 070 * Get the type of the property represented as a {@code Class}. 071 * 072 * @return the type of the property, not null 073 */ 074 Class<P> propertyType(); 075 076 /** 077 * Gets the generic types of the property. 078 * <p> 079 * This provides access to the generic type declared in the source code. 080 * 081 * @return the full generic type of the property, unmodifiable, not null 082 */ 083 Type propertyGenericType(); 084 085 /** 086 * Gets whether the property is read-only, read-write or write-only. 087 * 088 * @return the property read-write type, not null 089 */ 090 PropertyReadWrite readWrite(); 091 092 //----------------------------------------------------------------------- 093 /** 094 * Gets the annotations of the property. 095 * 096 * @return the annotations, unmodifiable, not null 097 */ 098 List<Annotation> annotations(); 099 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}