com.feilong.lib.beanutils.BasicDynaBean Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of feilong Show documentation
Show all versions of feilong Show documentation
feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.feilong.lib.beanutils;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.DynaBean;
/**
*
* Minimal implementation of the DynaBean
interface. Can be
* used as a convenience base class for more sophisticated implementations.
*
*
*
* IMPLEMENTATION NOTE - Instances of this class that are
* accessed from multiple threads simultaneously need to be synchronized.
*
*
*
* IMPLEMENTATION NOTE - Instances of this class can be
* successfully serialized and deserialized ONLY if all
* property values are Serializable
.
*
*
* @version $Id$
*/
public class BasicDynaBean implements DynaBean,Serializable{
// ---------------------------------------------------------- Constructors
/**
*
*/
private static final long serialVersionUID = -345115896914191203L;
/**
* Construct a new DynaBean
associated with the specified
* DynaClass
instance.
*
* @param dynaClass
* The DynaClass we are associated with
*/
public BasicDynaBean(final DynaClass dynaClass){
super();
this.dynaClass = dynaClass;
}
// ---------------------------------------------------- Instance Variables
/**
* The DynaClass
"base class" that this DynaBean
* is associated with.
*/
protected DynaClass dynaClass = null;
/**
* The set of property values for this DynaBean, keyed by property name.
*/
protected HashMap values = new HashMap<>();
/** Map decorator for this DynaBean */
private transient Map mapDecorator;
/**
* Return a Map representation of this DynaBean.
*
* This, for example, could be used in JSTL in the following way to access
* a DynaBean's fooProperty
:
*
* ${myDynaBean.map.fooProperty}
*
*
* @return a Map representation of this DynaBean
* @since 1.8.0
*/
public Map getMap(){
// cache the Map
if (mapDecorator == null){
mapDecorator = new DynaBeanPropertyMapDecorator(this);
}
return mapDecorator;
}
// ------------------------------------------------------ DynaBean Methods
/**
* Does the specified mapped property contain a value for the specified
* key value?
*
* @param name
* Name of the property to check
* @param key
* Name of the key to check
* @return true
if the mapped property contains a value for
* the specified key, otherwise false
*
* @throws IllegalArgumentException
* if there is no property
* of the specified name
*/
@Override
public boolean contains(final String name,final String key){
final Object value = values.get(name);
if (value == null){
throw new NullPointerException("No mapped value for '" + name + "(" + key + ")'");
}else if (value instanceof Map){
return (((Map) value).containsKey(key));
}else{
throw new IllegalArgumentException("Non-mapped property for '" + name + "(" + key + ")'");
}
}
/**
* Return the value of a simple property with the specified name.
*
* @param name
* Name of the property whose value is to be retrieved
* @return The property's value
*
* @throws IllegalArgumentException
* if there is no property
* of the specified name
*/
@Override
public Object get(final String name){
// Return any non-null value for the specified property
final Object value = values.get(name);
if (value != null){
return (value);
}
// Return a null value for a non-primitive property
final Class type = getDynaProperty(name).getType();
if (!type.isPrimitive()){
return (value);
}
// Manufacture default values for primitive properties
if (type == Boolean.TYPE){
return (Boolean.FALSE);
}else if (type == Byte.TYPE){
return (new Byte((byte) 0));
}else if (type == Character.TYPE){
return (new Character((char) 0));
}else if (type == Double.TYPE){
return (new Double(0.0));
}else if (type == Float.TYPE){
return (new Float((float) 0.0));
}else if (type == Integer.TYPE){
return (new Integer(0));
}else if (type == Long.TYPE){
return (new Long(0));
}else if (type == Short.TYPE){
return (new Short((short) 0));
}else{
return (null);
}
}
/**
* Return the value of an indexed property with the specified name.
*
* @param name
* Name of the property whose value is to be retrieved
* @param index
* Index of the value to be retrieved
* @return The indexed property's value
*
* @throws IllegalArgumentException
* if there is no property
* of the specified name
* @throws IllegalArgumentException
* if the specified property
* exists, but is not indexed
* @throws IndexOutOfBoundsException
* if the specified index
* is outside the range of the underlying property
* @throws NullPointerException
* if no array or List has been
* initialized for this property
*/
@Override
public Object get(final String name,final int index){
final Object value = values.get(name);
if (value == null){
throw new NullPointerException("No indexed value for '" + name + "[" + index + "]'");
}else if (value.getClass().isArray()){
return (Array.get(value, index));
}else if (value instanceof List){
return ((List) value).get(index);
}else{
throw new IllegalArgumentException("Non-indexed property for '" + name + "[" + index + "]'");
}
}
/**
* Return the value of a mapped property with the specified name,
* or null
if there is no value for the specified key.
*
* @param name
* Name of the property whose value is to be retrieved
* @param key
* Key of the value to be retrieved
* @return The mapped property's value
*
* @throws IllegalArgumentException
* if there is no property
* of the specified name
* @throws IllegalArgumentException
* if the specified property
* exists, but is not mapped
*/
@Override
public Object get(final String name,final String key){
final Object value = values.get(name);
if (value == null){
throw new NullPointerException("No mapped value for '" + name + "(" + key + ")'");
}else if (value instanceof Map){
return (((Map) value).get(key));
}else{
throw new IllegalArgumentException("Non-mapped property for '" + name + "(" + key + ")'");
}
}
/**
* Return the DynaClass
instance that describes the set of
* properties available for this DynaBean.
*
* @return The associated DynaClass
*/
@Override
public DynaClass getDynaClass(){
return (this.dynaClass);
}
/**
* Remove any existing value for the specified key on the
* specified mapped property.
*
* @param name
* Name of the property for which a value is to
* be removed
* @param key
* Key of the value to be removed
*
* @throws IllegalArgumentException
* if there is no property
* of the specified name
*/
@Override
public void remove(final String name,final String key){
final Object value = values.get(name);
if (value == null){
throw new NullPointerException("No mapped value for '" + name + "(" + key + ")'");
}else if (value instanceof Map){
((Map) value).remove(key);
}else{
throw new IllegalArgumentException("Non-mapped property for '" + name + "(" + key + ")'");
}
}
/**
* Set the value of a simple property with the specified name.
*
* @param name
* Name of the property whose value is to be set
* @param value
* Value to which this property is to be set
*
* @throws ConversionException
* if the specified value cannot be
* converted to the type required for this property
* @throws IllegalArgumentException
* if there is no property
* of the specified name
* @throws NullPointerException
* if an attempt is made to set a
* primitive property to null
*/
@Override
public void set(final String name,final Object value){
final DynaProperty descriptor = getDynaProperty(name);
if (value == null){
if (descriptor.getType().isPrimitive()){
throw new NullPointerException("Primitive value for '" + name + "'");
}
}else if (!isAssignable(descriptor.getType(), value.getClass())){
throw new ConversionException(
"Cannot assign value of type '" + value.getClass().getName() + "' to property '" + name + "' of type '"
+ descriptor.getType().getName() + "'");
}
values.put(name, value);
}
/**
* Set the value of an indexed property with the specified name.
*
* @param name
* Name of the property whose value is to be set
* @param index
* Index of the property to be set
* @param value
* Value to which this property is to be set
*
* @throws ConversionException
* if the specified value cannot be
* converted to the type required for this property
* @throws IllegalArgumentException
* if there is no property
* of the specified name
* @throws IllegalArgumentException
* if the specified property
* exists, but is not indexed
* @throws IndexOutOfBoundsException
* if the specified index
* is outside the range of the underlying property
*/
@Override
public void set(final String name,final int index,final Object value){
final Object prop = values.get(name);
if (prop == null){
throw new NullPointerException("No indexed value for '" + name + "[" + index + "]'");
}else if (prop.getClass().isArray()){
Array.set(prop, index, value);
}else if (prop instanceof List){
try{
@SuppressWarnings("unchecked")
final
// This is safe to cast because list properties are always
// of type Object
List