import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
public abstract class AbstractBuilder<T> {
private final Class<T> beanClass;
private final BeanInfo beanInfo;
private final Map<String, Object> propertyMap;
/**
* {@link java.lang.Object Object}
*
* @param beanClass
*/
protected AbstractBuilder(final Class<T> beanClass){
super();
this.beanClass = beanClass;
try{
this.beanInfo = Introspector.getBeanInfo(beanClass);
this.propertyMap = new HashMap<String, Object>();
} catch(final IntrospectionException e){
throw new IllegalStateException(e);
}
}
public final T build(){
try{
final T bean = this.beanClass.newInstance();
for(final PropertyDescriptor descriptor : this.beanInfo
.getPropertyDescriptors()){
final String propertyName = descriptor.getName();
if(this.propertyMap.containsKey(propertyName)){
descriptor.getWriteMethod()//
.invoke(bean, this.propertyMap.get(propertyName));
}
}
return bean;
// CATCH:OFF
} catch(final RuntimeException e){
// CATCH:ON
throw new IllegalStateException(e);
} catch(final IllegalAccessException e){
throw new IllegalStateException(e);
} catch(final InvocationTargetException e){
throw new IllegalStateException(e);
} catch(final InstantiationException e){
throw new IllegalStateException(e);
}
}
@SuppressWarnings("unchecked")
protected final void addPropertyListItem(final String name,
final Object value){
final Object property = this.propertyMap.get(name);
Preconditions.checkState(property == null || property instanceof List,
"Expected property " + name + "to be of type List, but was "
+ (property == null ? null : property.getClass()));
if(property == null){
propertyMap.put(name, Lists.newArrayList(value));
} else{
((List<Object>) property).add(value);
}
}
protected final void setProperty(final String name, final Object value){
this.propertyMap.put(name, value);
}
}