[CVS nano] update
Paul Hammant <paul-yCVjj/[email protected]> Mon, 17 Nov 2003 15:02:27 -0600
| Newsgroups | gmane.comp.java.nanocontainer.cvs |
|---|---|
| Message-ID | <[email protected]> |
Commit in nano on MAIN
jmx/src/test/org/picoextras/jmx/AbstractNanoMXTestCase.java +43 added 1.1
/NanoMXComponentFactoryTestCase.java +50 added 1.1
/NanoMXContainerTestCase.java +142 added 1.1
nanning/src/java/org/picoextras/nanning/NanningComponentAdapter.java +55 added 1.1
/NanningComponentAdapterFactory.java +120 added 1.1
/NanningNanoContainer.java +41 added 1.1
nanning/src/test/org/picoextras/nanning/NanningComponentFactoryTestCase.java +100 added 1.1
/NanningNanoContainerTestCase.java +178 added 1.1
+729
8 added files
- TODO Nanning will at the moment only aspectify stuff when it has one and only one interface
- TODO Nanning will at the moment only aspectify stuff when it has one and only one interface
update
----------
nano /jmx /src /test /org /picoextras /jmx
AbstractNanoMXTestCase.java added at 1.1
diff -N AbstractNanoMXTestCase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AbstractNanoMXTestCase.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * Copyright (c) NanoContainer Organization. All rights reserved. *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file. *
+ * *
+ * Original code by James Strachan *
+ *****************************************************************************/
+
+package org.picoextras.jmx;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+/**
+ * Abstract base class with some helper methods for testing NanoMX
+ *
+ * @author James Strachan
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractNanoMXTestCase extends TestCase {
+
+ /**
+ * Helper method to check there exists an mbean at the given name
+ * @param name
+ */
+ protected void assertExistsInJMX(MBeanServer server, String name) throws InstanceNotFoundException, MalformedObjectNameException {
+ assertNotNull("MBeanServer is not null", server);
+
+ ObjectInstance instance = server.getObjectInstance(new ObjectName(name));
+
+ assertNotNull("Found one in MBeanServer", instance);
+
+ assertEquals("ObjectInstance has correct class name", NanoMBean.class.getName(), instance.getClassName());
+ }
+}
----------
nano /jmx /src /test /org /picoextras /jmx
NanoMXComponentFactoryTestCase.java added at 1.1
diff -N NanoMXComponentFactoryTestCase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NanoMXComponentFactoryTestCase.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * Copyright (c) NanoContainer Organization. All rights reserved. *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file. *
+ * *
+ * Original code by James Strachan *
+ *****************************************************************************/
+
+package org.picoextras.jmx;
+
+import org.picoextras.testmodel.WilmaImpl;
+
+public class NanoMXComponentFactoryTestCase extends AbstractNanoMXTestCase {
+
+ public void testClassAndKeyRegistration() throws Exception {
+ NanoMXContainer pico = new NanoMXContainer();
+
+ pico.registerComponentImplementation("nano:name=one", WilmaImpl.class);
+ pico.registerComponentImplementation("nano:name=two", WilmaImpl.class);
+
+ assertEquals("Wrong number of comps in the internals", 2, pico.getComponentInstances().size());
+ assertExistsInJMX(pico.getMBeanServer(), "nano:name=one");
+ assertExistsInJMX(pico.getMBeanServer(), "nano:name=two");
+ }
+
+ public void testClassOnlyRegistration() throws Exception {
+ NanoMXContainer pico = new NanoMXContainer();
+
+ pico.registerComponentImplementation(WilmaImpl.class);
+
+ assertEquals("Wrong number of comps in the internals", 1, pico.getComponentInstances().size());
+
+ assertExistsInJMX(pico.getMBeanServer(), "nanomx:type=" + WilmaImpl.class.getName());
+ }
+
+ public void testObjectAndNullKeyRegistration() throws Exception {
+ NanoMXContainer pico = new NanoMXContainer();
+
+ try {
+ pico.registerComponentInstance(null, new WilmaImpl());
+ fail("should have thrown NullPointerException");
+ }
+ catch (NullPointerException e) {
+ // worked
+ }
+ }
+
+}
----------
nano /jmx /src /test /org /picoextras /jmx
NanoMXContainerTestCase.java added at 1.1
diff -N NanoMXContainerTestCase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NanoMXContainerTestCase.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,142 @@
+/*****************************************************************************
+ * Copyright (c) NanoContainer Organization. All rights reserved. *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file. *
+ * *
+ * Original code by James Strachan *
+ *****************************************************************************/
+
+package org.picoextras.jmx;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.management.MBeanServerFactory;
+
+import org.picoextras.testmodel.WilmaImpl;
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.defaults.DefaultComponentAdapterFactory;
+import org.picocontainer.defaults.DefaultPicoContainer;
+
+public class NanoMXContainerTestCase extends AbstractNanoMXTestCase {
+
+ public void testKeyRegistration() throws Exception {
+ NanoMXContainer pico = new NanoMXContainer();
+
+ WilmaImpl one = new WilmaImpl();
+ WilmaImpl two = new WilmaImpl();
+
+ pico.registerComponentInstance("nano:name=one", one);
+ pico.registerComponentInstance("nano:name=two", two);
+
+ assertEquals("Wrong number of comps in the internals", 2, pico.getComponentInstances().size());
+
+ assertEquals("Looking up one Wilma", one, pico.getComponentInstance("nano:name=one"));
+ assertEquals("Looking up two Wilma", two, pico.getComponentInstance("nano:name=two"));
+
+ assertTrue("Object one the same", one == pico.getComponentInstance("nano:name=one"));
+ assertTrue("Object two the same", two == pico.getComponentInstance("nano:name=two"));
+
+ assertEquals("Lookup of unknown key should return null", null, pico.getComponentInstance("unknown"));
+
+ assertExistsInJMX(pico.getMBeanServer(), "nano:name=one");
+ assertExistsInJMX(pico.getMBeanServer(), "nano:name=two");
+ }
+
+ public void testObjectNameRegistration() throws Exception {
+ NanoMXContainer pico = new NanoMXContainer();
+
+ ObjectName nameOne = new ObjectName("nano:name=one;type=full");
+ ObjectName nameTwo = new ObjectName("nano:name=two;type=full");
+ ObjectName nameUnknown = new ObjectName("nano:name=unknown;type=full");
+
+ WilmaImpl one = new WilmaImpl();
+ WilmaImpl two = new WilmaImpl();
+
+ pico.registerComponentInstance(nameOne, one);
+ pico.registerComponentInstance(nameTwo, two);
+
+ assertEquals("Wrong number of comps in the internals", 2, pico.getComponentInstances().size());
+
+ assertEquals("Looking up one Wilma", one, pico.getComponentInstance(nameOne));
+ assertEquals("Looking up two Wilma", two, pico.getComponentInstance(nameTwo));
+
+ assertTrue("Object one the same", one == pico.getComponentInstance(nameOne));
+ assertTrue("Object two the same", two == pico.getComponentInstance(nameTwo));
+
+ assertEquals("Lookup of unknown key should return null", null, pico.getComponentInstance(nameUnknown));
+
+ assertExistsInJMX(pico.getMBeanServer(), "nano:name=one;type=full");
+ assertExistsInJMX(pico.getMBeanServer(), "nano:name=two;type=full");
+ }
+
+ public void testQueryMBeanServerAfterRegistration() throws Exception {
+ NanoMXContainer pico = new NanoMXContainer();
+
+ ObjectName nameOne = new ObjectName("nano:name=one;type=full");
+ ObjectName nameTwo = new ObjectName("nano:name=two;type=full");
+
+ WilmaImpl one = new WilmaImpl();
+ WilmaImpl two = new WilmaImpl();
+
+ pico.registerComponentInstance(nameOne, one);
+ pico.registerComponentInstance(nameTwo, two);
+
+ assertEquals("Wrong number of comps in the internals", 2, pico.getComponentInstances().size());
+
+ ObjectInstance instance = pico.getMBeanServer().getObjectInstance(nameOne);
+
+ assertTrue("Found one in MBeanServer", instance != null);
+
+ assertEquals("ObjectInstance has correct class name", NanoMBean.class.getName(), instance.getClassName());
+ }
+
+ public void testDuplicateRegistration() throws Exception {
+ NanoMXContainer pico = new NanoMXContainer();
+
+ pico.registerComponentInstance("nano:name=one", new WilmaImpl());
+ try {
+ pico.registerComponentInstance("nano:name=one", new WilmaImpl());
+ fail("Should have barfed with dupe registration");
+ }
+ catch (Exception e) {
+ // expected
+// assertTrue("Wrong key", e.getKey() == "nano:name=one");
+// assertTrue("Wrong component", e.findComponentInstance() instanceof WilmaImpl);
+// assertTrue(
+// "Wrong message: " + e.getMessage(),
+// e.getMessage().startsWith("Key: one duplicated, cannot register:"));
+ }
+ }
+
+ public void testHasComponentByKey() throws Exception {
+ MBeanServer mbeanServer = MBeanServerFactory.newMBeanServer();
+ NanoMXComponentAdapterFactory factory = new NanoMXComponentAdapterFactory(mbeanServer, new DefaultComponentAdapterFactory());
+ MutablePicoContainer pico = new DefaultPicoContainer(factory);
+
+ assertTrue("should not have non existent component", !pico.hasComponent("nano:name=doesNotExist"));
+
+ pico.registerComponentInstance("nano:name=foo", new WilmaImpl());
+
+ assertTrue("has component", pico.hasComponent("nano:name=foo"));
+ }
+
+// public void testRemoveComponent() throws Exception {
+// NanoMXContainer pico = createJmxContainer();
+//
+// // remove non existent doesn't throw exception
+// pico.removeComponent("nano:name=doesNotExist");
+//
+// pico.registerComponentInstance("nano:name=foo", new WilmaImpl());
+//
+// assertTrue("has component", pico.findComponentInstance("nano:name=foo") != null);
+//
+// pico.removeComponent("nano:name=foo");
+//
+// assertEquals("hasComponent(foo)", false, pico.hasComponent("nano:name=foo"));
+// assertEquals("findComponentInstance(foo)", null, pico.findComponentInstance("nano:name=foo"));
+// }
+
+}
----------
nano /nanning /src /java /org /picoextras /nanning
NanningComponentAdapter.java added at 1.1
diff -N NanningComponentAdapter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NanningComponentAdapter.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * Copyright (C) NanoContainer Organization. All rights reserved. *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file. *
+ * *
+ * Original code by Jon Tirsen *
+ *****************************************************************************/
+
+package org.picoextras.nanning;
+
+import org.codehaus.nanning.AspectInstance;
+import org.codehaus.nanning.Mixin;
+import org.codehaus.nanning.config.AspectSystem;
+import org.picocontainer.extras.DecoratingComponentAdapter;
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.defaults.AssignabilityRegistrationException;
+import org.picocontainer.defaults.NotConcreteRegistrationException;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.MutablePicoContainer;
+
+/**
+ * @author Jon Tirsen (tirsen-yCVjj/[email protected])
+ * @author Aslak Hellesoy
+ * @version $Revision: 1.1 $
+ */
+public class NanningComponentAdapter extends DecoratingComponentAdapter {
+
+ private final AspectSystem aspectSystem;
+
+ public NanningComponentAdapter(AspectSystem aspectSystem, ComponentAdapter decoratedComponentAdapter) {
+ super(decoratedComponentAdapter);
+ this.aspectSystem = aspectSystem;
+ }
+
+ public Object getComponentInstance(MutablePicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ Object component = super.getComponentInstance(picoContainer);
+ // TODO Nanning will at the moment only aspectify stuff when it has one and only one interface
+ if (component.getClass().getInterfaces().length == 1) {
+ Class intf = component.getClass().getInterfaces()[0];
+ // the trick: set up first mixin manually with the component as target
+ AspectInstance aspectInstance = new AspectInstance(intf);
+ Mixin mixin = new Mixin(intf, component);
+ aspectInstance.addMixin(mixin);
+
+ // let the aspects do its work
+ aspectSystem.initialize(aspectInstance);
+ component = aspectInstance.getProxy();
+ }
+
+ return component;
+ }
+}
----------
nano /nanning /src /java /org /picoextras /nanning
NanningComponentAdapterFactory.java added at 1.1
diff -N NanningComponentAdapterFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NanningComponentAdapterFactory.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,120 @@
+package org.picoextras.nanning;
+
+import org.codehaus.nanning.config.AspectSystem;
+import org.codehaus.nanning.config.Aspect;
+import org.codehaus.nanning.AspectInstance;
+import org.codehaus.nanning.Mixin;
+import org.picocontainer.extras.DecoratingComponentAdapterFactory;
+import org.picocontainer.extras.DecoratingComponentAdapter;
+import org.picocontainer.defaults.*;
+import org.picocontainer.*;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Collections;
+import java.util.ArrayList;
+
+/**
+ * @author Jon Tirsen
+ * @version $Revision: 1.1 $
+ */
+public class NanningComponentAdapterFactory extends DecoratingComponentAdapterFactory implements Serializable {
+ private AspectSystem aspectSystem;
+
+ public NanningComponentAdapterFactory(AspectSystem aspectSystem,
+ ComponentAdapterFactory delegate) {
+ super(delegate);
+ this.aspectSystem = aspectSystem;
+ }
+
+ public NanningComponentAdapterFactory() {
+ this(new AspectSystem(), new DefaultComponentAdapterFactory());
+ }
+
+ public ComponentAdapter createComponentAdapter(Object componentKey,
+ Class componentImplementation,
+ Parameter[] parameters)
+ throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ ComponentAdapter componentAdapter = super.createComponentAdapter(componentKey, componentImplementation, parameters);
+
+ if (Aspect.class.isAssignableFrom(componentImplementation)) {
+ componentAdapter = new AspectAdapter(componentAdapter, aspectSystem);
+
+ } else if (canBeWeaved(componentImplementation)) {
+ Class componentInterface = getComponentInterface(componentImplementation);
+ componentAdapter = new WeavingAdapter(componentAdapter, aspectSystem, componentInterface);
+ }
+
+ return componentAdapter;
+ }
+
+ private Class getComponentInterface(Class componentImplementation) {
+ return (Class) getAllInterfaces(componentImplementation).get(0);
+ }
+
+ List getAllInterfaces(Class componentImplementation) {
+ if (componentImplementation == null) {
+ return Collections.EMPTY_LIST;
+ }
+ List result = new ArrayList(Arrays.asList(componentImplementation.getInterfaces()));
+ result.addAll(getAllInterfaces(componentImplementation.getSuperclass()));
+ return result;
+ }
+
+ private boolean canBeWeaved(Class componentImplementation) {
+ return getAllInterfaces(componentImplementation).size() == 1;
+ }
+
+ public static class WeavingAdapter extends DecoratingComponentAdapter {
+
+ private final AspectSystem aspectSystem;
+ private Class componentInterface;
+
+ public WeavingAdapter(ComponentAdapter delegate, AspectSystem aspectSystem, Class componentInterface) {
+ super(delegate);
+ this.aspectSystem = aspectSystem;
+ this.componentInterface = componentInterface;
+ }
+
+ public Object getComponentInstance(MutablePicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ Object component = super.getComponentInstance(picoContainer);
+ // TODO Nanning will at the moment only aspectify stuff when it has one and only one interface
+
+ // the trick: set up first mixin manually with the component as target
+ AspectInstance aspectInstance = new AspectInstance(componentInterface);
+ Mixin mixin = new Mixin(componentInterface, component);
+ aspectInstance.addMixin(mixin);
+
+ // let the aspects do its work
+ getAspectSystem().initialize(aspectInstance);
+ component = aspectInstance.getProxy();
+
+ return component;
+ }
+
+ private AspectSystem getAspectSystem() {
+ return aspectSystem;
+ }
+ }
+
+ public static class AspectAdapter extends DecoratingComponentAdapter {
+ private AspectSystem aspectSystem;
+
+ public AspectAdapter(ComponentAdapter delegate, AspectSystem aspectSystem) {
+ super(delegate);
+ this.aspectSystem = aspectSystem;
+ }
+
+ public Object getComponentInstance(MutablePicoContainer picoContainer)
+ throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ Aspect aspect = (Aspect) super.getComponentInstance(picoContainer);
+ getAspectSystem().addAspect(aspect);
+ return aspect;
+ }
+
+ private AspectSystem getAspectSystem() {
+ return aspectSystem;
+ }
+ }
+}
----------
nano /nanning /src /java /org /picoextras /nanning
NanningNanoContainer.java added at 1.1
diff -N NanningNanoContainer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NanningNanoContainer.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved. *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file. *
+ * *
+ * Original code by Jon Tirsen *
+ *****************************************************************************/
+
+package org.picoextras.nanning;
+
+import org.codehaus.nanning.config.AspectSystem;
+import org.picocontainer.defaults.DefaultComponentAdapterFactory;
+import org.picocontainer.defaults.ComponentAdapterFactory;
+import org.picocontainer.defaults.DefaultPicoContainer;
+
+/**
+ * @author Jon Tirsen (tirsen-yCVjj/[email protected])
+ * @author Aslak Hellesoy
+ * @version $Revision: 1.1 $
+ * @deprecated Use a {@link DefaultPicoContainer} with a {@link NanningComponentAdapterFactory}
+ * instead. This favours chaining of component adapters.
+ */
+public class NanningNanoContainer extends DefaultPicoContainer {
+ public NanningNanoContainer(AspectSystem aspectSystem, ComponentAdapterFactory componentAdapterFactory) {
+ super(new NanningComponentAdapterFactory(aspectSystem, componentAdapterFactory));
+ }
+
+ public NanningNanoContainer(AspectSystem aspectSystem) {
+ this(aspectSystem, new DefaultComponentAdapterFactory());
+ }
+
+ public NanningNanoContainer(ComponentAdapterFactory componentAdapterFactory) {
+ this(new AspectSystem(), componentAdapterFactory);
+ }
+
+ public NanningNanoContainer() {
+ this(new AspectSystem(), new DefaultComponentAdapterFactory());
+ }
+}
----------
nano /nanning /src /test /org /picoextras /nanning
NanningComponentFactoryTestCase.java added at 1.1
diff -N NanningComponentFactoryTestCase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NanningComponentFactoryTestCase.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Copyright (C) NanoContainer Organization. All rights reserved. *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file. *
+ * *
+ * Original code by Jon Tirs?n *
+ *****************************************************************************/
+
+package org.picoextras.nanning;
+
+import junit.framework.TestCase;
+import org.codehaus.nanning.Aspects;
+import org.codehaus.nanning.Invocation;
+import org.codehaus.nanning.MethodInterceptor;
+import org.codehaus.nanning.config.AspectSystem;
+import org.codehaus.nanning.config.InterceptorAspect;
+import org.picocontainer.*;
+import org.picocontainer.defaults.*;
+
+/**
+ * @author Jon Tirsen
+ * @version $Revision: 1.1 $
+ */
+public class NanningComponentFactoryTestCase extends TestCase {
+
+ public interface Wilma {
+ void hello();
+ }
+
+ public static class WilmaImpl implements Wilma {
+ public void hello() {
+ }
+ }
+
+ public static class FredImpl {
+ public FredImpl(Wilma wilma) {
+ assertNotNull("Wilma cannot be passed in as null", wilma);
+ wilma.hello();
+ }
+ }
+
+ private StringBuffer log = new StringBuffer();
+
+ public void testComponentsWithOneInterfaceAreAspected() throws PicoInitializationException, AssignabilityRegistrationException, NotConcreteRegistrationException, PicoIntrospectionException {
+ NanningComponentAdapter componentFactory =
+ new NanningComponentAdapter(new AspectSystem(), new DefaultComponentAdapter(Wilma.class, WilmaImpl.class));
+ Object component = componentFactory.getComponentInstance(new DefaultPicoContainer());
+ assertTrue(Aspects.isAspectObject(component));
+ assertEquals(Wilma.class, Aspects.getAspectInstance(component).getClassIdentifier());
+ }
+
+ public void testComponentsWithoutInterfaceNotAspected() throws PicoInitializationException, PicoRegistrationException {
+ NanningComponentAdapter componentFactory = new NanningComponentAdapter(new AspectSystem(),
+ new DefaultComponentAdapter(FredImpl.class, FredImpl.class));
+ DefaultPicoContainer registry = new DefaultPicoContainer();
+ registry.registerComponent(new InstanceComponentAdapter(Wilma.class, new WilmaImpl()));
+ Object component = componentFactory.getComponentInstance(registry);
+ assertFalse(Aspects.isAspectObject(component));
+ }
+
+
+ /**
+ * Acceptance test (ie a teeny bit functional, but you'll get over it).
+ */
+ public void testSimpleLogOfMethodCall()
+ throws PicoException, PicoInitializationException {
+
+ AspectSystem aspectSystem = new AspectSystem();
+ aspectSystem.addAspect(new InterceptorAspect(new MethodInterceptor() {
+ public Object invoke(Invocation invocation) throws Throwable {
+ log.append(invocation.getMethod().getName() + " ");
+ return invocation.invokeNext();
+ }
+ }));
+
+ MutablePicoContainer nanningEnabledPicoContainer = new DefaultPicoContainer(
+ new NanningComponentAdapterFactory(aspectSystem, new DefaultComponentAdapterFactory()));
+ nanningEnabledPicoContainer.registerComponentImplementation(Wilma.class, WilmaImpl.class);
+ nanningEnabledPicoContainer.registerComponentImplementation(FredImpl.class);
+
+ assertEquals("", log.toString());
+
+ nanningEnabledPicoContainer.getComponentInstances();
+
+ // fred says hello to wilma, even the interceptor knows
+ assertEquals("hello ", log.toString());
+
+ Wilma wilma = (Wilma) nanningEnabledPicoContainer.getComponentInstance(Wilma.class);
+
+ assertNotNull(wilma);
+
+ wilma.hello();
+
+ // another entry in the log
+ assertEquals("hello hello ", log.toString());
+
+ }
+}
----------
nano /nanning /src /test /org /picoextras /nanning
NanningNanoContainerTestCase.java added at 1.1
diff -N NanningNanoContainerTestCase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NanningNanoContainerTestCase.java 17 Nov 2003 21:02:27 -0000 1.1
@@ -0,0 +1,178 @@
+package org.picoextras.nanning;
+
+import junit.framework.TestCase;
+import org.codehaus.nanning.*;
+import org.codehaus.nanning.config.Aspect;
+import org.codehaus.nanning.config.P;
+import org.codehaus.nanning.config.Pointcut;
+import org.picocontainer.*;
+import org.picocontainer.defaults.AssignabilityRegistrationException;
+import org.picocontainer.defaults.NotConcreteRegistrationException;
+import org.picocontainer.defaults.DefaultPicoContainer;
+
+/**
+ * Contains both unit-tests for the NanninNanoContainer and acceptance-tests outlining an example
+ * of how to use it.
+ * @author Jon Tirsen (tirsen-yCVjj/[email protected])
+ * @version $Revision: 1.1 $
+ */
+public class NanningNanoContainerTestCase extends TestCase {
+
+ private MutablePicoContainer container;
+
+ /**
+ * RecordingAware2 very simplified interface to a TransactionManager.
+ */
+ public static interface TransactionManager {
+ Transaction startTransaction();
+ }
+
+ public static interface Transaction {
+ void commit();
+
+ void rollback();
+ }
+
+ /**
+ * RecordingAware2 very simplified "declarative" transaction-aspect.
+ */
+ public static class TransactionAspect implements Aspect {
+ Pointcut transactionPointcut = P.all();
+ TransactionManager transactionManager;
+
+ public TransactionAspect(TransactionManager transactionManager) {
+ this.transactionManager = transactionManager;
+ }
+
+ public void introduce(AspectInstance instance) {
+ // nothing to introduce
+ }
+
+ public void advise(AspectInstance instance) {
+ transactionPointcut.advise(instance, new MethodInterceptor() {
+ public Object invoke(Invocation invocation) throws Throwable {
+ Transaction transaction = transactionManager.startTransaction();
+ try {
+ Object o = invocation.invokeNext();
+ transaction.commit();
+ return o;
+ } catch (Exception e) {
+ transaction.rollback();
+ throw e;
+ }
+ }
+ });
+ }
+ }
+
+ public static interface Component {
+ void doSomethingRequiringATransaction() throws Exception;
+ }
+
+ public static class SucceedingComponent implements Component {
+ public void doSomethingRequiringATransaction() {
+ // success!!
+ }
+ }
+
+ public static class FailingComponent implements Component {
+ public void doSomethingRequiringATransaction() throws Exception {
+ throw new Exception();
+ }
+ }
+
+ public static class LoggingTransactionManager implements TransactionManager {
+ public StringBuffer transactionLog = new StringBuffer();
+
+ public Transaction startTransaction() {
+ transactionLog.append("instantiateComponents ");
+
+ return new Transaction() {
+ public void commit() {
+ transactionLog.append("commit ");
+ }
+
+ public void rollback() {
+ transactionLog.append("rollback ");
+ }
+ };
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ container = new DefaultPicoContainer(new NanningComponentAdapterFactory());
+ }
+
+ public void testServiceIsInstantiated() throws PicoRegistrationException, PicoInitializationException {
+ container.registerComponentImplementation(TransactionManager.class, LoggingTransactionManager.class);
+ container.getComponentInstances();
+
+ assertTrue(container.hasComponent(TransactionManager.class));
+ assertNotNull(container.getComponentInstance(TransactionManager.class));
+ }
+
+ public void testAspectDependingOnServiceIsInstantiated() throws PicoRegistrationException, PicoInitializationException {
+ container.registerComponentImplementation(TransactionManager.class, LoggingTransactionManager.class);
+ container.registerComponentImplementation(TransactionAspect.class);
+ container.getComponentInstances();
+
+ TransactionAspect transactionAspect = (TransactionAspect) container.getComponentInstance(TransactionAspect.class);
+ assertNotNull(transactionAspect);
+ assertNotNull(transactionAspect.transactionManager);
+ }
+
+ public void testAspectifiedComponentIsInstantiatedWithProperAspects()
+ throws PicoRegistrationException, PicoInitializationException {
+ container.registerComponentImplementation(TransactionManager.class, LoggingTransactionManager.class);
+ container.registerComponentImplementation(TransactionAspect.class);
+ container.registerComponentImplementation(Component.class, SucceedingComponent.class);
+ container.getComponentInstances();
+
+ Component component = (Component) container.getComponentInstance(Component.class);
+ assertNotNull(component);
+ assertTrue(Aspects.isAspectObject(component));
+ assertEquals(1, Aspects.getAspectInstance(component).getAllInterceptors().size());
+ }
+
+ /**
+ * The 'acceptance-test' for the example.
+ */
+ public void testTransactionAspectStartsAndCommitsTransaction() throws PicoRegistrationException, PicoInstantiationException, Exception {
+ container.registerComponentImplementation(TransactionManager.class, LoggingTransactionManager.class);
+ container.registerComponentImplementation(TransactionAspect.class, TransactionAspect.class);
+ container.registerComponentImplementation(Component.class, SucceedingComponent.class);
+ container.getComponentInstances();
+
+ Component component = (Component) container.getComponentInstance(Component.class);
+ assertNotNull(component);
+ component.doSomethingRequiringATransaction();
+
+ LoggingTransactionManager transactionManager = getTransactionManagerTarget();
+ assertEquals("instantiateComponents commit ", transactionManager.transactionLog.toString());
+ }
+
+ public void testTransactionAspectStartsAndRollsBackTransaction() throws PicoRegistrationException, PicoInstantiationException, Exception {
+ container.registerComponentImplementation(TransactionManager.class, LoggingTransactionManager.class);
+ container.registerComponentImplementation(TransactionAspect.class);
+ container.registerComponentImplementation(Component.class, FailingComponent.class);
+ container.getComponentInstances();
+
+ Component component = (Component) container.getComponentInstance(Component.class);
+ try {
+ component.doSomethingRequiringATransaction();
+ fail();
+ } catch (Exception shouldHappen) {
+ }
+
+ LoggingTransactionManager transactionManager = getTransactionManagerTarget();
+ assertEquals("instantiateComponents rollback ", transactionManager.transactionLog.toString());
+ }
+
+ private LoggingTransactionManager getTransactionManagerTarget() throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ AspectInstance aspectInstance = Aspects.getAspectInstance(container.getComponentInstance(TransactionManager.class));
+ Mixin mixin = aspectInstance.getMixinForInterface(TransactionManager.class);
+ return (LoggingTransactionManager) mixin.getTarget();
+ }
+
+}