001: /*
002: * Copyright 2005-2006 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.opensource.org/licenses/ecl1.php
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.kuali.rice.resourceloader;
018:
019: import java.lang.reflect.InvocationTargetException;
020: import java.util.Collection;
021: import java.util.Iterator;
022: import java.util.List;
023:
024: import org.apache.commons.beanutils.ConstructorUtils;
025: import org.apache.commons.beanutils.PropertyUtils;
026: import org.apache.log4j.Logger;
027: import org.kuali.rice.definition.DataDefinition;
028: import org.kuali.rice.definition.ObjectDefinition;
029: import org.kuali.rice.definition.PropertyDefinition;
030: import org.kuali.rice.util.ClassLoaderUtils;
031:
032: /**
033: * Resolves object definitions into java Objects that are wrapped in a proxy whose classloader is the current
034: * context classloader.
035: *
036: * @author Kuali Rice Team (kuali-rice@googlegroups.com)
037: *
038: */
039: public class ObjectDefinitionResolver {
040:
041: private static final Logger LOG = Logger
042: .getLogger(ObjectDefinitionResolver.class);
043:
044: /**
045: * Wraps the given object in a proxy which switches the context classloader appropriately. The classloader
046: * of this resource loader is used.
047: */
048: public static Object wrap(Object object) {
049: return wrap(object, ClassLoaderUtils.getDefaultClassLoader());
050: }
051:
052: /**
053: * Wraps the given object in a proxy which switches the context classloader appropriately. The given classloader
054: * is used as the context classloader.
055: */
056: public static Object wrap(Object object, ClassLoader classLoader) {
057: // return ContextClassLoaderProxy.wrap(object, classLoader);
058: return object;
059: }
060:
061: public static Object createObject(String className,
062: ClassLoader classLoader) {
063: return createObject(new ObjectDefinition(className),
064: classLoader, true);
065: }
066:
067: public static Object createObject(ObjectDefinition definition,
068: ClassLoader classLoader, boolean wrap) {
069: Object object = null;
070: String className = definition.getClassName();
071: try {
072: ContextClassLoaderBinder.bind(classLoader);
073: Class<?>[] constructorParamTypes = buildConstructorParamTypes(definition
074: .getConstructorParameters());
075: Object[] constructorParams = buildConstructorParams(definition
076: .getConstructorParameters());
077: try {
078: Class<?> objectClass = Class.forName(className, true,
079: classLoader);
080: object = loadObject(objectClass, constructorParams,
081: constructorParamTypes);
082: } catch (ClassNotFoundException e) {
083: return null;
084: }
085: invokeProperties(object, definition.getProperties());
086: if (wrap) {
087: return wrap(object, classLoader);
088: }
089: return object;
090: } catch (Exception e) {
091: handleException(className, e);
092: } finally {
093: ContextClassLoaderBinder.unbind();
094: }
095: return object;
096: }
097:
098: protected static Object loadObject(Class<?> objectClass,
099: Object[] constructorParams, Class<?>[] constructorParamTypes)
100: throws NoSuchMethodException, InstantiationException,
101: IllegalAccessException, InvocationTargetException {
102: return ConstructorUtils.invokeConstructor(objectClass,
103: constructorParams, constructorParamTypes);
104: }
105:
106: private static void handleException(String className, Exception e) {
107: if (e instanceof RuntimeException) {
108: throw (RuntimeException) e;
109: }
110: throw new ResourceLoaderException(
111: "Could not materialize object from definition, using classname: "
112: + className, e);
113: }
114:
115: protected static Class<?>[] buildConstructorParamTypes(
116: List constructorParameters) {
117: Class<?>[] params = new Class[constructorParameters.size()];
118: int index = 0;
119: for (Iterator iterator = constructorParameters.iterator(); iterator
120: .hasNext();) {
121: DataDefinition dataDef = (DataDefinition) iterator.next();
122: params[index++] = dataDef.getType();
123: }
124: return params;
125: }
126:
127: protected static Object[] buildConstructorParams(
128: List constructorParameters) {
129: Object[] params = new Object[constructorParameters.size()];
130: int index = 0;
131: for (Iterator iterator = constructorParameters.iterator(); iterator
132: .hasNext();) {
133: DataDefinition dataDef = (DataDefinition) iterator.next();
134: params[index++] = dataDef.getValue();
135: }
136: return params;
137: }
138:
139: protected static void invokeProperties(Object object,
140: Collection properties) throws InvocationTargetException,
141: IllegalAccessException, NoSuchMethodException {
142: for (Iterator iterator = properties.iterator(); iterator
143: .hasNext();) {
144: PropertyDefinition propertyDef = (PropertyDefinition) iterator
145: .next();
146: invokeProperty(object, propertyDef);
147: }
148: }
149:
150: protected static void invokeProperty(Object object,
151: PropertyDefinition definition)
152: throws InvocationTargetException, IllegalAccessException,
153: NoSuchMethodException {
154: PropertyUtils.setProperty(object, definition.getName(),
155: definition.getData().getValue());
156: }
157:
158: }
|