- private Class _class;
- private boolean _publicOnly;
-
- private Map<Method, ParameterValues> _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<Method, ParameterValues>();
- }
-
- /**
- * 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 (without the "set" prefix).
- * @return Reference to the current object to allow call chaining.
- */
- public SetterConfiguration remove(String aName) {
- final String name = createSetterName(aName);
- Map<Method, ParameterValues> setters = new HashMap<Method, ParameterValues>();
- for (Method method : _setters.keySet()) {
- if (method.getName().equals(name)) {
- _setters.remove(method);
- return this;
- }
- }
- throw new IllegalArgumentException(
- "No setter configured by the name of '" + aName + "'");
- }
-
- /**
- * Creates the name of a setter based on the name of the setter without the
- * "set" prefix.
- *
- * @param aName
- * Setter name.
- * @return Setter name.
- */
- private String createSetterName(String aName) {
- return "set" + aName.substring(0, 1).toUpperCase() + aName.substring(1);
- }
-
- /**
- * Adds a given setter name to the setters.
- *
- * @param aName
- * @return Reference to the current object to allow call chaining.
- */
- public SetterConfiguration add(String aName) {
- final String name = createSetterName(aName);
- int oldlen = _setters.size();
- List<Method> methods = new ArrayList<Method>();
- CollectionFilter.filter(getAllSetters(_class, _publicOnly), methods,
- new Condition<Method>() {
- @Override
- public boolean matches(Method aObject) {
- return aObject.getName().equals(name);
- }
-
- });
- if (methods.size() == 0 ) {
- throw new IllegalArgumentException("No setter found for '" + aName
- + "' 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 add(final Class aType) {
- List<Method> result = new ArrayList<Method>();
- CollectionFilter.filter(getAllSetters(_class, _publicOnly), result,
- new Condition<Method>() {
- @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<Method> getAllSetters(Class aClass,
- boolean aPublicOnly) {
- List<Method> result = new ArrayList<Method>();
- 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 method) {
- return new ParameterValues(
- new String[] { getSetterName(method) }, new Class[] { method
- .getParameterTypes()[0] });
- }
-
- private static final List<Method> getAllMethods(Class aClass) {
- return ReflectionUtils.getAllMethods(aClass);
- }
-
- /**
- * Gets the required interfaces based on the configured setteres.
- *
- * @return List of required interfaces.
- */
- public List<RequiredInterface> getRequiredInterfaces() {
- List<RequiredInterface> result = new ArrayList<RequiredInterface>();
- 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) {
- String name = createSetterName(aMethod);
- for (Method method : _setters.keySet()) {
- if (method.getName().equals(name)) {
- return _setters.get(method);
- }
- }
- throw new IllegalArgumentException("No setter method '" + name
- + "' found");
- }
-
- /**
- * Gets the setter name for a given setter method. This is the name of the
- * setter without the "set" prefix and with the first character converted to
- * lowercase.
- *
- * @param aMethod
- * Method.
- * @return Setter name.
- */
- private static String getSetterName(Method aMethod) {
- String result = aMethod.getName().substring(3);
- return result.substring(0, 1).toLowerCase() + result.substring(1);
- }
-
- public List<Method> getSetters() {
- return new ArrayList<Method>(_setters.keySet());
- }