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    /**
019     * A property that is linked to a specific bean.
020     * <p>
021     * For a JavaBean, this will ultimately wrap a get/set method pair.
022     * Alternate implementations may perform any logic to obtain the value.
023     * 
024     * @param <P>  the type of the property content
025     * @author Stephen Colebourne
026     */
027    public interface Property<P> {
028    
029        /**
030         * Gets the bean which owns this property.
031         * <p>
032         * Each property is fully owned by a single bean.
033         * 
034         * @return the bean, not null
035         */
036        <B extends Bean> B bean();
037    
038        /**
039         * Gets the meta-property representing the parts of the property that are
040         * common across all instances, such as the name.
041         * 
042         * @return the meta-property, not null
043         */
044        MetaProperty<P> metaProperty();
045    
046        /**
047         * Gets the property name.
048         * <p>
049         * The JavaBean style methods getFoo() and setFoo() will lead to a property
050         * name of 'foo' and so on.
051         * 
052         * @return the name of the property, not empty
053         */
054        String name();
055    
056        //-----------------------------------------------------------------------
057        /**
058         * Gets the value of the property for the associated bean.
059         * <p>
060         * For a JavaBean, this is the equivalent to calling <code>getFoo()</code> on the bean itself.
061         * Alternate implementations may perform any logic to obtain the value.
062         * 
063         * @return the value of the property on the bound bean, may be null
064         * @throws UnsupportedOperationException if the property is write-only
065         */
066        P get();
067    
068        /**
069         * Sets the value of the property on the associated bean.
070         * <p>
071         * The value must be of the correct type for the property.
072         * See the meta-property for string conversion.
073         * For a standard JavaBean, this is equivalent to calling <code>setFoo()</code> on the bean.
074         * Alternate implementations may perform any logic to change the value.
075         * 
076         * @param value  the value to set into the property on the bean
077         * @throws ClassCastException if the value is of an invalid type for the property
078         * @throws UnsupportedOperationException if the property is read-only
079         * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
080         */
081        void set(Object value);
082    
083        /**
084         * Sets the value of the property on the associated bean and returns the previous value.
085         * <p>
086         * This is a combination of the {@code get} and {@code set} methods that matches the definition
087         * of {@code put} in a {@code Map}.
088         * 
089         * @param value  the value to set into the property on the bean
090         * @return the old value of the property, may be null
091         * @throws ClassCastException if the value is of an invalid type for the property
092         * @throws UnsupportedOperationException if the property is read-only
093         * @throws RuntimeException if the value is rejected by the property (use appropriate subclasses)
094         */
095        P put(Object value);
096    
097        //-----------------------------------------------------------------------
098        /**
099         * Checks if this property equals another.
100         * <p>
101         * This compares the meta-property and value.
102         * It does not consider the property or bean types.
103         * 
104         * @param obj  the other property, null returns false
105         * @return true if equal
106         */
107        @Override
108        boolean equals(Object obj);
109    
110        /**
111         * Returns a suitable hash code.
112         * 
113         * @return the hash code
114         */
115        @Override
116        int hashCode();
117    
118    }