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.impl; 017 018import org.joda.beans.Bean; 019import org.joda.beans.MetaProperty; 020import org.joda.beans.Property; 021 022/** 023 * A property that binds a {@code Bean} to a {@code MetaProperty}. 024 * <p> 025 * This is the standard implementation of a property. 026 * It defers the strategy of getting and setting the value to the meta-property. 027 * <p> 028 * This implementation is also a map entry to aid performance in maps. 029 * 030 * @param <P> the type of the property content 031 * @author Stephen Colebourne 032 */ 033public final class BasicProperty<P> implements Property<P> { 034 035 /** The bean that the property is bound to. */ 036 private final Bean bean; 037 /** The meta-property that the property is bound to. */ 038 private final MetaProperty<P> metaProperty; 039 040 /** 041 * Factory to create a property avoiding duplicate generics. 042 * 043 * @param <P> the property type 044 * @param bean the bean that the property is bound to, not null 045 * @param metaProperty the meta property, not null 046 * @return the property, not null 047 */ 048 public static <P> BasicProperty<P> of(Bean bean, MetaProperty<P> metaProperty) { 049 return new BasicProperty<P>(bean, metaProperty); 050 } 051 052 /** 053 * Creates a property binding the bean to the meta-property. 054 * 055 * @param bean the bean that the property is bound to, not null 056 * @param metaProperty the meta property, not null 057 */ 058 private BasicProperty(Bean bean, MetaProperty<P> metaProperty) { 059 if (bean == null) { 060 throw new NullPointerException("Bean must not be null"); 061 } 062 if (metaProperty == null) { 063 throw new NullPointerException("MetaProperty must not be null"); 064 } 065 this.bean = bean; 066 this.metaProperty = metaProperty; 067 } 068 069 //----------------------------------------------------------------------- 070 @SuppressWarnings("unchecked") 071 @Override 072 public <B extends Bean> B bean() { 073 return (B) bean; 074 } 075 076 @Override 077 public MetaProperty<P> metaProperty() { 078 return metaProperty; 079 } 080 081 @Override 082 public String name() { 083 return metaProperty.name(); 084 } 085 086 //----------------------------------------------------------------------- 087 @Override 088 public P get() { 089 return metaProperty.get(bean); 090 } 091 092 @Override 093 public void set(Object value) { 094 metaProperty.set(bean, value); 095 } 096 097 @Override 098 public P put(Object value) { 099 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}