/* * Copyright 2002-2006 the original author or authors. * * Licensed 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.nfwork.dbfound.json; 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.ConvertUtils; import org.apache.commons.beanutils.DynaBean; import org.apache.commons.beanutils.DynaClass; import org.apache.commons.beanutils.DynaProperty; /** * @author Andres Almiray */ @SuppressWarnings("unchecked") public class JSONDynaBean implements DynaBean, Serializable { private static final long serialVersionUID = -1088560023822108485L; protected JSONDynaClass dynaClass; protected Map dynaValues = new HashMap(); public JSONDynaBean() { super(); } public boolean contains( String name, String key ) { Object value = dynaValues.get( name ); if( value == null ){ throw new NullPointerException( "Unmapped property name: " + name + " key: " + key ); }else if( !(value instanceof Map) ){ throw new IllegalArgumentException( "Non-Mapped property name: " + name + " key: " + key ); } return ((Map) value).containsKey( key ); } public Object get( String name ) { Object value = dynaValues.get( name ); if( value != null ){ return value; } Class type = getDynaProperty( name ).getType(); if( type == null ){ throw new NullPointerException( "Unspecified property type for " + name ); } if( !type.isPrimitive() ){ return value; } 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 == Short.TYPE ){ return new Short( (short) 0 ); }else if( type == Integer.TYPE ){ return new Integer( 0 ); }else if( type == Long.TYPE ){ return new Long( 0 ); }else if( type == Float.TYPE ){ return new Float( 0.0 ); }else if( type == Double.TYPE ){ return new Double( 0 ); } return null; } public Object get( String name, int index ) { Object value = dynaValues.get( name ); if( value == null ){ throw new NullPointerException( "Unindexed property name: " + name + " index: " + index ); }else if( !(value instanceof List) || !(value.getClass().isArray()) ){ throw new IllegalArgumentException( "Non-Indexed property name: " + name + " index: " + index ); } if( value.getClass() .isArray() ){ value = Array.get( value, index ); }else if( value instanceof List ){ value = ((List) value).get( index ); } return value; } public Object get( String name, String key ) { Object value = dynaValues.get( name ); if( value == null ){ throw new NullPointerException( "Unmapped property name: " + name + " key: " + key ); }else if( !(value instanceof Map) ){ throw new IllegalArgumentException( "Non-Mapped property name: " + name + " key: " + key ); } return ((Map) value).get( key ); } public DynaClass getDynaClass() { return this.dynaClass; } public void remove( String name, String key ) { Object value = dynaValues.get( name ); if( value == null ){ throw new NullPointerException( "Unmapped property name: " + name + " key: " + key ); }else if( !(value instanceof Map) ){ throw new IllegalArgumentException( "Non-Mapped property name: " + name + " key: " + key ); } ((Map) value).remove( key ); } public void set( String name, int index, Object value ) { Object prop = dynaValues.get( name ); if( prop == null ){ throw new NullPointerException( "Unindexed property name: " + name + " index: " + index ); }else if( !(prop instanceof List) || !(prop.getClass().isArray()) ){ throw new IllegalArgumentException( "Non-Indexed property name: " + name + " index: " + index ); } if( prop.getClass() .isArray() ){ Array.set( prop, index, value ); }else if( value instanceof List ){ ((List) prop).set( index, value ); } } public void set( String name, Object value ) { DynaProperty property = getDynaProperty( name ); if( property.getType() == null ){ throw new NullPointerException( "Unspecified property type for " + name ); } if( value == null ){ if( property.getType() .isPrimitive() ){ throw new NullPointerException( "Property type for " + name + " is primitive" ); } }else if( !isDynaAssignable( property.getType(), value.getClass() ) ){ try{ value = ConvertUtils.convert( String.valueOf( value ), value.getClass() ); } catch( Exception e ){ throw new IllegalArgumentException( "Unassignable property type for " + name ); } } // log.debug( name + " = " + value ); dynaValues.put( name, value ); } public void set( String name, String key, Object value ) { Object prop = dynaValues.get( name ); if( prop == null ){ throw new IllegalArgumentException( "Unmapped property name: " + name + " key: " + key ); }else if( !(prop instanceof Map) ){ throw new IllegalArgumentException( "Non-Mapped property name: " + name + " key: " + key ); } ((Map) prop).put( key, value ); } protected DynaProperty getDynaProperty( String name ) { DynaProperty property = getDynaClass().getDynaProperty( name ); if( property == null ){ throw new IllegalArgumentException( "Unspecified property for " + name ); } return property; } protected boolean isDynaAssignable( Class dest, Class src ) { boolean assignable = dest.isAssignableFrom( src ); assignable = (dest == Boolean.TYPE && src == Boolean.class) ? true : assignable; assignable = (dest == Byte.TYPE && src == Byte.class) ? true : assignable; assignable = (dest == Character.TYPE && src == Character.class) ? true : assignable; assignable = (dest == Short.TYPE && src == Short.class) ? true : assignable; assignable = (dest == Integer.TYPE && src == Integer.class) ? true : assignable; assignable = (dest == Long.TYPE && src == Long.class) ? true : assignable; assignable = (dest == Float.TYPE && src == Float.class) ? true : assignable; assignable = (dest == Double.TYPE && src == Double.class) ? true : assignable; if( src == Double.TYPE || Double.class.isAssignableFrom( src ) ){ assignable = (isByte( dest ) || isShort( dest ) || isInteger( dest ) || isLong( dest ) || isFloat( dest )) ? true : assignable; } if( src == Float.TYPE || Float.class.isAssignableFrom( src ) ){ assignable = (isByte( dest ) || isShort( dest ) || isInteger( dest ) || isLong( dest )) ? true : assignable; } if( src == Long.TYPE || Long.class.isAssignableFrom( src ) ){ assignable = (isByte( dest ) || isShort( dest ) || isInteger( dest )) ? true : assignable; } if( src == Integer.TYPE || Integer.class.isAssignableFrom( src ) ){ assignable = (isByte( dest ) || isShort( dest )) ? true : assignable; } if( src == Short.TYPE || Short.class.isAssignableFrom( src ) ){ assignable = (isByte( dest )) ? true : assignable; } return assignable; } protected void setDynamicFormClass( JSONDynaClass dynaClass ) { this.dynaClass = dynaClass; } private boolean isByte( Class clazz ) { return Byte.class.isAssignableFrom( clazz ) || clazz == Byte.TYPE; } private boolean isFloat( Class clazz ) { return Float.class.isAssignableFrom( clazz ) || clazz == Float.TYPE; } private boolean isInteger( Class clazz ) { return Integer.class.isAssignableFrom( clazz ) || clazz == Integer.TYPE; } private boolean isLong( Class clazz ) { return Long.class.isAssignableFrom( clazz ) || clazz == Long.TYPE; } private boolean isShort( Class clazz ) { return Short.class.isAssignableFrom( clazz ) || clazz == Short.TYPE; } }