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 java.util.Map; 019import java.util.Map.Entry; 020 021import org.joda.beans.Bean; 022import org.joda.beans.BeanBuilder; 023import org.joda.beans.MetaProperty; 024 025/** 026 * Basic implementation of {@code BeanBuilder} that wraps a real bean. 027 * <p> 028 * This approach saves creating a temporary map, but is only suitable if the 029 * bean has a no-arg constructor and allows properties to be set. 030 * 031 * @author Stephen Colebourne 032 * @param <T> the bean type 033 */ 034public class BasicBeanBuilder<T extends Bean> implements BeanBuilder<T> { 035 036 /** 037 * The actual target bean. 038 */ 039 private final T bean; 040 041 /** 042 * Constructs the builder wrapping the target bean. 043 * 044 * @param bean the target bean, not null 045 */ 046 public BasicBeanBuilder(T bean) { 047 if (bean == null) { 048 throw new NullPointerException("Bean must not be null"); 049 } 050 this.bean = bean; 051 } 052 053 //----------------------------------------------------------------------- 054 /** 055 * Gets the target bean. 056 * 057 * @return the target bean, not null 058 */ 059 protected T getTargetBean() { 060 return bean; 061 } 062 063 /** 064 * Gets the current value of the property. 065 * 066 * @param propertyName the property name, not null 067 * @return the current value in the builder, null if not found or value is null 068 */ 069 protected BeanBuilder<T> get(String propertyName) { 070 bean.property(propertyName).get(); 071 return this; 072 } 073 074 //----------------------------------------------------------------------- 075 @Override 076 public BeanBuilder<T> set(String propertyName, Object value) { 077 return set(bean.metaBean().metaProperty(propertyName), value); 078 } 079 080 @Override 081 public BeanBuilder<T> set(MetaProperty<?> property, Object value) { 082 property.set(bean, value); 083 return this; 084 } 085 086 @Override 087 public BeanBuilder<T> setString(String propertyName, String value) { 088 return setString(bean.metaBean().metaProperty(propertyName), value); 089 } 090 091 @Override 092 public BeanBuilder<T> setString(MetaProperty<?> property, String value) { 093 property.setString(bean, value); 094 return this; 095 } 096 097 @Override 098 public BeanBuilder<T> setAll(Map<String, ? extends Object> propertyValueMap) { 099 for (Entry<String, ? extends Object> entry : propertyValueMap.entrySet()) { 100 set(entry.getKey(), entry.getValue()); 101 } 102 return this; 103 } 104 105 @Override 106 public T build() { 107 validate(bean); 108 return bean; 109 } 110 111 /** 112 * Hook to allow a subclass to validate the bean. 113 * 114 * @param bean the bean to validate, not null 115 */ 116 protected void validate(T bean) { 117 // override to validate the bean 118 } 119 120 //----------------------------------------------------------------------- 121 /** 122 * Returns a string that summarises the builder. 123 * 124 * @return a summary string, not null 125 */ 126 @Override 127 public String toString() { 128 return "BeanBuilder for " + bean.metaBean().beanName(); 129 } 130 131}