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.direct; 017 018import java.util.NoSuchElementException; 019import java.util.Set; 020 021import org.joda.beans.Bean; 022import org.joda.beans.JodaBeanUtils; 023import org.joda.beans.Property; 024 025/** 026 * A bean implementation designed for use by the code generator. 027 * <p> 028 * This implementation uses direct access via {@link #propertyGet(String, boolean)} and 029 * {@link #propertySet(String, Object, boolean)} to avoid reflection. 030 * <p> 031 * For code generation, the bean must directly extend this class and have a 032 * no-arguments constructor. 033 * 034 * @author Stephen Colebourne 035 */ 036public abstract class DirectBean implements Bean { 037 038 @Override 039 public <R> Property<R> property(String propertyName) { 040 return metaBean().<R>metaProperty(propertyName).createProperty(this); 041 } 042 043 @Override 044 public Set<String> propertyNames() { 045 return metaBean().metaPropertyMap().keySet(); 046 } 047 048 //------------------------------------------------------------------------- 049 /** 050 * Gets the value of the property. 051 * 052 * @param propertyName the property name, not null 053 * @param quiet true to return null if unable to read 054 * @return the value of the property, may be null 055 * @throws NoSuchElementException if the property name is invalid 056 */ 057 protected Object propertyGet(String propertyName, boolean quiet) { 058 throw new NoSuchElementException("Unknown property: " + propertyName); 059 } 060 061 /** 062 * Sets the value of the property. 063 * 064 * @param propertyName the property name, not null 065 * @param value the value of the property, may be null 066 * @param quiet true to take no action if unable to write 067 * @throws NoSuchElementException if the property name is invalid 068 */ 069 protected void propertySet(String propertyName, Object value, boolean quiet) { 070 throw new NoSuchElementException("Unknown property: " + propertyName); 071 } 072 073 /** 074 * Validates the values of the properties. 075 * 076 * @throws RuntimeException if a property is invalid 077 */ 078 protected void validate() { 079 } 080 081 //----------------------------------------------------------------------- 082 @Override 083 public boolean equals(Object obj) { 084 if (obj == this) { 085 return true; 086 } 087 if (obj != null && getClass() == obj.getClass()) { 088 DirectBean other = (DirectBean) obj; 089 for (String name : propertyNames()) { 090 Object value1 = propertyGet(name, true); 091 Object value2 = other.propertyGet(name, true); 092 if (JodaBeanUtils.equal(value1, value2) == false) { 093 return false; 094 } 095 } 096 return true; 097 } 098 return false; 099 } 100 101 @Override 102 public int hashCode() { 103 int hash = getClass().hashCode(); 104 Set<String> names = propertyNames(); 105 for (String name : names) { 106 Object value = propertyGet(name, true); 107 hash += JodaBeanUtils.hashCode(value); 108 } 109 return hash; 110 } 111 112 @Override 113 public String toString() { 114 Set<String> names = propertyNames(); 115 StringBuilder buf = new StringBuilder((names.size()) * 32 + 32); 116 buf.append(getClass().getSimpleName()); 117 buf.append('{'); 118 if (names.size() > 0) { 119 for (String name : names) { 120 Object value = propertyGet(name, true); 121 buf.append(name).append('=').append(value).append(',').append(' '); 122 } 123 buf.setLength(buf.length() - 2); 124 } 125 buf.append('}'); 126 return buf.toString(); 127 } 128 129}