X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2Fadapters%2FSetterConfiguration.java;h=d9c83bb45b5b50249c88648ce16a8eada013f795;hb=ddd261f331280640c5b53c7128230b629ebcd268;hp=77fd9720b4c66c9ac69a12bce27862a1458e5d41;hpb=92e23e5ecf9614f2ab770a8cdedc0b21ddf1e127;p=utils diff --git a/system/general/src/main/java/org/wamblee/system/adapters/SetterConfiguration.java b/system/general/src/main/java/org/wamblee/system/adapters/SetterConfiguration.java index 77fd9720..d9c83bb4 100644 --- a/system/general/src/main/java/org/wamblee/system/adapters/SetterConfiguration.java +++ b/system/general/src/main/java/org/wamblee/system/adapters/SetterConfiguration.java @@ -1,12 +1,12 @@ /* * Copyright 2008 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. @@ -15,22 +15,15 @@ */ package org.wamblee.system.adapters; -import java.awt.CompositeContext; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.wamblee.collections.CollectionFilter; + import org.wamblee.conditions.Condition; import org.wamblee.conditions.FixedCondition; + import org.wamblee.general.Pair; + import org.wamblee.reflection.ReflectionUtils; + import org.wamblee.system.core.DefaultProvidedInterface; import org.wamblee.system.core.DefaultRequiredInterface; import org.wamblee.system.core.ProvidedInterface; @@ -38,266 +31,351 @@ import org.wamblee.system.core.RequiredInterface; import org.wamblee.system.core.Scope; import org.wamblee.system.core.SystemAssemblyException; +import java.awt.CompositeContext; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + + /** - * Represents the configuration for exposing the setters of a class as required - * interfaces. - * + * Represents the configuration for exposing the setters of a class as + * required interfaces. + * * @author Erik Brakkee */ public class SetterConfiguration { + /** + * DOCUMENT ME! + */ + private Class _class; - private Class _class; - private boolean publicOnly; - - private Map setters; - - /** - * Constructs the setter configuration. By default no setters are added. - * - * @param aClass - * Class which is being configured. - */ - public SetterConfiguration(Class aClass) { - _class = aClass; - publicOnly = true; - setters = new HashMap(); - } - - /** - * Makes sure that all available setters are used. - */ - public SetterConfiguration initAllSetters() { - setters.clear(); - for (Method method: getAllSetters(_class, publicOnly) ) { - setters.put(method, createParameterValues(method)); - } - return this; - } - - /** - * Called to set whether non-public setters are also used. By default only - * public setters are used. The currently selected setters remain chosen. - * - * @param aIsNonPublic - * Non public flag. - */ - public SetterConfiguration setNonPublic(boolean aIsNonPublic) { - publicOnly = !aIsNonPublic; - return this; - } - - /** - * Removes all setters. - * - * @return Reference to the current object to allow call chaining. - */ - public SetterConfiguration clear() { - setters.clear(); - return this; - } - - /** - * Removes a setter from the set of methods. - * - * @param aName - * Name of the setter to remove. - * @return Reference to the current object to allow call chaining. - */ - public SetterConfiguration remove(String aName) { - for (Method method : setters.keySet()) { - if (method.getName().equals(aName)) { - setters.remove(method); - return this; - } - } - throw new IllegalArgumentException( - "No method configured by the name of '" + aName + "'"); - } - - /** - * Removes the method from the set of methods. - * @param aMethod Method to remove. - * @return - */ - public SetterConfiguration remove(Method aMethod) { - if ( !aMethod.getDeclaringClass().isAssignableFrom(_class) ) { - throw new RuntimeException("Method " + aMethod + " not found in class " + _class + " or its superclasses"); - } - for (Method method : setters.keySet()) { - if (method.equals(aMethod)) { + /** + * DOCUMENT ME! + */ + private boolean publicOnly; + + /** + * DOCUMENT ME! + */ + private Map setters; + +/** + * Constructs the setter configuration. By default no setters are added. + * + * @param aClass + * Class which is being configured. + */ + public SetterConfiguration(Class aClass) { + _class = aClass; + publicOnly = true; + setters = new HashMap(); + } + + /** + * Makes sure that all available setters are used. + * + * @return DOCUMENT ME! + */ + public SetterConfiguration initAllSetters() { + setters.clear(); + + for (Method method : getAllSetters(_class, publicOnly)) { + setters.put(method, createParameterValues(method)); + } + + return this; + } + + /** + * Called to set whether non-public setters are also used. By + * default only public setters are used. The currently selected setters + * remain chosen. + * + * @param aIsNonPublic Non public flag. + * + * @return DOCUMENT ME! + */ + public SetterConfiguration setNonPublic(boolean aIsNonPublic) { + publicOnly = !aIsNonPublic; + + return this; + } + + /** + * Removes all setters. + * + * @return Reference to the current object to allow call chaining. + */ + public SetterConfiguration clear() { + setters.clear(); + + return this; + } + + /** + * Removes a setter from the set of methods. + * + * @param aName Name of the setter to remove. + * + * @return Reference to the current object to allow call chaining. + * + * @throws IllegalArgumentException DOCUMENT ME! + */ + public SetterConfiguration remove(String aName) { + for (Method method : setters.keySet()) { + if (method.getName().equals(aName)) { setters.remove(method); + return this; } } + throw new IllegalArgumentException( - "Method '" + aMethod + "' was not configured. "); - } - - /** - * Adds a given setter name to the setters. - * - * @param aName Name of a setter method. - * @return Reference to the current object to allow call chaining. - */ - public SetterConfiguration add(final String aName) { - int oldlen = setters.size(); - List methods = new ArrayList(); - CollectionFilter.filter(getAllSetters(_class, publicOnly), methods, - new Condition() { - @Override - public boolean matches(Method aObject) { - return aObject.getName().equals(aName); - } - - }); - if (methods.size() == 0 ) { - throw new IllegalArgumentException("Method '" + aName - + "' not found in " + _class.getName()); - } - // TODO is it possible to get more than one setter here in case the subclass overrides - // the baseclass method? - setters.put(methods.get(0), createParameterValues(methods.get(0))); - return this; - } - - /** - * Adds a given setter identified by the type it accepts to the list of - * setters.N - * - * @param aType - * Type to look for. Note that this must be the exact type as - * autoboxing and autounboxing is not used. - * @return Reference to the current object to allow call chaining. - * @throws IllegalArgumentException - * In case no setter is found or multiple setters are found. - */ - public SetterConfiguration addSetter(final Class aType) { - List result = new ArrayList(); - CollectionFilter.filter(getAllSetters(_class, publicOnly), result, - new Condition() { - @Override - public boolean matches(Method aObject) { - Class type = aObject.getParameterTypes()[0]; - return type.equals(aType); - } - - }); - if (result.size() == 0) { - throw new IllegalArgumentException("No setter found in class '" - + _class.getName() - + "' that has a setter with argument type '" - + aType.getName() + "'"); - } - if (result.size() > 1) { - String setters = ""; - for (Method method : result) { - setters += method.getName() + " "; - } - throw new IllegalArgumentException( - "Multiple setters found in class '" + _class.getName() - + " that accept type '" + aType.getName() + "': " - + setters); - } - Method method = result.get(0); - setters.put(method, createParameterValues(method)); - return this; - } - - /** - * Gets all setters for the current class. - * - * @return List of all setters. - */ - public static List getAllSetters(Class aClass, - boolean aPublicOnly) { - List result = new ArrayList(); - for (Method method : getAllMethods(aClass)) { - if (!aPublicOnly || Modifier.isPublic(method.getModifiers())) { - if (method.getName().startsWith("set") - && method.getParameterTypes().length == 1) { - method.setAccessible(true); - result.add(method); - } - } - } - return result; - } - - private static ParameterValues createParameterValues(Method aMethod) { - - Class[] paramTypes = aMethod.getParameterTypes(); - String[] paramNames = new String[paramTypes.length]; - for (int i = 0; i < paramTypes.length; i++) { - paramNames[i] = aMethod.getName() + "." + i; - } - return new ParameterValues(paramNames, paramTypes); - } - - private static final List getAllMethods(Class aClass) { - return ReflectionUtils.getAllMethods(aClass); - } - - /** - * Gets the required interfaces based on the configured setteres. - * - * @return List of required interfaces. - */ - public List getRequiredInterfaces() { - List result = new ArrayList(); - for (Method method : setters.keySet()) { - result.addAll(setters.get(method).getRequiredInterfaces()); - } - return result; - } - - /** - * Invokes all configured setters with the appropriate values. - * - * @param aScope - * Scope within which invocation takes place. - * @param aObject - * Object on which the invocation takes place. - */ - public void inject(Scope aScope, Object aObject) { - if (!_class.isInstance(aObject)) { - throw new IllegalArgumentException("Object '" + aObject - + "' is not an instance of " + _class.getName()); - } - for (Method method : setters.keySet()) { - ParameterValues values = setters.get(method); - - try { - method.invoke(aObject, values.values(aScope)); - } catch (IllegalAccessException e) { - throw new SystemAssemblyException("Problem invoking " + method - + " with " + values, e); - } catch (InvocationTargetException e) { - throw new SystemAssemblyException("Problem invoking " + method - + " with " + values, e); - } - } - } - - /** - * Returns the parameter values for allowing detailed configuration of how - * parameter values are set. - * - * @param aSetter - * Setter name without the "set" prefix with the first character - * converted to lower case. - * @return Parameter values. - */ - public ParameterValues values(String aMethod) { - for (Method method : setters.keySet()) { - if (method.getName().equals(aMethod)) { - return setters.get(method); - } - } - throw new IllegalArgumentException("No setter method '" + aMethod - + "' found"); - } - - public List getSetters() { - return new ArrayList(setters.keySet()); - } + "No method configured by the name of '" + aName + "'"); + } + + /** + * Removes the method from the set of methods. + * + * @param aMethod Method to remove. + * + * @return + * + * @throws RuntimeException DOCUMENT ME! + * @throws IllegalArgumentException DOCUMENT ME! + */ + public SetterConfiguration remove(Method aMethod) { + if (!aMethod.getDeclaringClass().isAssignableFrom(_class)) { + throw new RuntimeException("Method " + aMethod + + " not found in class " + _class + " or its superclasses"); + } + + for (Method method : setters.keySet()) { + if (method.equals(aMethod)) { + setters.remove(method); + + return this; + } + } + + throw new IllegalArgumentException("Method '" + aMethod + + "' was not configured. "); + } + + /** + * Adds a given setter name to the setters. + * + * @param aName Name of a setter method. + * + * @return Reference to the current object to allow call chaining. + * + * @throws IllegalArgumentException DOCUMENT ME! + */ + public SetterConfiguration add(final String aName) { + int oldlen = setters.size(); + List methods = new ArrayList(); + CollectionFilter.filter(getAllSetters(_class, publicOnly), methods, + new Condition() { + @Override + public boolean matches(Method aObject) { + return aObject.getName().equals(aName); + } + }); + + if (methods.size() == 0) { + throw new IllegalArgumentException("Method '" + aName + + "' not found in " + _class.getName()); + } + + // TODO is it possible to get more than one setter here in case the subclass overrides + // the baseclass method? + setters.put(methods.get(0), createParameterValues(methods.get(0))); + + return this; + } + + /** + * Adds a given setter identified by the type it accepts to the + * list of setters.N + * + * @param aType Type to look for. Note that this must be the exact type as + * autoboxing and autounboxing is not used. + * + * @return Reference to the current object to allow call chaining. + * + * @throws IllegalArgumentException In case no setter is found or multiple + * setters are found. + */ + public SetterConfiguration addSetter(final Class aType) { + List result = new ArrayList(); + CollectionFilter.filter(getAllSetters(_class, publicOnly), result, + new Condition() { + @Override + public boolean matches(Method aObject) { + Class type = aObject.getParameterTypes()[0]; + + return type.equals(aType); + } + }); + + if (result.size() == 0) { + throw new IllegalArgumentException("No setter found in class '" + + _class.getName() + "' that has a setter with argument type '" + + aType.getName() + "'"); + } + + if (result.size() > 1) { + String setters = ""; + + for (Method method : result) { + setters += (method.getName() + " "); + } + + throw new IllegalArgumentException( + "Multiple setters found in class '" + _class.getName() + + " that accept type '" + aType.getName() + "': " + setters); + } + + Method method = result.get(0); + setters.put(method, createParameterValues(method)); + + return this; + } + + /** + * Gets all setters for the current class. + * + * @param aClass DOCUMENT ME! + * @param aPublicOnly DOCUMENT ME! + * + * @return List of all setters. + */ + public static List getAllSetters(Class aClass, boolean aPublicOnly) { + List result = new ArrayList(); + + for (Method method : getAllMethods(aClass)) { + if (!aPublicOnly || Modifier.isPublic(method.getModifiers())) { + if (method.getName().startsWith("set") + && (method.getParameterTypes().length == 1)) { + method.setAccessible(true); + result.add(method); + } + } + } + + return result; + } + + /** + * DOCUMENT ME! + * + * @param aMethod DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private static ParameterValues createParameterValues(Method aMethod) { + Class[] paramTypes = aMethod.getParameterTypes(); + String[] paramNames = new String[paramTypes.length]; + + for (int i = 0; i < paramTypes.length; i++) { + paramNames[i] = aMethod.getName() + "." + i; + } + + return new ParameterValues(paramNames, paramTypes); + } + + /** + * DOCUMENT ME! + * + * @param aClass DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private static final List getAllMethods(Class aClass) { + return ReflectionUtils.getAllMethods(aClass); + } + + /** + * Gets the required interfaces based on the configured setteres. + * + * @return List of required interfaces. + */ + public List getRequiredInterfaces() { + List result = new ArrayList(); + + for (Method method : setters.keySet()) { + result.addAll(setters.get(method).getRequiredInterfaces()); + } + + return result; + } + + /** + * Invokes all configured setters with the appropriate values. + * + * @param aScope Scope within which invocation takes place. + * @param aObject Object on which the invocation takes place. + * + * @throws IllegalArgumentException DOCUMENT ME! + * @throws SystemAssemblyException DOCUMENT ME! + */ + public void inject(Scope aScope, Object aObject) { + if (!_class.isInstance(aObject)) { + throw new IllegalArgumentException("Object '" + aObject + + "' is not an instance of " + _class.getName()); + } + + for (Method method : setters.keySet()) { + ParameterValues values = setters.get(method); + + try { + method.invoke(aObject, values.values(aScope)); + } catch (IllegalAccessException e) { + throw new SystemAssemblyException("Problem invoking " + method + + " with " + values, e); + } catch (InvocationTargetException e) { + throw new SystemAssemblyException("Problem invoking " + method + + " with " + values, e); + } + } + } + + /** + * Returns the parameter values for allowing detailed configuration + * of how parameter values are set. + * + * @param aMethod Setter name without the "set" prefix with the first + * character converted to lower case. + * + * @return Parameter values. + * + * @throws IllegalArgumentException DOCUMENT ME! + */ + public ParameterValues values(String aMethod) { + for (Method method : setters.keySet()) { + if (method.getName().equals(aMethod)) { + return setters.get(method); + } + } + + throw new IllegalArgumentException("No setter method '" + aMethod + + "' found"); + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public List getSetters() { + return new ArrayList(setters.keySet()); + } }