package de.axone.tools; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * This is for creating classes which name and config values are given by * parameter. * * Format of Parameter-String is: classpath[( parameter1=value1[, ...] )] where * values are strings. * * Every class created in this way must conform to following conditions: * * <ol> * <li>Class must have an public parameterless constructor * <li>For every parameter parmN there must be a public setter Method with this * signature: public void setParamN( String value ) * </ol> * * @author flo * */ public abstract class ClassConfigurator { private static final String WS = "\\s*"; private static final String STRING = "[\\w\\.]+"; // word or dot private static final String NAME_ARG = "(" + STRING + ")"; private static final String DEL = "'"; private static final String P_NAME = "\\w+"; private static final String P_VALUE = "[^']*"; private static final String P_NV_ARG = "(" + P_NAME + ")" +WS+ "=" +WS+ DEL + "(" + P_VALUE + ")" + DEL; private static final String COMPLETE = NAME_ARG + // classname WS+"(?:\\("+WS + // opt. P_NV_ARG + // first param "(?:"+WS+","+WS+"(" + P_NV_ARG + "))*"+WS+"\\))?";// otherparams private static final String PARAMETER = P_NV_ARG; private static final Pattern PATTERN_COMPLETE = Pattern.compile(COMPLETE); private static final Pattern PATTERN_PARAMETER = Pattern.compile(PARAMETER); /** * Create a new Instance of the class specified in the description * initialized by these parameters. * * The constuctor to call is found via the given construcotorparameters * which then are used to construct the object. * * @param description * @param constructorClasses * @param constructorParameters * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException * @throws NoSuchMethodException * @throws SecurityException * @throws InvocationTargetException * @throws IllegalArgumentException * @return the created object */ public static Object create(String description, Class<?> [] constructorClasses, Object [] constructorParameters ) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { description = description.trim(); Matcher matcherComplete = PATTERN_COMPLETE.matcher(description); String className = null; Map<String, String> parameters = new HashMap<String, String>(); if (matcherComplete.matches()) { className = matcherComplete.group(1); Matcher matcherParameter = PATTERN_PARAMETER.matcher(description); while( matcherParameter.find() ){ String name = matcherParameter.group(1); String value = matcherParameter.group(2); parameters.put(name, value); } } else { throw new IllegalArgumentException("Definition doesn't comply"); } Class<?> clazz = Class.forName(className); Object instance = construct( clazz, constructorClasses, constructorParameters ); configure( instance, parameters ); return instance; } public static Object create(String description ) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { return create( description, null, null ); } public static <T> T construct( Class<T> clazz, Class<?> [] constructorClasses, Object [] constructorParameters ) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ Constructor<T> constructor = clazz.getConstructor( constructorClasses ); T instance = constructor.newInstance( constructorParameters ); //T instance = clazz.newInstance(); return instance; } public static void configure( Object object, Map<String,String> parameters ) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ for( Map.Entry<String,String> entry : parameters.entrySet() ){ String parameter = entry.getKey(); String methodName = methodize(parameter); Method method = object.getClass().getMethod( methodName, String.class ); method.invoke( object, entry.getValue() ); } } /* * Make setXxx out of xxx */ private static String methodize(String name) { if (name.length() == 1) { return "set" + name.toUpperCase(); } else { return "set" + name.substring(0, 1).toUpperCase() + name.substring(1); } } }