All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibatis.common.beans.ComplexBeanProbe Maven / Gradle / Ivy

Go to download

The jBATIS persistence framework will help you to significantly reduce the amount of Java code that you normally need to access a relational database. iBATIS simply maps JavaBeans to SQL statements using a very simple XML descriptor.

The newest version!
/*
 *  Copyright 2004 Clinton Begin
 *
 *  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.ibatis.common.beans;

import java.util.Map;
import static com.ibatis.common.Objects.uncheckedCast;

import com.ibatis.common.StringTokenizer;
import com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactoryUtil;

import org.ibatis.cglib.*;

/**
 * StaticBeanProbe provides methods that allow simple, reflective access to JavaBeans style properties. Methods are
 * provided for all simple types as well as object types.
 * 

* Examples: *

* StaticBeanProbe.setObject(object, propertyName, value); *

* Object value = StaticBeanProbe.getObject(object, propertyName); */ public class ComplexBeanProbe extends BaseProbe { private static final Object[] NO_ARGUMENTS = new Object[0]; protected ComplexBeanProbe() { } /** * Returns the class that the setter expects to receive as a parameter when setting a property value. * * @param object * The bean to check * @param name * The name of the property * @return The type of the property */ public Class getPropertyTypeForSetter(Object object, String name) { Class type = object.getClass(); if (object instanceof Class) { type = getClassPropertyTypeForSetter((Class) object, name); } else if (object instanceof Map) { Map map = (Map) object; Object value = map.get(name); if (value == null) { type = Object.class; } else { type = value.getClass(); } } else { if (name.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(name, '.'); while (parser.hasMoreTokens()) { name = parser.nextToken(); type = parser.hasMoreTokens() ? ClassInfo.getInstance(type).getGetterType(name) : ClassInfo .getInstance(type).getSetterType(name); ; } } else { type = ClassInfo.getInstance(type).getSetterType(name); } } return type; } /** * Returns the class that the getter will return when reading a property value. * * @param object * The bean to check * @param name * The name of the property * @return The type of the property */ public Class getPropertyTypeForGetter(Object object, String name) { Class type = object.getClass(); if (object instanceof Class) { type = getClassPropertyTypeForGetter((Class) object, name); } else if (object instanceof Map) { Map map = (Map) object; Object value = map.get(name); if (value == null) { type = Object.class; } else { type = value.getClass(); } } else { if (name.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(name, '.'); while (parser.hasMoreTokens()) { name = parser.nextToken(); type = ClassInfo.getInstance(type).getGetterType(name); } } else { type = ClassInfo.getInstance(type).getGetterType(name); } } return type; } /** * Returns the class that the getter will return when reading a property value. * * @param type * The class to check * @param name * The name of the property * @return The type of the property */ private Class getClassPropertyTypeForGetter(Class type, String name) { if (name.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(name, '.'); while (parser.hasMoreTokens()) { name = parser.nextToken(); type = ClassInfo.getInstance(type).getGetterType(name); } } else { type = ClassInfo.getInstance(type).getGetterType(name); } return type; } /** * Returns the class that the setter expects to receive as a parameter when setting a property value. * * @param type * The class to check * @param name * The name of the property * @return The type of the property */ private Class getClassPropertyTypeForSetter(Class type, String name) { if (name.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(name, '.'); while (parser.hasMoreTokens()) { name = parser.nextToken(); type = parser.hasMoreTokens() ? ClassInfo.getInstance(type).getGetterType(name) : ClassInfo .getInstance(type).getSetterType(name); } } else { type = ClassInfo.getInstance(type).getSetterType(name); } return type; } /** * Gets an Object property from a bean * * @param object * The bean * @param name * The property name * @return The property value (as an Object) */ @Override public Object getObject(Object object, String name) { if (name.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(name, '.'); Object value = object; while (parser.hasMoreTokens()) { value = getProperty(value, parser.nextToken()); if (value == null) { break; } } return value; } else { return getProperty(object, name); } } /** * Sets the value of a bean property to an Object * * @param object * The bean to change * @param name * The name of the property to set * @param value * The new value to set */ @Override public void setObject(Object object, String name, Object value) { if (name.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(name, '.'); String property = parser.nextToken(); Object child = object; while (parser.hasMoreTokens()) { Class type = getPropertyTypeForGetter(child, property); Object parent = child; child = getProperty(parent, property); if (child == null) { if (value == null) { return; // don't instantiate child path if value is null } else { try { child = ResultObjectFactoryUtil.createObjectThroughFactory(type); setObject(parent, property, child); } catch (Exception e) { throw new ProbeException("Cannot set value of property '" + name + "' because '" + property + "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e); } } } property = parser.nextToken(); } setProperty(child, property, value); } else { setProperty(object, name, value); } } /** * Checks to see if a bean has a writable property be a given name * * @param object * The bean to check * @param propertyName * The property to check for * @return True if the property exists and is writable */ @Override public boolean hasWritableProperty(Object object, String propertyName) { boolean hasProperty = false; if (object instanceof Map) { hasProperty = true;// ((Map) object).containsKey(propertyName); } else { if (propertyName.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(propertyName, '.'); Class type = object.getClass(); while (parser.hasMoreTokens()) { propertyName = parser.nextToken(); type = ClassInfo.getInstance(type).getGetterType(propertyName); hasProperty = ClassInfo.getInstance(type).hasWritableProperty(propertyName); } } else { hasProperty = ClassInfo.getInstance(object.getClass()).hasWritableProperty(propertyName); } } return hasProperty; } /** * Checks to see if a bean has a readable property be a given name * * @param object * The bean to check * @param propertyName * The property to check for * @return True if the property exists and is readable */ @Override public boolean hasReadableProperty(Object object, String propertyName) { boolean hasProperty = false; if (object instanceof Map) { hasProperty = true;// ((Map) object).containsKey(propertyName); } else { if (propertyName.indexOf('.') >= 0) { StringTokenizer parser = new StringTokenizer(propertyName, '.'); Class type = object.getClass(); while (parser.hasMoreTokens()) { propertyName = parser.nextToken(); type = ClassInfo.getInstance(type).getGetterType(propertyName); hasProperty = ClassInfo.getInstance(type).hasReadableProperty(propertyName); } } else { hasProperty = ClassInfo.getInstance(object.getClass()).hasReadableProperty(propertyName); } } return hasProperty; } @Override protected Object getProperty(Object object, String name) { try { Object value = null; if (name.indexOf('[') >= 0) { value = getIndexedProperty(object, name); } else { if (object instanceof Map) { int index = name.indexOf('.'); if (index >= 0) { String mapId = name.substring(0, index); value = getProperty(((Map) object).get(mapId), name.substring(index + 1)); } else { value = ((Map) object).get(name); } } else { int index = name.indexOf('.'); if (index >= 0) { String newName = name.substring(0, index); value = getProperty(getObject(object, newName), name.substring(index + 1)); } else { ClassInfo classCache = ClassInfo.getInstance(object.getClass()); Invoker method = classCache.getGetInvoker(name); if (method == null) { throw new NoSuchMethodException("No GET method for property " + name + " on instance of " + object.getClass().getName()); } try { value = method.invoke(object, NO_ARGUMENTS); } catch (Throwable t) { throw ClassInfo.unwrapThrowable(t); } } } } return value; } catch (ProbeException e) { throw e; } catch (Throwable t) { if (object == null) { throw new ProbeException("Could not get property '" + name + "' from null reference. Cause: " + t.toString(), t); } else { throw new ProbeException("Could not get property '" + name + "' from " + object.getClass().getName() + ". Cause: " + t.toString(), t); } } } @Override protected void setProperty(Object object, String name, Object value) { ClassInfo classCache = ClassInfo.getInstance(object.getClass()); try { if (name.indexOf('[') >= 0) { setIndexedProperty(object, name, value); } else { if (object instanceof Map) { Map mo = uncheckedCast(object); mo.put(name, value); } else { Invoker method = classCache.getSetInvoker(name); if (method == null) { throw new NoSuchMethodException("No SET method for property " + name + " on instance of " + object.getClass().getName()); } Object[] params = new Object[1]; params[0] = value; try { method.invoke(object, params); } catch (Throwable t) { throw ClassInfo.unwrapThrowable(t); } } } } catch (ProbeException e) { throw e; } catch (Throwable t) { throw new ProbeException("Could not set property '" + name + "' to value '" + value + "' for " + object.getClass().getName() + ". Cause: " + t.toString(), t); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy