Added Spring and JNDI integration.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@258 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/build.properties b/build.properties
index 6bfac26..92d4f20 100644
--- a/build.properties
+++ b/build.properties
@@ -1,4 +1,3 @@
-version=1.0rc2
lib.dir=lib
src.dir=src
test.dir=test
@@ -6,5 +5,5 @@
build.dir=build
javadoc.packagenames=com.google.inject,com.google.inject.spi,\
com.google.inject.matcher,com.google.inject.servlet,com.google.inject.name,\
- com.google.inject.tools.jmx,com.google.inject.binder
+ com.google.inject.tools.jmx,com.google.inject.binder,com.google.inject.jndi
test.class=com.google.inject.AllTests
diff --git a/build.xml b/build.xml
index 61729c4..919cc80 100644
--- a/build.xml
+++ b/build.xml
@@ -26,12 +26,16 @@
<target name="dist" depends="jar, javadoc"
description="Build entire distribution.">
<ant antfile="servlet/build.xml" target="jar" inheritAll="false"/>
+ <ant antfile="spring/build.xml" target="jar" inheritAll="false"/>
<ant antfile="struts2/plugin/build.xml" target="jar" inheritAll="false"/>
<copy toDir="${build.dir}/dist">
<fileset dir="servlet/build" includes="*.jar"/>
</copy>
<copy toDir="${build.dir}/dist">
+ <fileset dir="spring/build" includes="*.jar"/>
+ </copy>
+ <copy toDir="${build.dir}/dist">
<fileset dir="struts2/plugin/build" includes="*.jar"/>
</copy>
@@ -95,6 +99,7 @@
depends="clean"
description="Remove generated files.">
<ant dir="servlet" antfile="build.xml" target="clean"/>
+ <ant dir="spring" antfile="build.xml" target="clean"/>
<ant dir="struts2/plugin" antfile="build.xml" target="clean"/>
</target>
diff --git a/common.xml b/common.xml
index 8343c6a..68ed220 100644
--- a/common.xml
+++ b/common.xml
@@ -3,7 +3,8 @@
<project name="common">
<property file="build.properties"/>
-
+ <property name="version" value="1.0rc3"/>
+
<target name="compile" description="Compile Java source.">
<mkdir dir="${build.dir}/classes"/>
<javac srcdir="${src.dir}"
diff --git a/guice.ipr b/guice.ipr
index a911ed0..9f97b57 100644
--- a/guice.ipr
+++ b/guice.ipr
@@ -347,6 +347,7 @@
<modules>
<module fileurl="file://$PROJECT_DIR$/guice.iml" filepath="$PROJECT_DIR$/guice.iml" />
<module fileurl="file://$PROJECT_DIR$/servlet/servlet.iml" filepath="$PROJECT_DIR$/servlet/servlet.iml" />
+ <module fileurl="file://$PROJECT_DIR$/spring/spring.iml" filepath="$PROJECT_DIR$/spring/spring.iml" />
<module fileurl="file://$PROJECT_DIR$/struts2/example/struts2-example.iml" filepath="$PROJECT_DIR$/struts2/example/struts2-example.iml" />
<module fileurl="file://$PROJECT_DIR$/struts2/plugin/struts2-plugin.iml" filepath="$PROJECT_DIR$/struts2/plugin/struts2-plugin.iml" />
</modules>
diff --git a/servlet/build.properties b/servlet/build.properties
index 56546f0..9722f8b 100644
--- a/servlet/build.properties
+++ b/servlet/build.properties
@@ -1,4 +1,3 @@
-version=1.0rc2
lib.dir=lib
src.dir=src
test.dir=test
diff --git a/spring/build.properties b/spring/build.properties
new file mode 100644
index 0000000..2ee6533
--- /dev/null
+++ b/spring/build.properties
@@ -0,0 +1,5 @@
+src.dir=src
+test.dir=test
+build.dir=build
+test.class=com.google.inject.spring.SpringTest
+
diff --git a/spring/build.xml b/spring/build.xml
new file mode 100644
index 0000000..b331ba7
--- /dev/null
+++ b/spring/build.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<project name="guice-spring" basedir="." default="jar">
+
+ <import file="../common.xml"/>
+
+ <path id="compile.classpath">
+ <fileset dir="../lib" includes="*.jar"/>
+ <fileset dir="../lib/build" includes="*.jar"/>
+ <fileset dir="../build/dist" includes="*.jar"/>
+ </path>
+
+ <target name="jar" depends="compile"
+ description="Build jar.">
+ <mkdir dir="${build.dir}"/>
+ <jar destfile="${build.dir}/${ant.project.name}-${version}.jar">
+ <fileset dir="${build.dir}/classes"/>
+ </jar>
+ </target>
+
+</project>
diff --git a/spring/spring.iml b/spring/spring.iml
new file mode 100644
index 0000000..c6fae4c
--- /dev/null
+++ b/spring/spring.iml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4" relativePaths="true" type="JAVA_MODULE">
+ <component name="ModuleRootManager" />
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="guice" />
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../lib/build/spring-beans.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../lib/build/spring-core.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../lib/build/junit.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../lib/build/commons-logging-1.0.4.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntryProperties />
+ </component>
+</module>
+
diff --git a/spring/src/com/google/inject/spring/SpringIntegration.java b/spring/src/com/google/inject/spring/SpringIntegration.java
new file mode 100644
index 0000000..f791ae8
--- /dev/null
+++ b/spring/src/com/google/inject/spring/SpringIntegration.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * 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 com.google.inject.spring;
+
+import com.google.inject.Provider;
+import com.google.inject.Inject;
+import org.springframework.beans.factory.BeanFactory;
+
+/**
+ * Integrates Guice with Spring. Requires a binding to
+ * {@link org.springframework.beans.factory.BeanFactory}.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class SpringIntegration {
+
+ private SpringIntegration() {}
+
+ /**
+ * Creates a provider which looks up objects from Spring using the given name.
+ * Example usage:
+ *
+ * <pre>
+ * bind(DataSource.class).toProvider(fromSpring(DataSource.class, "dataSource"));
+ * </pre>
+ */
+ public static <T> Provider<T> fromSpring(Class<T> type, String name) {
+ return new SpringProvider<T>(type, name);
+ }
+
+ static class SpringProvider<T> implements Provider<T> {
+
+ BeanFactory beanFactory;
+ boolean singleton;
+ final Class<T> type;
+ final String name;
+
+ public SpringProvider(Class<T> type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ @Inject
+ void initialize(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ if (!beanFactory.isTypeMatch(name, type)) {
+ throw new ClassCastException("Spring bean named '" + name
+ + "' does not implement " + type.getName() + ".");
+ }
+ singleton = beanFactory.isSingleton(name);
+ }
+
+ public T get() {
+ return singleton ? getSingleton() : type.cast(beanFactory.getBean(name));
+ }
+
+ volatile T instance;
+
+ private T getSingleton() {
+ if (instance == null) {
+ instance = type.cast(beanFactory.getBean(name));
+ }
+ return instance;
+ }
+ }
+}
diff --git a/spring/test/com/google/inject/spring/SpringIntegrationTest.java b/spring/test/com/google/inject/spring/SpringIntegrationTest.java
new file mode 100644
index 0000000..048c050
--- /dev/null
+++ b/spring/test/com/google/inject/spring/SpringIntegrationTest.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * 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 com.google.inject.spring;
+
+import junit.framework.TestCase;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.BeanFactory;
+import com.google.inject.PerformanceComparison.TeeImpl;
+import com.google.inject.Injector;
+import com.google.inject.Guice;
+import com.google.inject.AbstractModule;
+import com.google.inject.CreationException;
+import static com.google.inject.spring.SpringIntegration.*;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class SpringIntegrationTest extends TestCase {
+
+ public void testSpringIntegration() throws CreationException {
+ final DefaultListableBeanFactory beanFactory
+ = new DefaultListableBeanFactory();
+
+ RootBeanDefinition singleton
+ = new RootBeanDefinition(Singleton.class);
+ beanFactory.registerBeanDefinition("singleton", singleton);
+
+ RootBeanDefinition prototype
+ = new RootBeanDefinition(Prototype.class, false);
+ beanFactory.registerBeanDefinition("prototype", prototype);
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bind(BeanFactory.class).toInstance(beanFactory);
+ bind(Singleton.class)
+ .toProvider(fromSpring(Singleton.class, "singleton"));
+ bind(Prototype.class)
+ .toProvider(fromSpring(Prototype.class, "prototype"));
+ }
+ });
+
+ assertNotNull(injector.getInstance(Singleton.class));
+ assertSame(injector.getInstance(Singleton.class),
+ injector.getInstance(Singleton.class));
+
+ assertNotNull(injector.getInstance(Prototype.class));
+ assertNotSame(injector.getInstance(Prototype.class),
+ injector.getInstance(Prototype.class));
+ }
+
+ static class Singleton {}
+ static class Prototype {}
+}
diff --git a/src/com/google/inject/jndi/JndiIntegration.java b/src/com/google/inject/jndi/JndiIntegration.java
new file mode 100644
index 0000000..fea706b
--- /dev/null
+++ b/src/com/google/inject/jndi/JndiIntegration.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * 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 com.google.inject.jndi;
+
+import com.google.inject.Provider;
+import com.google.inject.Inject;
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+/**
+ * Integrates Guice with JNDI. Requires a binding to
+ * {@link javax.naming.Context}.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class JndiIntegration {
+
+ private JndiIntegration() {}
+
+ /**
+ * Creates a provider which looks up objects in JNDI using the given name.
+ * Example usage:
+ *
+ * <pre>
+ * bind(DataSource.class).toProvider(fromJndi(DataSource.class, "java:..."));
+ * </pre>
+ */
+ public static <T> Provider<T> fromJndi(Class<T> type, String name) {
+ return new JndiProvider<T>(type, name);
+ }
+
+ static class JndiProvider<T> implements Provider<T> {
+
+ @Inject Context context;
+ final Class<T> type;
+ final String name;
+
+ public JndiProvider(Class<T> type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ public T get() {
+ try {
+ return type.cast(context.lookup(name));
+ }
+ catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/struts2/plugin/build.properties b/struts2/plugin/build.properties
index 31ee68d..a155282 100644
--- a/struts2/plugin/build.properties
+++ b/struts2/plugin/build.properties
@@ -1,4 +1,3 @@
-version=1.0rc2
lib.dir=../lib
src.dir=src
build.dir=build