2 * Copyright 2008 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.system.adapters;
18 import java.awt.CompositeContext;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.util.ArrayList;
22 import java.util.List;
24 import org.wamblee.collections.CollectionFilter;
25 import org.wamblee.conditions.Condition;
26 import org.wamblee.conditions.FixedCondition;
27 import org.wamblee.general.Pair;
28 import org.wamblee.system.core.DefaultProvidedInterface;
29 import org.wamblee.system.core.DefaultRequiredInterface;
30 import org.wamblee.system.core.ProvidedInterface;
31 import org.wamblee.system.core.RequiredInterface;
32 import org.wamblee.system.core.Scope;
33 import org.wamblee.system.core.SystemAssemblyException;
36 * Represents the configuration for exposing the setters of a class as required
39 * @author Erik Brakkee
41 public class SetterConfiguration {
45 private List<Pair<Method, ParameterValues>> _setters;
48 * Constructs the setter configuration. By default all setters are added.
51 * Class which is being configured.
53 public SetterConfiguration(Class aClass) {
55 _setters = getAllSetters();
59 * Removes all setters.
61 * @return Reference to the current object to allow call chaining.
63 public SetterConfiguration clear() {
69 * Removes a setter from the set of methods.
72 * Name of the setter to remove (without the "set" prefix).
73 * @return Reference to the current object to allow call chaining.
75 public SetterConfiguration remove(String aName) {
76 final String name = createSetterName(aName);
77 List<Pair<Method,ParameterValues>> setters =
78 new ArrayList<Pair<Method,ParameterValues>>();
79 CollectionFilter.filter(_setters, setters, new Condition<Pair<Method,ParameterValues>>() {
81 public boolean matches(Pair<Method,ParameterValues> aObject) {
82 return !aObject.getFirst().getName().equals(name);
86 if ( _setters.size() == setters.size()) {
87 throw new IllegalArgumentException("No setter configured by the name of '" + aName + "'");
94 * Creates the name of a setter based on the name of the setter without
96 * @param aName Setter name.
97 * @return Setter name.
99 private String createSetterName(String aName) {
100 return "set" + aName.substring(0, 1).toUpperCase()
101 + aName.substring(1);
105 * Adds a given setter name to the setters.
107 * @return Reference to the current object to allow call chaining.
109 public SetterConfiguration add(String aName) {
110 final String name = createSetterName(aName);
111 int oldlen = _setters.size();
112 CollectionFilter.filter(getAllSetters(), _setters,
113 new Condition<Pair<Method,ParameterValues>>() {
115 public boolean matches(Pair<Method,ParameterValues> aObject) {
116 return aObject.getFirst().getName().equals(name);
120 if ( _setters.size() == oldlen) {
121 throw new IllegalArgumentException("No setter found for '" + aName + "'");
127 * Gets all setters for the current class.
128 * @return List of all setters.
130 private List<Pair<Method, ParameterValues>> getAllSetters() {
131 List<Pair<Method,ParameterValues>> result =
132 new ArrayList<Pair<Method, ParameterValues>>();
133 for (Method method : _class.getMethods()) {
134 if (method.getName().startsWith("set")
135 && method.getParameterTypes().length == 1) {
136 String name = getSetterName(method);
137 result.add(new Pair<Method,ParameterValues>(method,
139 new String[] { name }, new Class[] { method.getParameterTypes()[0] })));
146 * Gets the required interfaces based on the configured setteres.
147 * @return List of required interfaces.
149 public List<RequiredInterface> getRequiredInterfaces() {
150 List<RequiredInterface> result = new ArrayList<RequiredInterface>();
151 for (Pair<Method,ParameterValues> method: _setters) {
152 result.addAll(method.getSecond().getRequiredInterfaces());
159 * Invokes all configured setters with the appropriate values.
160 * @param aScope Scope within which invocation takes place.
161 * @param aObject Object on which the invocation takes place.
163 public void inject(Scope aScope, Object aObject) {
164 if ( !_class.isInstance(aObject)) {
165 throw new IllegalArgumentException("Object '" + aObject + "' is not an instance of "
168 for (Pair<Method,ParameterValues> setter: _setters) {
169 Method method = setter.getFirst();
170 ParameterValues values = setter.getSecond();
173 method.invoke(aObject, values.values(aScope));
174 } catch (IllegalAccessException e) {
175 throw new SystemAssemblyException("Problem invoking " + method + " with " + values, e);
176 } catch (InvocationTargetException e) {
177 throw new SystemAssemblyException("Problem invoking " + method + " with " + values, e);
183 * Returns the parameter values for allowing detailed configuration of how
184 * parameter values are set.
185 * @param aSetter Setter name without the "set" prefix with the first
186 * character converted to lower case.
187 * @return Parameter values.
189 public ParameterValues values(String aMethod) {
190 String name = createSetterName(aMethod);
191 for (Pair<Method,ParameterValues> method: _setters) {
192 if ( method.getFirst().getName().equals(name) ) {
193 return method.getSecond();
196 throw new IllegalArgumentException("No setter method '" + name + "' found");
200 * Gets the setter name for a given setter method. This is the name of the
201 * setter without the "set" prefix and with the first character converted to
203 * @param aMethod Method.
204 * @return Setter name.
206 private String getSetterName(Method aMethod) {
207 String result = aMethod.getName().substring(3);
208 return result.substring(0,1).toLowerCase() + result.substring(1);