(no commit message)
authorErik Brakkee <erik@brakkee.org>
Sun, 13 Apr 2008 09:48:05 +0000 (09:48 +0000)
committerErik Brakkee <erik@brakkee.org>
Sun, 13 Apr 2008 09:48:05 +0000 (09:48 +0000)
21 files changed:
system/general/pom.xml
system/general/src/main/java/org/wamblee/system/adapters/ClassAdapter.java [new file with mode: 0644]
system/general/src/main/java/org/wamblee/system/adapters/ClassConfiguration.java [new file with mode: 0644]
system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java [new file with mode: 0644]
system/general/src/main/java/org/wamblee/system/adapters/FixedValueProvider.java [new file with mode: 0644]
system/general/src/main/java/org/wamblee/system/adapters/ParameterValues.java [new file with mode: 0644]
system/general/src/main/java/org/wamblee/system/adapters/RequiredInterfaceProvider.java [new file with mode: 0644]
system/general/src/main/java/org/wamblee/system/adapters/ValueProvider.java [new file with mode: 0644]
system/general/src/main/java/org/wamblee/system/core/DefaultScope.java
system/general/src/main/java/org/wamblee/system/core/Scope.java
system/general/src/test/java/org/wamblee/system/adapters/AdapterTestCase.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/adapters/ClassAdapterTest.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/adapters/ClassConfigurationTest.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/adapters/ConstructorConfigurationTest.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/adapters/X1.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/adapters/X2.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/adapters/X3.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/adapters/X4.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/core/Application.java
system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java
system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java

index 4f770c4331b9648fbdc12b745eb02f2758b30784..a08f08443885e0f9d9030569c60b5bb0552b4619 100644 (file)
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.wamblee</groupId>
+      <artifactId>wamblee-support-general</artifactId>
+      <version>0.2-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>org.wamblee</groupId>
       <artifactId>wamblee-support-general</artifactId>
diff --git a/system/general/src/main/java/org/wamblee/system/adapters/ClassAdapter.java b/system/general/src/main/java/org/wamblee/system/adapters/ClassAdapter.java
new file mode 100644 (file)
index 0000000..0de8322
--- /dev/null
@@ -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<Object> {
+
+       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/system/general/src/main/java/org/wamblee/system/adapters/ClassConfiguration.java b/system/general/src/main/java/org/wamblee/system/adapters/ClassConfiguration.java
new file mode 100644 (file)
index 0000000..3756bd3
--- /dev/null
@@ -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:
+ * <ul>
+ *   <li> Selection of a constructor using explicit selection 
+ *      {@link #select(Class...)} or using the most greedy constructor 
+ *      {@link #greedy()}.
+ *   </li>
+ *   <li>
+ *      Selection of methods to invoke to inject other objects into the object.  
+ *   </li>
+ *   <li> Selection of fields to set. 
+ *   </li>
+ * </ul>
+ * 
+ * @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/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java b/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java
new file mode 100644 (file)
index 0000000..2725d03
--- /dev/null
@@ -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<Constructor<?>> checked = new ArrayList<Constructor<?>>();
+               CollectionFilter.filter(Arrays.asList(declared), checked, 
+                       new Condition<Constructor<?>>() { 
+                       @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<Constructor<?>> ctors = checked;
+               List<Constructor<?>> longest = new ArrayList<Constructor<?>>();
+               CollectionFilter.filter(ctors, longest,
+                               new Condition<Constructor<?>>() {
+                                       @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<RequiredInterface> getRequiredInterfaces() {
+               getConstructor(); // initialize constructor if needed.
+               return _values.getRequiredInterfaces(); 
+       }
+       
+       private Constructor getConstructor() { 
+               if (_constructor == null ) { 
+                       greedy(); 
+               }
+               return _constructor; 
+       }
+}
diff --git a/system/general/src/main/java/org/wamblee/system/adapters/FixedValueProvider.java b/system/general/src/main/java/org/wamblee/system/adapters/FixedValueProvider.java
new file mode 100644 (file)
index 0000000..e36ecfb
--- /dev/null
@@ -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/system/general/src/main/java/org/wamblee/system/adapters/ParameterValues.java b/system/general/src/main/java/org/wamblee/system/adapters/ParameterValues.java
new file mode 100644 (file)
index 0000000..4134819
--- /dev/null
@@ -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<RequiredInterface> getRequiredInterfaces() { 
+               List<RequiredInterface> result = new ArrayList<RequiredInterface>(); 
+               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/system/general/src/main/java/org/wamblee/system/adapters/RequiredInterfaceProvider.java b/system/general/src/main/java/org/wamblee/system/adapters/RequiredInterfaceProvider.java
new file mode 100644 (file)
index 0000000..76d2d3d
--- /dev/null
@@ -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/system/general/src/main/java/org/wamblee/system/adapters/ValueProvider.java b/system/general/src/main/java/org/wamblee/system/adapters/ValueProvider.java
new file mode 100644 (file)
index 0000000..03eac1e
--- /dev/null
@@ -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);
+}
index 8b0c88efe0e4b746a6d92dd5e9a49d1fe1446ddc..b57f51f64f01a04d743f626fc6e90fd00fae4c39 100644 (file)
@@ -83,7 +83,7 @@ public class DefaultScope implements Scope {
        }
 
        @Override
-       public <T> T retrieveInterfaceImplementation(ProvidedInterface aInterface,
+       public <T> T getInterfaceImplementation(ProvidedInterface aInterface,
                        Class<T> 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; 
                                }
index 829435f620abe022f1d75c033ab07685994cdbf7..9db462f5c4393a873aaf3713272d67ee9f10a8e3 100644 (file)
@@ -66,7 +66,7 @@ public interface Scope {
         * @param aType Type of implementation that is expected.
         * @return Retrieved interface.
         */
-       <T> T retrieveInterfaceImplementation(ProvidedInterface aProvided, Class<T> aType );
+       <T> T getInterfaceImplementation(ProvidedInterface aProvided, Class<T> aType );
 
        /**
         * Gets the runtime for a component.  
diff --git a/system/general/src/test/java/org/wamblee/system/adapters/AdapterTestCase.java b/system/general/src/test/java/org/wamblee/system/adapters/AdapterTestCase.java
new file mode 100644 (file)
index 0000000..cf67b24
--- /dev/null
@@ -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<String> EVENT_TRACKER;
+
+       @Override
+       protected void setUp() throws Exception {
+               super.setUp();
+               EVENT_TRACKER = new EventTracker<String>();
+               _scope = new DefaultScope(new ProvidedInterface[0]);
+       }
+
+}
diff --git a/system/general/src/test/java/org/wamblee/system/adapters/ClassAdapterTest.java b/system/general/src/test/java/org/wamblee/system/adapters/ClassAdapterTest.java
new file mode 100644 (file)
index 0000000..925f3ef
--- /dev/null
@@ -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/system/general/src/test/java/org/wamblee/system/adapters/ClassConfigurationTest.java b/system/general/src/test/java/org/wamblee/system/adapters/ClassConfigurationTest.java
new file mode 100644 (file)
index 0000000..2ac1484
--- /dev/null
@@ -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<RequiredInterface> 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/system/general/src/test/java/org/wamblee/system/adapters/ConstructorConfigurationTest.java b/system/general/src/test/java/org/wamblee/system/adapters/ConstructorConfigurationTest.java
new file mode 100644 (file)
index 0000000..1ee899f
--- /dev/null
@@ -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<RequiredInterface> 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<RequiredInterface> 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<RequiredInterface> 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<RequiredInterface> 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<RequiredInterface> 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/system/general/src/test/java/org/wamblee/system/adapters/X1.java b/system/general/src/test/java/org/wamblee/system/adapters/X1.java
new file mode 100644 (file)
index 0000000..b17a27c
--- /dev/null
@@ -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/system/general/src/test/java/org/wamblee/system/adapters/X2.java b/system/general/src/test/java/org/wamblee/system/adapters/X2.java
new file mode 100644 (file)
index 0000000..50a5902
--- /dev/null
@@ -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/system/general/src/test/java/org/wamblee/system/adapters/X3.java b/system/general/src/test/java/org/wamblee/system/adapters/X3.java
new file mode 100644 (file)
index 0000000..4601a03
--- /dev/null
@@ -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/system/general/src/test/java/org/wamblee/system/adapters/X4.java b/system/general/src/test/java/org/wamblee/system/adapters/X4.java
new file mode 100644 (file)
index 0000000..8d086a8
--- /dev/null
@@ -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;
+       }
+}
index 07857aee2b7510fa05e87a056676b805b360ace8..d1302f5852177582763f1cf1e0f85bdc4eb3a684 100644 (file)
@@ -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; 
        }
        
index 55433a9c47aac5b793b2da484dafd5298fae7d4b..ddd93f6f76ec6708fd3250b68ef4fc1132d57d17 100644 (file)
@@ -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);
        }
 
index 0914c9aa3d5e065c138ebb30387fe5f6ba377221..c63916f5d68946a6c3d0baa5a004d11b8d3322b8 100644 (file)
@@ -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());