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