org.milyn.javabean.factory.BasicFactoryDefinitionParser Maven / Gradle / Ivy
The newest version!
/*
* Milyn - Copyright (C) 2006 - 2010
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License (version 2.1) as published by the Free Software
* Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Lesser General Public License for more details:
* http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.javabean.factory;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.milyn.container.ExecutionContext;
import org.milyn.util.ClassUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* The BasicFactoryDefinitionParser supports two kinds of
* factory definitions:
*
* - some.package.SomeFactory#createObject
* This defines that the 'createObject' of the class 'some.package.SomeFactory'
* should be called for creating the target object.
* - some.package.SomeFactorySingleton#getFactoryMethod.createObject
* This defines that the 'getFactoryMethod' of the class 'some.package.SomeFactorySingleton'
* should be called to retrieve the factory object on which the 'createObject' should
* be called for creating the target object.
* The factory retrieval method should never return null
. This
* will result in a {@link NullPointerException}.
*
*
*
*
* @author [email protected]
*
*/
@Alias("basic")
public class BasicFactoryDefinitionParser extends
AbstractCachingFactoryDefinitionParser {
@Override
protected Factory> createFactory(String factoryDefinition) {
String[] defParts = StringUtils.split(factoryDefinition, '#');
if (defParts.length == 2) {
String className = defParts[0];
String methodDef = defParts[1];
try {
String[] methodParts = StringUtils.split(methodDef, '.');
if (methodParts.length == 1) {
return createStaticMethodFactory(factoryDefinition, className, methodDef);
} else if (methodParts.length == 2) {
String staticGetInstanceMethodDef = methodParts[0];
String factoryMethodDef = methodParts[1];
return createFactoryInstanceFactory(factoryDefinition, className, staticGetInstanceMethodDef, factoryMethodDef);
} else {
throw createInvalidDefinitionException(factoryDefinition);
}
} catch (InvalidFactoryDefinitionException e) {
throw e;
} catch (Exception e) {
throw new FactoryException("The factory could not be created from the definition '"+ factoryDefinition +"'.", e);
}
} else {
throw createInvalidDefinitionException(factoryDefinition);
}
}
/**
* Creates a StaticMethodFactory object.
*
* @param factoryDefinition
* @param className
* @param methodDef
* @return
* @throws ClassNotFoundException
* @throws SecurityException
* @throws NoSuchMethodException
*/
private Factory> createStaticMethodFactory(String factoryDefinition, String className, String methodDef) throws ClassNotFoundException, SecurityException, NoSuchMethodException {
Class> factoryClass = ClassUtil.forName(className, this.getClass());
Method factoryMethod = factoryClass.getMethod(methodDef);
if(!Modifier.isStatic(factoryMethod.getModifiers())) {
throw new NoSuchMethodException("No static method with the name '"+ methodDef +"' can be found on the class '" + className + "' while processing the factory definition '"+ factoryDefinition +"'.");
}
return new StaticMethodFactory(factoryDefinition, factoryMethod);
}
/**
* Creates a FactoryInstanceFactory object.
*
* @param factoryDefinition
* @param className
* @param staticGetInstanceMethodDef
* @param factoryMethodDef
* @return
* @throws ClassNotFoundException
* @throws SecurityException
* @throws NoSuchMethodException
*/
private Factory> createFactoryInstanceFactory(String factoryDefinition, String className, String staticGetInstanceMethodDef, String factoryMethodDef) throws ClassNotFoundException, SecurityException, NoSuchMethodException{
Class> factoryClass = ClassUtil.forName(className, this.getClass());
Method getInstanceMethod = factoryClass.getMethod(staticGetInstanceMethodDef);
Class> factoryType = getInstanceMethod.getReturnType();
Method factoryMethod = factoryType.getMethod(factoryMethodDef);
if(!Modifier.isStatic(getInstanceMethod.getModifiers())) {
throw new NoSuchMethodException("No static method with the name '"+ staticGetInstanceMethodDef +"' can be found on the class '" + className + "'.");
}
return new FactoryInstanceFactory(factoryDefinition, getInstanceMethod, factoryMethod);
}
private InvalidFactoryDefinitionException createInvalidDefinitionException(String factoryDefinition) {
return new InvalidFactoryDefinitionException("The factory definition '" + factoryDefinition +"' " +
"isn't valid. The definition is 'some.package.SomeFactory#createObject' or " +
"'some.package.SomeFactorySingleton#getFactoryMethod.createObject'");
}
private static String toClassDefinition(Method method) {
return method.getDeclaringClass().getName() + "#" + method.getName() + "()";
}
/**
* The StaticMethodFactory uses a static factory method create the target objects.
*/
private static class StaticMethodFactory implements Factory