Added: camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/InjectorManager.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/InjectorManager.java?rev=1429309&view=auto ============================================================================== --- camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/InjectorManager.java (added) +++ camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/InjectorManager.java Sat Jan 5 15:14:02 2013 @@ -0,0 +1,238 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.guice.testing; +import java.lang.reflect.Modifier; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import com.google.common.base.Preconditions; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; + +import org.apache.camel.guice.inject.Injectors; +import org.apache.camel.guice.support.CloseErrors; +import org.apache.camel.guice.support.CloseFailedException; +import org.apache.camel.guice.support.internal.CloseErrorsImpl; +import org.apache.camel.guice.util.CloseableScope; + +/** + * Used to manage the injectors for the various injection points + * + */ +public class InjectorManager { + private static final String NESTED_MODULE_CLASS = "TestModule"; + + private Map<Object, Injector> injectors = new ConcurrentHashMap<Object, Injector>(); + private AtomicInteger initializeCounter = new AtomicInteger(0); + private CloseableScope testScope = new CloseableScope(TestScoped.class); + private CloseableScope classScope = new CloseableScope(ClassScoped.class); + + private boolean closeSingletonsAfterClasses; + private boolean runFinalizer = true; + private Class<? extends Module> moduleType; + + public void beforeClasses() { + int counter = initializeCounter.incrementAndGet(); + if (counter > 1) { + System.out.println("WARNING! Initialised more than once! Counter: " + counter); + } else { + if (runFinalizer) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + closeSingletons(); + } catch (Throwable e) { + System.out.println("Failed to shut down Guice Singletons: " + e); + e.printStackTrace(); + } + } + }); + } + } + + } + + /** Lets close all of the injectors we have created so far */ + public void afterClasses() throws CloseFailedException { + Injector injector = injectors.get(moduleType); + if (injector != null) { + classScope.close(injector); + } else { + System.out.println("Could not close Class scope as there is no Injector for module type " + + injector); + } + + // NOTE that we don't have any good hooks yet to call complete() + // when the JVM is completed to ensure real singletons shut down + // correctly + // + if (isCloseSingletonsAfterClasses()) { + closeInjectors(); + } + } + + public void beforeTest(Object test) throws Exception { + Preconditions.checkNotNull(test, "test"); + + Class<? extends Object> testType = test.getClass(); + moduleType = getModuleForTestClass(testType); + + Injector classInjector; + synchronized (injectors) { + classInjector = injectors.get(moduleType); + if (classInjector == null) { + classInjector = createInjector(moduleType); + Preconditions.checkNotNull(classInjector, "classInjector"); + injectors.put(moduleType, classInjector); + } + } + injectors.put(testType, classInjector); + + classInjector.injectMembers(test); + } + + public void afterTest(Object test) throws Exception { + Injector injector = injectors.get(test.getClass()); + if (injector == null) { + System.out.println("Warning - no injector available for: " + test); + } else { + testScope.close(injector); + } + } + + /** + * Closes down any JVM level singletons used in this testing JVM + */ + public void closeSingletons() throws CloseFailedException { + closeInjectors(); + } + + public boolean isCloseSingletonsAfterClasses() { + return closeSingletonsAfterClasses; + } + + public void setCloseSingletonsAfterClasses(boolean closeSingletonsAfterClasses) { + this.closeSingletonsAfterClasses = closeSingletonsAfterClasses; + } + + protected class TestModule extends AbstractModule { + + protected void configure() { + bindScope(ClassScoped.class, classScope); + bindScope(TestScoped.class, testScope); + } + } + + protected void closeInjectors() throws CloseFailedException { + CloseErrors errors = new CloseErrorsImpl(this); + Set<Entry<Object, Injector>> entries = injectors.entrySet(); + for (Entry<Object, Injector> entry : entries) { + // Object key = entry.getKey(); + Injector injector = entry.getValue(); + Injectors.close(injector, errors); + } + injectors.clear(); + errors.throwIfNecessary(); + } + + /** + * Factory method to return the module type that will be used to create an + * injector. + * + * The default implementation will use the system property + * <code>org.guiceyfruit.modules</code> (see + * {@link Injectors#MODULE_CLASS_NAMES} otherwise if that is not set it will + * look for the {@link UseModule} annotation and use the module defined on + * that otherwise it will try look for the inner public static class + * "TestModule" + * + * @see org.apache.camel.guice.testing.UseModule + * @see #NESTED_MODULE_CLASS + */ + @SuppressWarnings("unchecked") + protected Class<? extends Module> getModuleForTestClass(Class<?> objectType) + throws IllegalAccessException, InstantiationException, ClassNotFoundException { + String modules = System.getProperty(Injectors.MODULE_CLASS_NAMES); + if (modules != null) { + modules = modules.trim(); + if (modules.length() > 0) { + System.out.println("Overloading Guice Modules: " + modules); + return null; + } + } + Class<? extends Module> moduleType; + UseModule config = objectType.getAnnotation(UseModule.class); + if (config != null) { + moduleType = config.value(); + } else { + String name = objectType.getName() + "$" + NESTED_MODULE_CLASS; + Class<?> type; + try { + type = objectType.getClassLoader().loadClass(name); + } catch (ClassNotFoundException e) { + try { + type = Thread.currentThread().getContextClassLoader().loadClass(name); + } catch (ClassNotFoundException e2) { + throw new ClassNotFoundException( + "Class " + + objectType.getName() + + " does not have a @UseModule annotation nor does it have a nested class called " + + NESTED_MODULE_CLASS + + " available on the classpath. Please see: http://code.google.com/p/guiceyfruit/wiki/Testing" + + e, e); + } + } + try { + moduleType = (Class<? extends Module>)type; + } catch (Exception e) { + throw new IllegalArgumentException("Class " + type.getName() + " is not a Guice Module!", e); + } + } + int modifiers = moduleType.getModifiers(); + if (Modifier.isAbstract(modifiers) || !Modifier.isPublic(modifiers)) { + throw new IllegalArgumentException("Class " + moduleType.getName() + + " must be a public class which is non abstract"); + } + try { + moduleType.getConstructor(); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException("Class " + moduleType.getName() + + " must have a zero argument constructor", e); + } + return moduleType; + } + + /** + * Creates the injector for the given key + */ + protected Injector createInjector(Class<? extends Module> moduleType) throws InstantiationException, + IllegalAccessException, ClassNotFoundException { + if (moduleType == null) { + return Injectors.createInjector(System.getProperties(), new TestModule()); + } + // System.out.println("Creating Guice Injector from module: " + + // moduleType.getName()); + Module module = moduleType.newInstance(); + return Guice.createInjector(module, new TestModule()); + } +}
Added: camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/TestScoped.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/TestScoped.java?rev=1429309&view=auto ============================================================================== --- camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/TestScoped.java (added) +++ camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/TestScoped.java Sat Jan 5 15:14:02 2013 @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.guice.testing; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.google.inject.Scope; +import com.google.inject.ScopeAnnotation; + +/** + * This defines a {@link Scope} that lasts for a single test run. + * + * <p> + * A test conceptually comes in scope when it starts and goes out of scope when + * it finishes its execution (e.g., on JUnit lingo, roughly at the moment of + * {@link junit.framework.TestCase#setUp()} and + * {@link junit.framework.TestCase#tearDown()}). + * + * @author Luiz-Otavio Zorzella + * @author Danka Karwanska + * @see org.apache.camel.guice.util.CloseableScope for an implementation of this + * scope + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@ScopeAnnotation +public @interface TestScoped { +} \ No newline at end of file Copied: camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/UseModule.java (from r1429285, camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/ConciseGuiceRouteTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/UseModule.java?p2=camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/UseModule.java&p1=camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/ConciseGuiceRouteTest.java&r1=1429285&r2=1429309&rev=1429309&view=diff ============================================================================== --- camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/ConciseGuiceRouteTest.java (original) +++ camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/UseModule.java Sat Jan 5 15:14:02 2013 @@ -14,25 +14,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.guice; +package org.apache.camel.guice.testing; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; -import com.google.inject.Guice; -import com.google.inject.Injector; -import org.junit.Assert; -import org.junit.Test; -/** - * Uses a RouteBuilder to bind instances of routes to the CamelContext - * - * @version - */ -public class ConciseGuiceRouteTest extends Assert { +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.google.inject.Module; - @SuppressWarnings("unchecked") - @Test - public void testGuice() throws Exception { - // lets disable resource injection to avoid JNDI being used - Injector injector = Guice.createInjector(new CamelModuleWithRouteTypes(MyRouteInstaller.class, MyHardcodeRoute.class)); - GuiceTest.assertCamelContextRunningThenCloseInjector(injector); - } -} \ No newline at end of file + +/** + * Specifies the default Guice Module to use when running the test case when + * using <a href="http://code.google.com/p/guiceyfruit/wiki/Testing">Guicey + * Testing</a> + * + */ +@Target({ TYPE }) +@Retention(RUNTIME) +@Documented +public @interface UseModule { + Class<? extends Module> value(); +} Added: camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/junit4/GuiceyJUnit4.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/junit4/GuiceyJUnit4.java?rev=1429309&view=auto ============================================================================== --- camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/junit4/GuiceyJUnit4.java (added) +++ camel/trunk/components/camel-guice/src/test/java/org/apache/camel/guice/testing/junit4/GuiceyJUnit4.java Sat Jan 5 15:14:02 2013 @@ -0,0 +1,92 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.guice.testing.junit4; + +import org.apache.camel.guice.testing.InjectorManager; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; + +public class GuiceyJUnit4 extends BlockJUnit4ClassRunner { + + protected static InjectorManager manager = new InjectorManager(); + + public GuiceyJUnit4(Class<?> aClass) throws InitializationError { + super(aClass); + } + + @Override + protected Statement withBeforeClasses(Statement statement) { + final Statement parent = super.withBeforeClasses(statement); + return new Statement() { + @Override + public void evaluate() throws Throwable { + manager.beforeClasses(); + + parent.evaluate(); + } + }; + } + + @Override + protected Statement withAfterClasses(Statement statement) { + final Statement parent = super.withAfterClasses(statement); + return new Statement() { + @Override + public void evaluate() throws Throwable { + parent.evaluate(); + + manager.afterClasses(); + } + }; + } + + @Override + protected Statement withBefores(FrameworkMethod frameworkMethod, final Object test, Statement statement) { + @SuppressWarnings("deprecation") + final Statement parent = super.withBefores(frameworkMethod, test, statement); + return new Statement() { + @Override + public void evaluate() throws Throwable { + manager.beforeTest(test); + + parent.evaluate(); + } + }; + } + + @SuppressWarnings("deprecation") + @Override + protected Statement withAfters(FrameworkMethod frameworkMethod, final Object test, Statement statement) { + final Statement parent = super.withBefores(frameworkMethod, test, statement); + return new Statement() { + @Override + public void evaluate() throws Throwable { + parent.evaluate(); + + manager.afterTest(test); + } + }; + } + + @Override + public void run(RunNotifier runNotifier) { + super.run(runNotifier); + } +} Modified: camel/trunk/components/camel-guice/src/test/resources/jndi.properties URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-guice/src/test/resources/jndi.properties?rev=1429309&r1=1429308&r2=1429309&view=diff ============================================================================== --- camel/trunk/components/camel-guice/src/test/resources/jndi.properties (original) +++ camel/trunk/components/camel-guice/src/test/resources/jndi.properties Sat Jan 5 15:14:02 2013 @@ -21,7 +21,7 @@ # # Guice JNDI provider -java.naming.factory.initial = org.guiceyfruit.jndi.GuiceInitialContextFactory +java.naming.factory.initial = org.apache.camel.guice.jndi.GuiceInitialContextFactory # list of guice modules to boot up (space separated) org.guiceyfruit.modules = org.apache.camel.guice.CamelModuleWithMatchingRoutes Modified: camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/MyModule.java URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/MyModule.java?rev=1429309&r1=1429308&r2=1429309&view=diff ============================================================================== --- camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/MyModule.java (original) +++ camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/MyModule.java Sat Jan 5 15:14:02 2013 @@ -19,16 +19,16 @@ package org.apache.camel.example.guice.j import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.name.Named; + import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.camel.component.jms.JmsComponent; import org.apache.camel.guice.CamelModuleWithMatchingRoutes; -import org.guiceyfruit.jndi.JndiBind; +import org.apache.camel.guice.jndi.JndiBind; /** * Configures the CamelContext, RouteBuilder, Component and Endpoint instances using * Guice * - * @version */ public class MyModule extends CamelModuleWithMatchingRoutes { Modified: camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/OSGiCamelContextProvider.java URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/OSGiCamelContextProvider.java?rev=1429309&r1=1429308&r2=1429309&view=diff ============================================================================== --- camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/OSGiCamelContextProvider.java (original) +++ camel/trunk/examples/camel-example-guice-jms/src/main/java/org/apache/camel/example/guice/jms/OSGiCamelContextProvider.java Sat Jan 5 15:14:02 2013 @@ -15,22 +15,23 @@ * limitations under the License. */ package org.apache.camel.example.guice.jms; - import java.util.Properties; import java.util.Set; + import javax.naming.Context; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Provider; import com.google.inject.ProvisionException; + import org.apache.camel.CamelContext; import org.apache.camel.RoutesBuilder; +import org.apache.camel.guice.jndi.JndiBindings; +import org.apache.camel.guice.jndi.internal.JndiContext; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.impl.JndiRegistry; import org.apache.camel.osgi.CamelContextFactory; -import org.guiceyfruit.jndi.JndiBindings; -import org.guiceyfruit.jndi.internal.JndiContext; import org.osgi.framework.BundleContext; public class OSGiCamelContextProvider implements Provider<CamelContext> { Modified: camel/trunk/examples/camel-example-guice-jms/src/main/resources/guicejndi.properties URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-guice-jms/src/main/resources/guicejndi.properties?rev=1429309&r1=1429308&r2=1429309&view=diff ============================================================================== --- camel/trunk/examples/camel-example-guice-jms/src/main/resources/guicejndi.properties (original) +++ camel/trunk/examples/camel-example-guice-jms/src/main/resources/guicejndi.properties Sat Jan 5 15:14:02 2013 @@ -21,7 +21,7 @@ # # Guice JNDI provider -java.naming.factory.initial = org.guiceyfruit.jndi.GuiceInitialContextFactory +java.naming.factory.initial = org.apache.camel.guice.jndi.GuiceInitialContextFactory # list of guice modules to boot up (space separated) org.guiceyfruit.modules = org.apache.camel.example.guice.jms.MyModule Modified: camel/trunk/parent/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/parent/pom.xml?rev=1429309&r1=1429308&r2=1429309&view=diff ============================================================================== --- camel/trunk/parent/pom.xml (original) +++ camel/trunk/parent/pom.xml Sat Jan 5 15:14:02 2013 @@ -138,12 +138,13 @@ <geronimo-ws-metadata-spec-version>1.1.3</geronimo-ws-metadata-spec-version> <gmaven-plugin-version>1.4</gmaven-plugin-version> <google-app-engine-version>1.6.6</google-app-engine-version> + <google-collections-version>1.0</google-collections-version> <google-gdata-version>1.41.5.w1</google-gdata-version> <google-guava-version>13.0.1</google-guava-version> <groovy-version>2.0.6</groovy-version> <gson-version>2.2.2</gson-version> - <guice-bundle-version>2.0_2</guice-bundle-version> - <guiceyfruit-version>2.0</guiceyfruit-version> + <guice-bundle-version>3.0_2</guice-bundle-version> + <guice-version>3.0</guice-version> <hadoop-bundle-version>1.0.4_1</hadoop-bundle-version> <hadoop-version>1.0.4</hadoop-version> <hamcrest-version>1.3</hamcrest-version> @@ -1476,9 +1477,14 @@ <!-- optional guice dependencies --> <dependency> - <groupId>org.guiceyfruit</groupId> - <artifactId>guiceyfruit-core</artifactId> - <version>${guiceyfruit-version}</version> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + <version>${guice-version}</version> + </dependency> + <dependency> + <groupId>com.google.collections</groupId> + <artifactId>google-collections</artifactId> + <version>${google-collections-version}</version> </dependency> <!-- optional castor dependencies -->
