From 9863227742d5925024fbd6dfc1d06838af1d5d94 Mon Sep 17 00:00:00 2001 From: erik Date: Sun, 13 Apr 2008 09:48:05 +0000 Subject: [PATCH] --- trunk/system/general/pom.xml | 5 + .../wamblee/system/adapters/ClassAdapter.java | 51 ++++++ .../system/adapters/ClassConfiguration.java | 88 ++++++++++ .../adapters/ConstructorConfiguration.java | 165 ++++++++++++++++++ .../system/adapters/FixedValueProvider.java | 32 ++++ .../system/adapters/ParameterValues.java | 93 ++++++++++ .../adapters/RequiredInterfaceProvider.java | 38 ++++ .../system/adapters/ValueProvider.java | 23 +++ .../org/wamblee/system/core/DefaultScope.java | 4 +- .../java/org/wamblee/system/core/Scope.java | 2 +- .../system/adapters/AdapterTestCase.java | 37 ++++ .../system/adapters/ClassAdapterTest.java | 52 ++++++ .../adapters/ClassConfigurationTest.java | 53 ++++++ .../ConstructorConfigurationTest.java | 146 ++++++++++++++++ .../java/org/wamblee/system/adapters/X1.java | 26 +++ .../java/org/wamblee/system/adapters/X2.java | 26 +++ .../java/org/wamblee/system/adapters/X3.java | 26 +++ .../java/org/wamblee/system/adapters/X4.java | 30 ++++ .../org/wamblee/system/core/Application.java | 4 +- .../system/spring/RequiredServiceBean.java | 2 +- .../system/spring/SpringComponentTest.java | 6 +- 21 files changed, 900 insertions(+), 9 deletions(-) create mode 100644 trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassAdapter.java create mode 100644 trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassConfiguration.java create mode 100644 trunk/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java create mode 100644 trunk/system/general/src/main/java/org/wamblee/system/adapters/FixedValueProvider.java create mode 100644 trunk/system/general/src/main/java/org/wamblee/system/adapters/ParameterValues.java create mode 100644 trunk/system/general/src/main/java/org/wamblee/system/adapters/RequiredInterfaceProvider.java create mode 100644 trunk/system/general/src/main/java/org/wamblee/system/adapters/ValueProvider.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/AdapterTestCase.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassAdapterTest.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassConfigurationTest.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/ConstructorConfigurationTest.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/X1.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/X2.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/X3.java create mode 100644 trunk/system/general/src/test/java/org/wamblee/system/adapters/X4.java diff --git a/trunk/system/general/pom.xml b/trunk/system/general/pom.xml index 4f770c43..a08f0844 100644 --- a/trunk/system/general/pom.xml +++ b/trunk/system/general/pom.xml @@ -19,6 +19,11 @@ commons-logging commons-logging + + org.wamblee + wamblee-support-general + 0.2-SNAPSHOT + org.wamblee wamblee-support-general diff --git a/trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassAdapter.java b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassAdapter.java new file mode 100644 index 00000000..0de8322d --- /dev/null +++ b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassAdapter.java @@ -0,0 +1,51 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import org.wamblee.system.core.AbstractComponent; +import org.wamblee.system.core.Component; +import org.wamblee.system.core.ProvidedInterface; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; + +public class ClassAdapter extends AbstractComponent { + + private ClassConfiguration _classConfig; + + public ClassAdapter(String aName, ClassConfiguration aClassConfig) { + super(aName, + aClassConfig.getProvidedInterfaces(), + aClassConfig.getRequiredInterface()); + _classConfig = aClassConfig; + } + + @Override + protected Object doStart(Scope aScope) { + + Object obj = _classConfig.create(aScope); + + for (ProvidedInterface provided: getProvidedInterfaces()) { + addInterface(provided, obj, aScope); + } + + return obj; + } + + @Override + protected void doStop(Object aRuntime) { + // Empty. + } +} diff --git a/trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassConfiguration.java b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassConfiguration.java new file mode 100644 index 00000000..3756bd3b --- /dev/null +++ b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ClassConfiguration.java @@ -0,0 +1,88 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.wamblee.collections.CollectionFilter; +import org.wamblee.conditions.Condition; +import org.wamblee.system.core.DefaultProvidedInterface; +import org.wamblee.system.core.DefaultRequiredInterface; +import org.wamblee.system.core.ProvidedInterface; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; +import org.wamblee.system.core.SystemAssemblyException; + +/** + * The class configuration encapsulates the knowledge of how to wrap a class as a component. + * In particular, it provides: + *
    + *
  • Selection of a constructor using explicit selection + * {@link #select(Class...)} or using the most greedy constructor + * {@link #greedy()}. + *
  • + *
  • + * Selection of methods to invoke to inject other objects into the object. + *
  • + *
  • Selection of fields to set. + *
  • + *
+ * + * @author Erik Brakkee + * + */ +public class ClassConfiguration { + + private Class _class; + private ConstructorConfiguration _constructorConfig; + + /** + * Constructs the configuration. By default no constructor is selected and + * one of {@link #select(Class...)} or + * {@link #greedy()} must be called. + * @param aClass Class to construct. + */ + public ClassConfiguration(Class aClass) { + _class = aClass; + _constructorConfig = new ConstructorConfiguration(aClass); + } + + public ConstructorConfiguration getConstructorConfig() { + return _constructorConfig; + } + + /** + * Creates the object in the given scope. + * @param aScope Scope containing required interfaces for this object. + * @return object. + */ + public Object create(Scope aScope) { + return _constructorConfig.create(aScope); + } + + public ProvidedInterface[] getProvidedInterfaces() { + return new ProvidedInterface[] { + new DefaultProvidedInterface("provided", _class) + }; + } + + public RequiredInterface[] getRequiredInterface() { + return _constructorConfig.getRequiredInterfaces().toArray(new RequiredInterface[0]); + } +} diff --git a/trunk/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java new file mode 100644 index 00000000..2725d033 --- /dev/null +++ b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java @@ -0,0 +1,165 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Member; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.wamblee.collections.CollectionFilter; +import org.wamblee.conditions.Condition; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; +import org.wamblee.system.core.SystemAssemblyException; + +public class ConstructorConfiguration { + private Class _class; + private Constructor _constructor; + private ParameterValues _values; + private boolean _publicOnly; + + /** + * Constructs the configuration. By default no constructor is selected and + * one of {@link #select(Class...)} or + * {@link #greedy()} must be called. + * @param aClass Class to construct. + */ + public ConstructorConfiguration(Class aClass) { + _class = aClass; + _constructor = null; + _publicOnly = true; + } + + /** + * Sets whether or no non public constructors are also considered. + * Reset the choice of a constructor. + * @param aNonPublic + * @return + */ + public ConstructorConfiguration setNonPublic(boolean aNonPublic) { + _publicOnly = !aNonPublic; + _constructor = null; + _values = null; + return this; + } + + /** + * Selects an explicit constructor. + * @param aTypes Arguments of the constructor. + * @return Return the injector to allow call chaining. + */ + public ConstructorConfiguration select(Class... aTypes) { + try { + _constructor = _class.getDeclaredConstructor(aTypes); + } catch (Exception e) { + throw new SystemAssemblyException(e.getMessage(), e); + } + resetValues(); + return this; + } + + /** + * Selects the greediest constructor. + * @return The injector to allow call chaining. + * @throws SystemAssemblyException if the greediest constructor cannot be uniquely + * identified. + */ + public ConstructorConfiguration greedy() { + Constructor[] declared = _class.getDeclaredConstructors(); + if (declared.length == 0) { + throw new SystemAssemblyException("Class '" + _class + + " is an interface, primitive type, or array"); + } + int max = -1; + List> checked = new ArrayList>(); + CollectionFilter.filter(Arrays.asList(declared), checked, + new Condition>() { + @Override + public boolean matches(Constructor aObject) { + if ( !_publicOnly ) { + return true; + } else { + return Modifier.isPublic(aObject.getModifiers()); + } + } + }); + for (Constructor ctor : checked) { + if (ctor.getParameterTypes().length > max) { + max = ctor.getParameterTypes().length; + } + } + final int max2 = max; + List> ctors = checked; + List> longest = new ArrayList>(); + CollectionFilter.filter(ctors, longest, + new Condition>() { + @Override + public boolean matches(Constructor aObject) { + return aObject.getParameterTypes().length == max2; + } + }); + if (longest.size() > 1) { + throw new SystemAssemblyException( + "Greediest constructor cannot be uniquely determined"); + } + _constructor = longest.get(0); + resetValues(); + return this; + } + + public ParameterValues getParameters() { + getConstructor(); // initialize constructor if needed. + return _values; + } + + /** + * Resets the values. + */ + private void resetValues() { + _constructor.setAccessible(true); + _values = new ParameterValues(_constructor.getParameterTypes()); + } + + /** + * Creates the object in the given scope. + * @param aScope Scope containing required interfaces for this object. + * @return object. + */ + public Object create(Scope aScope) { + Object[] values = _values.values(aScope); + try { + return getConstructor().newInstance(values); + } catch (Exception e) { + throw new SystemAssemblyException("Could not construct object " + + getConstructor() + " " + Arrays.asList(values), e); + } + } + + public List getRequiredInterfaces() { + getConstructor(); // initialize constructor if needed. + return _values.getRequiredInterfaces(); + } + + private Constructor getConstructor() { + if (_constructor == null ) { + greedy(); + } + return _constructor; + } +} diff --git a/trunk/system/general/src/main/java/org/wamblee/system/adapters/FixedValueProvider.java b/trunk/system/general/src/main/java/org/wamblee/system/adapters/FixedValueProvider.java new file mode 100644 index 00000000..e36ecfb2 --- /dev/null +++ b/trunk/system/general/src/main/java/org/wamblee/system/adapters/FixedValueProvider.java @@ -0,0 +1,32 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import org.wamblee.system.core.Scope; + +public class FixedValueProvider implements ValueProvider { + + private Object _value; + + public FixedValueProvider(Object aValue) { + _value = aValue; + } + + @Override + public Object getValue(Scope aScope) { + return _value; + } +} diff --git a/trunk/system/general/src/main/java/org/wamblee/system/adapters/ParameterValues.java b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ParameterValues.java new file mode 100644 index 00000000..41348190 --- /dev/null +++ b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ParameterValues.java @@ -0,0 +1,93 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import java.util.ArrayList; +import java.util.List; + +import org.wamblee.system.core.DefaultRequiredInterface; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; + +public class ParameterValues { + private Class[] _types; + private ValueProvider[] _values; + + /** + * Constructs the configuration. By default no constructor is selected and + * one of {@link #select(Class...)} or + * {@link #greedy()} must be called. + * @param aClass Class to construct. + */ + public ParameterValues(Class[] aTypes) { + _types = aTypes; + resetValues(); + } + + public Class[] getTypes() { + return _types; + } + + /** + * Sets argument i to be optional, meaning that null is allowed to be passed in. + * @param aArg Argument to set. + */ + public ParameterValues setOptional(int aArg) { + _values[aArg] = new RequiredInterfaceProvider(new DefaultRequiredInterface( + "arg" + aArg, _types[aArg], true)); + return this; + } + + /** + * Sets the argument i to a fixed value. + * @param aArg Argument to set. + * @param aValue Value. + */ + public ParameterValues setValue(int aArg, Object aValue) { + _values[aArg] = new FixedValueProvider(aValue); + return this; + } + + /** + * Resets the values. + */ + private void resetValues() { + _values = new ValueProvider[_types.length]; + for (int i = 0; i < _values.length; i++) { + _values[i] = new RequiredInterfaceProvider(new DefaultRequiredInterface( + "arg" + i, _types[i])); + } + } + + public List getRequiredInterfaces() { + List result = new ArrayList(); + for (ValueProvider provider: _values) { + if ( provider instanceof RequiredInterfaceProvider) { + result.add( ((RequiredInterfaceProvider)provider).getRequiredInterface()); + } + } + return result; + } + + public Object[] values(Scope aScope) { + Object[] values = new Object[_values.length]; + for (int i = 0; i < _values.length; i++) { + values[i] = _values[i].getValue(aScope); + } + return values; + } + +} diff --git a/trunk/system/general/src/main/java/org/wamblee/system/adapters/RequiredInterfaceProvider.java b/trunk/system/general/src/main/java/org/wamblee/system/adapters/RequiredInterfaceProvider.java new file mode 100644 index 00000000..76d2d3dc --- /dev/null +++ b/trunk/system/general/src/main/java/org/wamblee/system/adapters/RequiredInterfaceProvider.java @@ -0,0 +1,38 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; + +public class RequiredInterfaceProvider implements ValueProvider { + + private RequiredInterface _required; + + public RequiredInterfaceProvider(RequiredInterface aRequired) { + _required = aRequired; + } + + @Override + public Object getValue(Scope aScope) { + return aScope.getInterfaceImplementation(_required.getProvider(), Object.class); + } + + public RequiredInterface getRequiredInterface() { + return _required; + } + +} diff --git a/trunk/system/general/src/main/java/org/wamblee/system/adapters/ValueProvider.java b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ValueProvider.java new file mode 100644 index 00000000..03eac1e9 --- /dev/null +++ b/trunk/system/general/src/main/java/org/wamblee/system/adapters/ValueProvider.java @@ -0,0 +1,23 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import org.wamblee.system.core.Scope; + +public interface ValueProvider { + + Object getValue(Scope aScope); +} diff --git a/trunk/system/general/src/main/java/org/wamblee/system/core/DefaultScope.java b/trunk/system/general/src/main/java/org/wamblee/system/core/DefaultScope.java index 8b0c88ef..b57f51f6 100644 --- a/trunk/system/general/src/main/java/org/wamblee/system/core/DefaultScope.java +++ b/trunk/system/general/src/main/java/org/wamblee/system/core/DefaultScope.java @@ -83,7 +83,7 @@ public class DefaultScope implements Scope { } @Override - public T retrieveInterfaceImplementation(ProvidedInterface aInterface, + public T getInterfaceImplementation(ProvidedInterface aInterface, Class aType) { if ( aInterface == null ) { return null; @@ -96,7 +96,7 @@ public class DefaultScope implements Scope { ProvidedInterfaceImplementation provided = _provided.get(id); if (provided == null) { for (Scope parent : _parents) { - T impl = parent.retrieveInterfaceImplementation(aInterface, aType); + T impl = parent.getInterfaceImplementation(aInterface, aType); if ( impl != null ) { return impl; } diff --git a/trunk/system/general/src/main/java/org/wamblee/system/core/Scope.java b/trunk/system/general/src/main/java/org/wamblee/system/core/Scope.java index 829435f6..9db462f5 100644 --- a/trunk/system/general/src/main/java/org/wamblee/system/core/Scope.java +++ b/trunk/system/general/src/main/java/org/wamblee/system/core/Scope.java @@ -66,7 +66,7 @@ public interface Scope { * @param aType Type of implementation that is expected. * @return Retrieved interface. */ - T retrieveInterfaceImplementation(ProvidedInterface aProvided, Class aType ); + T getInterfaceImplementation(ProvidedInterface aProvided, Class aType ); /** * Gets the runtime for a component. diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/AdapterTestCase.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/AdapterTestCase.java new file mode 100644 index 00000000..cf67b247 --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/AdapterTestCase.java @@ -0,0 +1,37 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import org.wamblee.system.core.DefaultScope; +import org.wamblee.system.core.ProvidedInterface; +import org.wamblee.system.core.Scope; +import org.wamblee.test.EventTracker; + +import junit.framework.TestCase; + +public class AdapterTestCase extends TestCase { + + protected Scope _scope; + static EventTracker EVENT_TRACKER; + + @Override + protected void setUp() throws Exception { + super.setUp(); + EVENT_TRACKER = new EventTracker(); + _scope = new DefaultScope(new ProvidedInterface[0]); + } + +} diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassAdapterTest.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassAdapterTest.java new file mode 100644 index 00000000..925f3ef9 --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassAdapterTest.java @@ -0,0 +1,52 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import org.wamblee.system.core.Component; +import org.wamblee.system.core.Container; +import org.wamblee.system.core.DefaultScope; +import org.wamblee.system.core.ProvidedInterface; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; +import org.wamblee.test.AssertionUtils; + +import junit.framework.TestCase; + +public class ClassAdapterTest extends AdapterTestCase { + + + public void testSimpleConstructorInjection() { + ClassConfiguration x1Config = new ClassConfiguration(X1.class); + x1Config.getConstructorConfig().getParameters().setValue(0, "hello"); + ClassConfiguration x4Config = new ClassConfiguration(X4.class); + + ClassAdapter x1Adapter = new ClassAdapter("x1", x1Config); + ClassAdapter x4Adapter = new ClassAdapter("x4", x4Config); + + Container container = new Container("top", new Component[] { + x1Adapter, x4Adapter + }, new ProvidedInterface[0], new RequiredInterface[0]); + + Scope scope = container.start(); + AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)" }, + EVENT_TRACKER.getEvents(Thread.currentThread()).toArray()); + + Object obj = scope.getRuntime(x1Adapter); + assertTrue(obj instanceof X1); + obj = scope.getRuntime(x4Adapter); + assertTrue(obj instanceof X4); + } +} diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassConfigurationTest.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassConfigurationTest.java new file mode 100644 index 00000000..2ac1484d --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/ClassConfigurationTest.java @@ -0,0 +1,53 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import java.util.List; + +import junit.framework.TestCase; + +import org.wamblee.system.core.DefaultProvidedInterface; +import org.wamblee.system.core.DefaultScope; +import org.wamblee.system.core.ProvidedInterface; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; +import org.wamblee.test.AssertionUtils; +import org.wamblee.test.EventTracker; + +public class ClassConfigurationTest extends AdapterTestCase { + + + public void testConstructorConfig() { + ClassConfiguration classConfig = new ClassConfiguration(X1.class); + + ConstructorConfiguration config = classConfig.getConstructorConfig() + .greedy(); + ProvidedInterface provided = new DefaultProvidedInterface("arg", + String.class); + List required = config.getRequiredInterfaces(); + + assertEquals(1, required.size()); + assertFalse(required.get(0).isOptional()); + + required.get(0).setProvider(provided); + + provided.publish("hello", _scope); + config.create(_scope); + + AssertionUtils.assertEquals(new String[] { "x1(hello)" }, AdapterTestCase.EVENT_TRACKER + .getEvents(Thread.currentThread()).toArray()); + } +} diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/ConstructorConfigurationTest.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/ConstructorConfigurationTest.java new file mode 100644 index 00000000..1ee899f8 --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/ConstructorConfigurationTest.java @@ -0,0 +1,146 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +import java.util.List; + +import org.wamblee.system.core.DefaultProvidedInterface; +import org.wamblee.system.core.DefaultScope; +import org.wamblee.system.core.ProvidedInterface; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; +import org.wamblee.system.core.SystemAssemblyException; +import org.wamblee.test.AssertionUtils; +import org.wamblee.test.EventTracker; + +import junit.framework.TestCase; + +public class ConstructorConfigurationTest extends AdapterTestCase { + + public void testGreedyUnique() { + ConstructorConfiguration config = new ConstructorConfiguration(X1.class) + .greedy(); + ProvidedInterface provided = new DefaultProvidedInterface("arg", + String.class); + List required = config.getRequiredInterfaces(); + + assertEquals(1, required.size()); + assertFalse(required.get(0).isOptional()); + + required.get(0).setProvider(provided); + + provided.publish("hello", _scope); + config.create(_scope); + + AssertionUtils.assertEquals(new String[] { "x1(hello)" }, AdapterTestCase.EVENT_TRACKER + .getEvents(Thread.currentThread()).toArray()); + } + + public void testGreedyNonUnique() { + try { + ConstructorConfiguration config = new ConstructorConfiguration( + X2.class).greedy(); + } catch (SystemAssemblyException e) { + // e.printStackTrace(); + return; + } + fail(); + } + + public void testSpecificConstructor() { + ConstructorConfiguration config = new ConstructorConfiguration(X2.class) + .select(String.class); + ProvidedInterface provided = new DefaultProvidedInterface("arg", + String.class); + List required = config.getRequiredInterfaces(); + + assertEquals(1, required.size()); + required.get(0).setProvider(provided); + + provided.publish("hello", _scope); + config.create(_scope); + + AssertionUtils.assertEquals(new String[] { "x2(hello)" }, AdapterTestCase.EVENT_TRACKER + .getEvents(Thread.currentThread()).toArray()); + } + + public void testSetValue() { + ConstructorConfiguration config = new ConstructorConfiguration(X1.class) + .greedy(); + config.getParameters().setValue(0, "bla"); + + config.create(_scope); + + AssertionUtils.assertEquals(new String[] { "x1(bla)" }, AdapterTestCase.EVENT_TRACKER + .getEvents(Thread.currentThread()).toArray()); + } + + public void testOptionalValueProvided() { + ConstructorConfiguration config = new ConstructorConfiguration(X1.class) + .greedy(); + config.getParameters().setOptional(0); + ProvidedInterface provided = new DefaultProvidedInterface("arg", + String.class); + List required = config.getRequiredInterfaces(); + + assertEquals(1, required.size()); + required.get(0).setProvider(provided); + + provided.publish("hello", _scope); + config.create(_scope); + + AssertionUtils.assertEquals(new String[] { "x1(hello)" }, AdapterTestCase.EVENT_TRACKER + .getEvents(Thread.currentThread()).toArray()); + } + + public void testOptionalValueMissing() { + ConstructorConfiguration config = new ConstructorConfiguration(X1.class) + .greedy(); + config.getParameters().setOptional(0); + assertTrue(config.getRequiredInterfaces().get(0).isOptional()); + + config.create(_scope); + + AssertionUtils.assertEquals(new String[] { "x1(null)" }, AdapterTestCase.EVENT_TRACKER + .getEvents(Thread.currentThread()).toArray()); + } + + public void testIgnoredNonPublic() { + ConstructorConfiguration config = new ConstructorConfiguration(X3.class) + .greedy(); + List required = config.getRequiredInterfaces(); + assertEquals(0, config.getParameters().getTypes().length); + } + + public void testNonPublicConstructor() { + ConstructorConfiguration config = new ConstructorConfiguration(X3.class) + .setNonPublic(true).greedy(); + ProvidedInterface provided = new DefaultProvidedInterface("arg", + String.class); + List required = config.getRequiredInterfaces(); + + assertEquals(1, required.size()); + assertFalse(required.get(0).isOptional()); + + required.get(0).setProvider(provided); + + provided.publish("hello", _scope); + config.create(_scope); + + AssertionUtils.assertEquals(new String[] { "x3(hello)" }, AdapterTestCase.EVENT_TRACKER + .getEvents(Thread.currentThread()).toArray()); + } +} diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/X1.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X1.java new file mode 100644 index 00000000..b17a27c0 --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X1.java @@ -0,0 +1,26 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +public class X1 { + public X1() { + AdapterTestCase.EVENT_TRACKER.eventOccurred("x1()"); + } + + public X1(String aValue) { + AdapterTestCase.EVENT_TRACKER.eventOccurred("x1(" + aValue + ")"); + } +} \ No newline at end of file diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/X2.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X2.java new file mode 100644 index 00000000..50a59027 --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X2.java @@ -0,0 +1,26 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +public class X2 { + public X2(Integer aInteger) { + AdapterTestCase.EVENT_TRACKER.eventOccurred("x2(" + aInteger + ")"); + } + + public X2(String aValue) { + AdapterTestCase.EVENT_TRACKER.eventOccurred("x2(" + aValue + ")"); + } +} \ No newline at end of file diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/X3.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X3.java new file mode 100644 index 00000000..4601a033 --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X3.java @@ -0,0 +1,26 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +public class X3 { + public X3() { + AdapterTestCase.EVENT_TRACKER.eventOccurred("x3()"); + } + + protected X3(String aValue) { + AdapterTestCase.EVENT_TRACKER.eventOccurred("x3(" + aValue + ")"); + } +} \ No newline at end of file diff --git a/trunk/system/general/src/test/java/org/wamblee/system/adapters/X4.java b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X4.java new file mode 100644 index 00000000..8d086a8b --- /dev/null +++ b/trunk/system/general/src/test/java/org/wamblee/system/adapters/X4.java @@ -0,0 +1,30 @@ +/* + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.system.adapters; + +public class X4 { + + private X1 _x1; + + public X4(X1 aX1) { + AdapterTestCase.EVENT_TRACKER.eventOccurred("x4(x1)"); + _x1 = aX1; + } + + public X1 getX1() { + return _x1; + } +} diff --git a/trunk/system/general/src/test/java/org/wamblee/system/core/Application.java b/trunk/system/general/src/test/java/org/wamblee/system/core/Application.java index 07857aee..d1302f58 100644 --- a/trunk/system/general/src/test/java/org/wamblee/system/core/Application.java +++ b/trunk/system/general/src/test/java/org/wamblee/system/core/Application.java @@ -54,8 +54,8 @@ public class Application extends AbstractComponent { @Override protected Object doStart(Scope aScope) { track("start." + getName()); - _string = aScope.retrieveInterfaceImplementation(getRequiredInterfaces()[0].getProvider(), String.class); - _integer = aScope.retrieveInterfaceImplementation(getRequiredInterfaces()[1].getProvider(), Integer.class); + _string = aScope.getInterfaceImplementation(getRequiredInterfaces()[0].getProvider(), String.class); + _integer = aScope.getInterfaceImplementation(getRequiredInterfaces()[1].getProvider(), Integer.class); return _random; } diff --git a/trunk/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java b/trunk/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java index 55433a9c..ddd93f6f 100644 --- a/trunk/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java +++ b/trunk/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java @@ -47,7 +47,7 @@ class RequiredServiceBean implements FactoryBean { @Override public Object getObject() throws Exception { - return SpringComponent.SCOPE.get().retrieveInterfaceImplementation( + return SpringComponent.SCOPE.get().getInterfaceImplementation( _required.getProvider(), Object.class); } diff --git a/trunk/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java b/trunk/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java index 0914c9aa..c63916f5 100644 --- a/trunk/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java +++ b/trunk/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java @@ -65,7 +65,7 @@ public class SpringComponentTest extends TestCase { Scope runtime = system.start(); ProvidedInterface[] services = runtime.getProvidedInterfaces(); assertEquals(1, services.length); - Object service = runtime.retrieveInterfaceImplementation(services[0], Object.class); + Object service = runtime.getInterfaceImplementation(services[0], Object.class); assertTrue(service instanceof HelloService); assertEquals("Hello world!", ((HelloService) service).say()); system.stop(runtime); @@ -84,7 +84,7 @@ public class SpringComponentTest extends TestCase { Scope scope = system.start(); ProvidedInterface[] services = scope.getProvidedInterfaces(); - assertEquals("Property Value", scope.retrieveInterfaceImplementation(services[0], HelloService.class).say()); + assertEquals("Property Value", scope.getInterfaceImplementation(services[0], HelloService.class).say()); } public void testWithMissingRequirement() { @@ -141,7 +141,7 @@ public class SpringComponentTest extends TestCase { Scope runtime = system.start(scope); ProvidedInterface started = runtime.getProvidedInterfaces()[0]; - Object impl = runtime.retrieveInterfaceImplementation(started, BlaService.class); + Object impl = runtime.getInterfaceImplementation(started, BlaService.class); assertNotNull(impl); assertTrue(impl instanceof BlaService); assertEquals("ladida", ((BlaService)impl).execute()); -- 2.31.1