001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.ioc.services;
014
015import org.apache.tapestry5.ioc.AnnotationProvider;
016
017import java.lang.reflect.Field;
018import java.lang.reflect.Method;
019
020/**
021 * Provides access to a single property within a class. Acts as an {@link org.apache.tapestry5.ioc.AnnotationProvider};
022 * when searching for annotations, the read method (if present) is checked first, followed by the write method, followed
023 * by the underlying field (when the property name matches the field name).
024 *
025 * Starting in release 5.2, this property may actually be a public field. In 5.3, it may be a public static field.
026 *
027 * @see org.apache.tapestry5.ioc.services.ClassPropertyAdapter
028 */
029@SuppressWarnings("unchecked")
030public interface PropertyAdapter extends AnnotationProvider
031{
032    /**
033     * Returns the name of the property (or public field).
034     */
035    String getName();
036
037    /**
038     * Returns true if the property is readable (i.e., has a getter method or is a public field).
039     */
040    boolean isRead();
041
042    /**
043     * Returns the method used to read the property, or null if the property is not readable (or is a public field).
044     */
045    public Method getReadMethod();
046
047    /**
048     * Returns true if the property is writeable (i.e., has a setter method or is a non-final field).
049     */
050    boolean isUpdate();
051
052    /**
053     * Returns the method used to update the property, or null if the property is not writeable (or a public field).
054     */
055    public Method getWriteMethod();
056
057    /**
058     * Reads the property value.
059     *
060     * @param instance to read from
061     * @throws UnsupportedOperationException if the property is write only
062     */
063    Object get(Object instance);
064
065    /**
066     * Updates the property value. The provided value must not be null if the property type is primitive, and must
067     * otherwise be of the proper type.
068     *
069     * @param instance to update
070     * @param value    new value for the property
071     * @throws UnsupportedOperationException if the property is read only
072     */
073    void set(Object instance, Object value);
074
075    /**
076     * Returns the type of the property.
077     */
078    Class getType();
079
080    /**
081     * Returns true if the return type of the read method is not the same as the property type. This can occur when the
082     * property has been defined using generics, in which case, the method's type may be Object when the property type
083     * is something more specific. This method is primarily used when generating runtime code related to the property.
084     */
085    boolean isCastRequired();
086
087    /**
088     * Returns the {@link org.apache.tapestry5.ioc.services.ClassPropertyAdapter} that provides access to other
089     * properties defined by the same class.
090     */
091    ClassPropertyAdapter getClassAdapter();
092
093    /**
094     * Returns the type of bean to which this property belongs. This is the same as
095     * {@link org.apache.tapestry5.ioc.services.ClassPropertyAdapter#getBeanType()}.
096     */
097    Class getBeanType();
098
099    /**
100     * Returns true if the property is actually a public field (possibly, a public static field).
101     *
102     * @since 5.2
103     */
104    boolean isField();
105
106    /**
107     * Returns the field if the property is a public field or null if the property is accessed via the read method.
108     *
109     * @since 5.2
110     */
111    Field getField();
112
113    /**
114     * The class in which the property (or public field) is defined.
115     *
116     * @since 5.2
117     */
118    Class getDeclaringClass();
119}