From: Erik Brakkee Date: Tue, 10 Jun 2008 21:42:53 +0000 (+0000) Subject: (no commit message) X-Git-Tag: wamblee-utils-0.7~673 X-Git-Url: http://wamblee.org/gitweb/?a=commitdiff_plain;ds=sidebyside;h=2680fc967c8e19bcc91d3a62cdb8e7ad25aa204e;hp=7d65731ca9f92b8b448433389f9ca62aa28081df;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 581c5b59..b2ab5f6d 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 @@ -21,12 +21,16 @@ 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; @@ -45,7 +49,7 @@ public class SetterConfiguration { private Class _class; private boolean _publicOnly; - private List> _setters; + private Map _setters; /** * Constructs the setter configuration. By default all setters are added. @@ -56,19 +60,27 @@ public class SetterConfiguration { public SetterConfiguration(Class aClass) { _class = aClass; _publicOnly = true; - _setters = getAllSetters(_class, _publicOnly); + initSetters(); + } + + private void initSetters() { + _setters = new HashMap(); + for (Method method: getAllSetters(_class, _publicOnly) ) { + _setters.put(method, createParameterValues(method)); + } } /** * Called to set whether non-public setters are also used. By default only - * public setters are used. + * public setters are used. This resets all changes made and selects all + * public setters if non-public is false and all setters if it is true. * * @param aIsNonPublic * Non public flag. */ public void setNonPublic(boolean aIsNonPublic) { _publicOnly = !aIsNonPublic; - _setters = getAllSetters(_class, _publicOnly); + initSetters(); } /** @@ -90,21 +102,15 @@ public class SetterConfiguration { */ public SetterConfiguration remove(String aName) { final String name = createSetterName(aName); - List> setters = new ArrayList>(); - CollectionFilter.filter(_setters, setters, - new Condition>() { - @Override - public boolean matches(Pair aObject) { - return !aObject.getFirst().getName().equals(name); - } - - }); - if (_setters.size() == setters.size()) { - throw new IllegalArgumentException( - "No setter configured by the name of '" + aName + "'"); + Map setters = new HashMap(); + for (Method method : _setters.keySet()) { + if (method.getName().equals(name)) { + _setters.remove(method); + return this; + } } - _setters = setters; - return this; + throw new IllegalArgumentException( + "No setter configured by the name of '" + aName + "'"); } /** @@ -128,18 +134,65 @@ public class SetterConfiguration { public SetterConfiguration add(String aName) { final String name = createSetterName(aName); int oldlen = _setters.size(); - CollectionFilter.filter(getAllSetters(_class, false), _setters, - new Condition>() { + List methods = new ArrayList(); + CollectionFilter.filter(getAllSetters(_class, _publicOnly), methods, + new Condition() { @Override - public boolean matches(Pair aObject) { - return aObject.getFirst().getName().equals(name); + public boolean matches(Method aObject) { + return aObject.getName().equals(name); } }); - if (_setters.size() == oldlen) { + 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 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; } @@ -148,35 +201,30 @@ public class SetterConfiguration { * * @return List of all setters. */ - private static List> getAllSetters( - Class aClass, boolean aPublicOnly) { - List> result = new ArrayList>(); + private 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); - String name = getSetterName(method); - result - .add(new Pair(method, - new ParameterValues(new String[] { name }, - new Class[] { method - .getParameterTypes()[0] }))); + 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 getAllMethods(Class aClass) { - List result = new ArrayList(); - result.addAll(Arrays.asList(aClass.getDeclaredMethods())); - Class superClass = aClass.getSuperclass(); - if ( superClass != null ) { - result.addAll(getAllMethods(superClass)); - } - return result; - } + return ReflectionUtils.getAllMethods(aClass); + } /** * Gets the required interfaces based on the configured setteres. @@ -185,8 +233,8 @@ public class SetterConfiguration { */ public List getRequiredInterfaces() { List result = new ArrayList(); - for (Pair method : _setters) { - result.addAll(method.getSecond().getRequiredInterfaces()); + for (Method method : _setters.keySet()) { + result.addAll(_setters.get(method).getRequiredInterfaces()); } return result; } @@ -204,9 +252,8 @@ public class SetterConfiguration { throw new IllegalArgumentException("Object '" + aObject + "' is not an instance of " + _class.getName()); } - for (Pair setter : _setters) { - Method method = setter.getFirst(); - ParameterValues values = setter.getSecond(); + for (Method method : _setters.keySet()) { + ParameterValues values = _setters.get(method); try { method.invoke(aObject, values.values(aScope)); @@ -231,9 +278,9 @@ public class SetterConfiguration { */ public ParameterValues values(String aMethod) { String name = createSetterName(aMethod); - for (Pair method : _setters) { - if (method.getFirst().getName().equals(name)) { - return method.getSecond(); + for (Method method : _setters.keySet()) { + if (method.getName().equals(name)) { + return _setters.get(method); } } throw new IllegalArgumentException("No setter method '" + name @@ -254,4 +301,7 @@ public class SetterConfiguration { return result.substring(0, 1).toLowerCase() + result.substring(1); } + public List getSetters() { + return new ArrayList(_setters.keySet()); + } } diff --git a/system/general/src/test/java/org/wamblee/system/adapters/SetterConfigurationTest.java b/system/general/src/test/java/org/wamblee/system/adapters/SetterConfigurationTest.java index 2b7bd918..730dfe6d 100644 --- a/system/general/src/test/java/org/wamblee/system/adapters/SetterConfigurationTest.java +++ b/system/general/src/test/java/org/wamblee/system/adapters/SetterConfigurationTest.java @@ -15,11 +15,14 @@ */ package org.wamblee.system.adapters; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import javax.sql.DataSource; + import org.wamblee.system.core.DefaultProvidedInterface; import org.wamblee.system.core.ProvidedInterface; import org.wamblee.system.core.RequiredInterface; @@ -201,7 +204,7 @@ public class SetterConfigurationTest extends AdapterTestCase { assertNull(obj.getPort()); } - public void testAdd() { + public void testAddByName() { SetterConfiguration config = new SetterConfiguration(X6.class); config.clear().add("host"); List required = config.getRequiredInterfaces(); @@ -222,6 +225,44 @@ public class SetterConfigurationTest extends AdapterTestCase { assertEquals("hello", obj.getHost()); assertNull(obj.getPort()); } + + public void testAddByType() { + SetterConfiguration config = new SetterConfiguration(X6.class); + config.clear().add(String.class); + List required = config.getRequiredInterfaces(); + Collections.sort(required, new RequiredInterfaceComparator()); + assertEquals(1, required.size()); + assertEquals("host", required.get(0).getName()); + + ProvidedInterface provided0 = new DefaultProvidedInterface("janse", + String.class); + required.get(0).setProvider(provided0); + provided0.publish("hello", _scope); + + X6 obj = new X6(); + assertNull(obj.getHost()); + assertNull(obj.getPort()); + + config.inject(_scope, obj); + assertEquals("hello", obj.getHost()); + assertNull(obj.getPort()); + } + + public void testAddPrivate() { + X5 obj = new X5(); + final SetterConfiguration config = new SetterConfiguration(X5.class); + AssertionUtils.assertException(new AssertionUtils.ErroneousCode() { + @Override + public void run() throws Exception { + config.add("xyz"); + } + }, IllegalArgumentException.class); + + config.setNonPublic(true); + config.clear(); + config.add("xyz"); + assertEquals(1, config.getRequiredInterfaces().size()); + } public void testAddNonExisting() { final SetterConfiguration config = new SetterConfiguration(X6.class); @@ -233,6 +274,23 @@ public class SetterConfigurationTest extends AdapterTestCase { config.add("bladibla"); } }, IllegalArgumentException.class); + AssertionUtils.assertException(new AssertionUtils.ErroneousCode() { + @Override + public void run() throws Exception { + config.add(DataSource.class); + } + }, IllegalArgumentException.class); + } + + public void testAddByTypeNonUnique() { + final SetterConfiguration config = new SetterConfiguration(X11.class); + config.clear(); + AssertionUtils.assertException(new AssertionUtils.ErroneousCode() { + @Override + public void run() throws Exception { + config.add(String.class); + } + }, IllegalArgumentException.class); } public void testRemove() { @@ -267,4 +325,15 @@ public class SetterConfigurationTest extends AdapterTestCase { } }, IllegalArgumentException.class); } + + public void testOverridingSetters() { + SetterConfiguration config = new SetterConfiguration(X10.class); + assertEquals(2, config.getRequiredInterfaces().size()); + List methods = config.getSetters(); + assertEquals(2, methods.size()); + for (Method method: methods) { + assertEquals(X10.class, method.getDeclaringClass()); + } + + } } diff --git a/system/general/src/test/java/org/wamblee/system/adapters/X10.java b/system/general/src/test/java/org/wamblee/system/adapters/X10.java new file mode 100644 index 00000000..fc8b90a5 --- /dev/null +++ b/system/general/src/test/java/org/wamblee/system/adapters/X10.java @@ -0,0 +1,26 @@ +package org.wamblee.system.adapters; + +public class X10 extends X6 { + + + @Override + public void setHost(String aHost) { + super.setHost(aHost); + } + + @Override + public String getHost() { + return super.getHost(); + } + + @Override + public Integer getPort() { + return super.getPort(); + } + + @Override + public void setPort(Integer aPort) { + super.setPort(aPort); + } + +} diff --git a/system/general/src/test/java/org/wamblee/system/adapters/X11.java b/system/general/src/test/java/org/wamblee/system/adapters/X11.java new file mode 100644 index 00000000..4ddc11eb --- /dev/null +++ b/system/general/src/test/java/org/wamblee/system/adapters/X11.java @@ -0,0 +1,14 @@ +package org.wamblee.system.adapters; + +public class X11 { + + + public void setX(String aValue) { + + } + + public void setY(String aValue) { + + } + +}