View Javadoc

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.impl;
17  
18  import org.joda.beans.Bean;
19  import org.joda.beans.MetaProperty;
20  import org.joda.beans.Property;
21  
22  /**
23   * A property that binds a {@code Bean} to a {@code MetaProperty}.
24   * <p>
25   * This is the standard implementation of a property.
26   * It defers the strategy of getting and setting the value to the meta-property.
27   * <p>
28   * This implementation is also a map entry to aid performance in maps.
29   * 
30   * @param <P>  the type of the property content
31   * @author Stephen Colebourne
32   */
33  public final class BasicProperty<P> implements Property<P> {
34  
35      /** The bean that the property is bound to. */
36      private final Bean bean;
37      /** The meta-property that the property is bound to. */
38      private final MetaProperty<P> metaProperty;
39  
40      /**
41       * Factory to create a property avoiding duplicate generics.
42       * 
43       * @param <P>  the property type
44       * @param bean  the bean that the property is bound to, not null
45       * @param metaProperty  the meta property, not null
46       * @return the property, not null
47       */
48      public static <P> BasicProperty<P> of(Bean bean, MetaProperty<P> metaProperty) {
49          return new BasicProperty<P>(bean, metaProperty);
50      }
51  
52      /**
53       * Creates a property binding the bean to the meta-property.
54       * 
55       * @param bean  the bean that the property is bound to, not null
56       * @param metaProperty  the meta property, not null
57       */
58      private BasicProperty(Bean bean, MetaProperty<P> metaProperty) {
59          if (bean == null) {
60              throw new NullPointerException("Bean must not be null");
61          }
62          if (metaProperty == null) {
63              throw new NullPointerException("MetaProperty must not be null");
64          }
65          this.bean = bean;
66          this.metaProperty = metaProperty;
67      }
68  
69      //-----------------------------------------------------------------------
70      @SuppressWarnings("unchecked")
71      @Override
72      public <B extends Bean> B bean() {
73          return (B) bean;
74      }
75  
76      @Override
77      public MetaProperty<P> metaProperty() {
78          return metaProperty;
79      }
80  
81      @Override
82      public String name() {
83          return metaProperty.name();
84      }
85  
86      //-----------------------------------------------------------------------
87      @Override
88      public P get() {
89          return metaProperty.get(bean);
90      }
91  
92      @Override
93      public void set(Object value) {
94          metaProperty.set(bean, value);
95      }
96  
97      @Override
98      public P put(Object value) {
99          return metaProperty.put(bean, value);
100     }
101 
102     //-----------------------------------------------------------------------
103     @Override
104     public boolean equals(Object obj) {
105         if (obj == this) {
106             return true;
107         }
108         if (obj instanceof Property) {
109             Property<?> other = (Property<?>) obj;
110             if (metaProperty.equals(other.metaProperty())) {
111                 Object a = get();
112                 Object b = other.get();
113                 return a == null ? b == null : a.equals(b);
114             }
115         }
116         return false;
117     }
118 
119     @Override
120     public int hashCode() {
121         P value = get();
122         return metaProperty.hashCode() ^ (value == null ? 0 : value.hashCode());
123     }
124 
125     /**
126      * Returns a string that summarises the property.
127      * 
128      * @return a summary string, not null
129      */
130     @Override
131     public String toString() {
132         return metaProperty + "=" + get();
133     }
134 
135 }