Added intercept() to ContainerBuilder. Hid ConstructionProxy, ProxyFactory, etc. Removed intercept package. Added query package. Started Struts 2 plugin and example.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@111 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/build.properties b/build.properties
index ea4aa7d..6f148d2 100644
--- a/build.properties
+++ b/build.properties
@@ -3,4 +3,4 @@
src.dir=src
test.dir=test
build.dir=build
-javadoc.packagenames=com.google.inject,com.google.inject.spi,com.google.inject.intercept,com.google.inject.servlet
+javadoc.packagenames=com.google.inject,com.google.inject.spi,com.google.inject.query,com.google.inject.servlet
diff --git a/guice.ipr b/guice.ipr
index b7a3645..102ee18 100644
--- a/guice.ipr
+++ b/guice.ipr
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project version="4" relativePaths="false">
+<project version="4" relativePaths="true">
<component name="AntConfiguration">
<defaultAnt bundledAnt="true" />
</component>
<component name="Build editor project-level loader">
<settings>
<class-settings class="com.google.devtools.intellig.configcheck.ProjectPathChecker" />
- <class-settings class="com.google.devtools.intellig.configcheck.PythonSdkChecker" />
<class-settings class="com.google.devtools.intellig.configcheck.ProjectJdkChecker">
- <setting name="getProjectJdk" value="/usr/local/buildtools/java/jdk1.5.0_06" />
+ <setting name="getProjectJdk" value="$PROJECT_DIR$/../../buildtools/java/jdk1.5.0_06" />
<setting name="getModuleJdks" value="rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAABA/QAAAAAAAAHg=" />
</class-settings>
+ <class-settings class="com.google.devtools.intellig.configcheck.PythonSdkChecker" />
<class-settings class="com.google.devtools.intellig.configcheck.ClearOutputChecker" />
</settings>
</component>
@@ -822,9 +822,10 @@
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/guice.iml" filepath="$PROJECT_DIR$/guice.iml" />
+ <module fileurl="file://$PROJECT_DIR$/struts2/struts2.iml" filepath="$PROJECT_DIR$/struts2/struts2.iml" />
</modules>
</component>
- <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" />
+ <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK" />
<component name="ProjectRunConfigurationManager" />
<component name="RmicSettings">
<option name="IS_EANABLED" value="false" />
diff --git a/src/com/google/inject/spi/ConstructionProxy.java b/src/com/google/inject/ConstructionProxy.java
similarity index 92%
rename from src/com/google/inject/spi/ConstructionProxy.java
rename to src/com/google/inject/ConstructionProxy.java
index e9f521d..1c2af95 100644
--- a/src/com/google/inject/spi/ConstructionProxy.java
+++ b/src/com/google/inject/ConstructionProxy.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.inject.spi;
+package com.google.inject;
import java.lang.reflect.InvocationTargetException;
@@ -24,7 +24,7 @@
*
* @author crazybob@google.com (Bob Lee)
*/
-public interface ConstructionProxy<T> {
+interface ConstructionProxy<T> {
/**
* Constructs an instance of {@code T} for the given arguments.
diff --git a/src/com/google/inject/spi/ConstructionProxyFactory.java b/src/com/google/inject/ConstructionProxyFactory.java
similarity index 91%
rename from src/com/google/inject/spi/ConstructionProxyFactory.java
rename to src/com/google/inject/ConstructionProxyFactory.java
index a5d2649..9bdf137 100644
--- a/src/com/google/inject/spi/ConstructionProxyFactory.java
+++ b/src/com/google/inject/ConstructionProxyFactory.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.inject.spi;
+package com.google.inject;
import java.lang.reflect.Constructor;
@@ -23,7 +23,7 @@
*
* @author crazybob@google.com (Bob Lee)
*/
-public interface ConstructionProxyFactory {
+interface ConstructionProxyFactory {
/**
* Gets a construction proxy for the given constructor.
diff --git a/src/com/google/inject/ConstructorInjector.java b/src/com/google/inject/ConstructorInjector.java
index c1f3e92..8d93cdb 100644
--- a/src/com/google/inject/ConstructorInjector.java
+++ b/src/com/google/inject/ConstructorInjector.java
@@ -16,7 +16,7 @@
package com.google.inject;
-import com.google.inject.spi.ConstructionProxy;
+import com.google.inject.ConstructionProxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index ac64662..af82250 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -16,18 +16,23 @@
package com.google.inject;
-import com.google.inject.spi.ConstructionProxyFactory;
-import com.google.inject.spi.DefaultConstructionProxyFactory;
+import static com.google.inject.Scopes.CONTAINER;
+import static com.google.inject.Scopes.CONTAINER_NAME;
+import static com.google.inject.Scopes.DEFAULT;
+import static com.google.inject.Scopes.DEFAULT_NAME;
import com.google.inject.spi.Message;
import com.google.inject.spi.SourceConsumer;
import com.google.inject.util.Objects;
import static com.google.inject.util.Objects.nonNull;
import com.google.inject.util.Stopwatch;
import com.google.inject.util.ToStringBuilder;
-import static com.google.inject.Scopes.*;
+import com.google.inject.query.Query;
-import java.lang.reflect.Member;
+import org.aopalliance.intercept.MethodInterceptor;
+
import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -98,29 +103,19 @@
static final String UNKNOWN_SOURCE = "[unknown source]";
- final ConstructionProxyFactory constructionProxyFactory;
+ final ProxyFactoryBuilder proxyFactoryBuilder;
/**
* Constructs a new builder.
- *
- * @param constructionProxyFactory to use when constructing objects
*/
- public ContainerBuilder(ConstructionProxyFactory constructionProxyFactory) {
+ public ContainerBuilder() {
scope(DEFAULT_NAME, DEFAULT);
scope(CONTAINER_NAME, CONTAINER);
bind(Container.class).to(CONTAINER_FACTORY);
bind(Logger.class).to(LOGGER_FACTORY);
- this.constructionProxyFactory = nonNull(constructionProxyFactory,
- "construction proxy factory");
- }
-
- /**
- * Constructs a new builder.
- */
- public ContainerBuilder() {
- this(new DefaultConstructionProxyFactory());
+ this.proxyFactoryBuilder = new ProxyFactoryBuilder();
}
final List<Validation> validations = new ArrayList<Validation>();
@@ -151,6 +146,21 @@
}
/**
+ * Applies the given method interceptor to the methods matched by the class
+ * and method queries.
+ *
+ * @param classQuery matches classes the interceptor should apply to. For
+ * example: {@code only(Runnable.class)}.
+ * @param methodQuery matches methods the interceptor should apply to. For
+ * example: {@code annotatedWith(Transactional.class)}.
+ * @param interceptors to apply
+ */
+ public void intercept(Query<? super Class<?>> classQuery,
+ Query<? super Method> methodQuery, MethodInterceptor... interceptors) {
+ proxyFactoryBuilder.intercept(classQuery, methodQuery, interceptors);
+ }
+
+ /**
* Adds a new scope. Maps a {@link Scope} instance to a given scope name.
* Scopes should be mapped before used in bindings. {@link Scoped#value()}
* references this name.
@@ -298,7 +308,8 @@
ensureNotCreated();
Map<Key<?>, Binding<?>> bindings =
new HashMap<Key<?>, Binding<?>>();
- container = new ContainerImpl(constructionProxyFactory, bindings);
+ container = new ContainerImpl(
+ proxyFactoryBuilder.create(), bindings);
createConstantBindings();
diff --git a/src/com/google/inject/ContainerImpl.java b/src/com/google/inject/ContainerImpl.java
index 6e9eaad..564efe0 100644
--- a/src/com/google/inject/ContainerImpl.java
+++ b/src/com/google/inject/ContainerImpl.java
@@ -20,7 +20,7 @@
import com.google.inject.util.Strings;
import com.google.inject.util.ToStringBuilder;
import com.google.inject.util.GuiceFastClass;
-import com.google.inject.spi.ConstructionProxyFactory;
+import com.google.inject.ConstructionProxyFactory;
import net.sf.cglib.reflect.FastMethod;
diff --git a/src/com/google/inject/spi/DefaultConstructionProxyFactory.java b/src/com/google/inject/DefaultConstructionProxyFactory.java
similarity index 95%
rename from src/com/google/inject/spi/DefaultConstructionProxyFactory.java
rename to src/com/google/inject/DefaultConstructionProxyFactory.java
index 4192316..02c8266 100644
--- a/src/com/google/inject/spi/DefaultConstructionProxyFactory.java
+++ b/src/com/google/inject/DefaultConstructionProxyFactory.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.google.inject.spi;
+package com.google.inject;
+
+import com.google.inject.util.GuiceFastClass;
import net.sf.cglib.reflect.FastClass;
import net.sf.cglib.reflect.FastConstructor;
@@ -22,8 +24,6 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import com.google.inject.util.GuiceFastClass;
-
/**
* Default {@link ConstructionProxyFactory} implementation. Simply invokes the
* constructor. Can be reused by other {@code ConstructionProxyFactory}
@@ -31,7 +31,7 @@
*
* @author crazybob@google.com (Bob Lee)
*/
-public class DefaultConstructionProxyFactory
+class DefaultConstructionProxyFactory
implements ConstructionProxyFactory {
public <T> ConstructionProxy<T> get(Constructor<T> constructor) {
diff --git a/src/com/google/inject/intercept/InterceptorStackCallback.java b/src/com/google/inject/InterceptorStackCallback.java
similarity index 98%
rename from src/com/google/inject/intercept/InterceptorStackCallback.java
rename to src/com/google/inject/InterceptorStackCallback.java
index 5c31378..015a045 100644
--- a/src/com/google/inject/intercept/InterceptorStackCallback.java
+++ b/src/com/google/inject/InterceptorStackCallback.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject;
import net.sf.cglib.proxy.MethodProxy;
diff --git a/src/com/google/inject/intercept/MethodAspect.java b/src/com/google/inject/MethodAspect.java
similarity index 95%
rename from src/com/google/inject/intercept/MethodAspect.java
rename to src/com/google/inject/MethodAspect.java
index 1e5bee4..2d71add 100644
--- a/src/com/google/inject/intercept/MethodAspect.java
+++ b/src/com/google/inject/MethodAspect.java
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject;
import com.google.inject.util.Objects;
+import com.google.inject.query.Query;
import org.aopalliance.intercept.MethodInterceptor;
diff --git a/src/com/google/inject/intercept/ProxyFactory.java b/src/com/google/inject/ProxyFactory.java
similarity index 95%
rename from src/com/google/inject/intercept/ProxyFactory.java
rename to src/com/google/inject/ProxyFactory.java
index 3fc784c..8ec4f9a 100644
--- a/src/com/google/inject/intercept/ProxyFactory.java
+++ b/src/com/google/inject/ProxyFactory.java
@@ -14,32 +14,28 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject;
-import com.google.inject.spi.ConstructionProxyFactory;
-import com.google.inject.spi.ConstructionProxy;
-import com.google.inject.spi.DefaultConstructionProxyFactory;
-import com.google.inject.util.ReferenceCache;
import com.google.inject.util.GuiceFastClass;
import com.google.inject.util.GuiceNamingPolicy;
-import com.google.inject.Factory;
+import com.google.inject.util.ReferenceCache;
-import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.NoOp;
import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.NoOp;
import net.sf.cglib.reflect.FastClass;
import net.sf.cglib.reflect.FastConstructor;
import org.aopalliance.intercept.MethodInterceptor;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* Proxies classes applying interceptors to methods as specified in
@@ -47,7 +43,7 @@
*
* @author crazybob@google.com (Bob Lee)
*/
-public class ProxyFactory implements ConstructionProxyFactory {
+class ProxyFactory implements ConstructionProxyFactory {
final List<MethodAspect> methodAspects;
final ConstructionProxyFactory defaultFactory =
diff --git a/src/com/google/inject/intercept/ProxyFactoryBuilder.java b/src/com/google/inject/ProxyFactoryBuilder.java
similarity index 94%
rename from src/com/google/inject/intercept/ProxyFactoryBuilder.java
rename to src/com/google/inject/ProxyFactoryBuilder.java
index eb08af6..ee89f9b 100644
--- a/src/com/google/inject/intercept/ProxyFactoryBuilder.java
+++ b/src/com/google/inject/ProxyFactoryBuilder.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject;
+
+import com.google.inject.query.Query;
import org.aopalliance.intercept.MethodInterceptor;
@@ -27,7 +29,7 @@
*
* @author crazybob@google.com (Bob Lee)
*/
-public class ProxyFactoryBuilder {
+class ProxyFactoryBuilder {
final List<MethodAspect> methodAspects = new ArrayList<MethodAspect>();
diff --git a/src/com/google/inject/intercept/AbstractQuery.java b/src/com/google/inject/query/AbstractQuery.java
similarity index 97%
rename from src/com/google/inject/intercept/AbstractQuery.java
rename to src/com/google/inject/query/AbstractQuery.java
index c6732f9..287cbdb 100644
--- a/src/com/google/inject/intercept/AbstractQuery.java
+++ b/src/com/google/inject/query/AbstractQuery.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject.query;
/**
* Implements {@code and()} and {@code or()}.
diff --git a/src/com/google/inject/intercept/Queries.java b/src/com/google/inject/query/Queries.java
similarity index 98%
rename from src/com/google/inject/intercept/Queries.java
rename to src/com/google/inject/query/Queries.java
index d1b8d8b..880d192 100644
--- a/src/com/google/inject/intercept/Queries.java
+++ b/src/com/google/inject/query/Queries.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject.query;
import com.google.inject.util.Objects;
diff --git a/src/com/google/inject/intercept/Query.java b/src/com/google/inject/query/Query.java
similarity index 96%
rename from src/com/google/inject/intercept/Query.java
rename to src/com/google/inject/query/Query.java
index f9aded7..1b26a01 100644
--- a/src/com/google/inject/intercept/Query.java
+++ b/src/com/google/inject/query/Query.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject.query;
/**
* Returns {@code true} or {@code false} for a given input.
diff --git a/src/com/google/inject/intercept/package-info.java b/src/com/google/inject/query/package-info.java
similarity index 69%
rename from src/com/google/inject/intercept/package-info.java
rename to src/com/google/inject/query/package-info.java
index 663ed7e..6553436 100644
--- a/src/com/google/inject/intercept/package-info.java
+++ b/src/com/google/inject/query/package-info.java
@@ -15,10 +15,6 @@
*/
/**
- * A simple and very efficient AOP Alliance-based interception framework for
- * Guice. To use with Guice, create a
- * {@link com.google.inject.intercept.ProxyFactory} and pass it to
- * {@link com.google.inject.ContainerBuilder}.
+ * A query API. Used to pick out methods to which to apply interceptors.
*/
-
-package com.google.inject.intercept;
\ No newline at end of file
+package com.google.inject.query;
\ No newline at end of file
diff --git a/src/com/google/inject/servlet/GuiceFilter.java b/src/com/google/inject/servlet/GuiceFilter.java
index 6d880b5..5a890e3 100644
--- a/src/com/google/inject/servlet/GuiceFilter.java
+++ b/src/com/google/inject/servlet/GuiceFilter.java
@@ -19,12 +19,13 @@
import java.io.IOException;
import javax.servlet.Filter;
+import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
-import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
/**
* Apply this filter to all requests where you plan to use servlet scopes.
@@ -33,30 +34,58 @@
*/
public class GuiceFilter implements Filter {
- static ThreadLocal<HttpServletRequest> localRequest =
- new ThreadLocal<HttpServletRequest>();
+ static ThreadLocal<Context> localContext = new ThreadLocal<Context>();
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
- HttpServletRequest previous = localRequest.get();
+ Context previous = localContext.get();
try {
- localRequest.set((HttpServletRequest) servletRequest);
+ localContext.set(new Context((HttpServletRequest) servletRequest,
+ (HttpServletResponse) servletResponse));
filterChain.doFilter(servletRequest, servletResponse);
} finally {
- localRequest.set(previous);
+ localContext.set(previous);
}
}
static HttpServletRequest getRequest() {
- HttpServletRequest request = localRequest.get();
- if (request == null) {
+ return getContext().getRequest();
+ }
+
+ static HttpServletResponse getResponse() {
+ return getContext().getResponse();
+ }
+
+ static Context getContext() {
+ Context context = localContext.get();
+ if (context == null) {
throw new RuntimeException("Please apply " + GuiceFilter.class.getName()
- + " to any request which uses servlet scopes.");
+ + " to any request which uses servlet scopes.");
}
- return request;
+ return context;
+ }
+
+ static class Context {
+
+ final HttpServletRequest request;
+ final HttpServletResponse response;
+
+ Context(HttpServletRequest request, HttpServletResponse response) {
+ this.request = request;
+ this.response = response;
+ }
+
+ HttpServletRequest getRequest() {
+ return request;
+ }
+
+ HttpServletResponse getResponse() {
+ return response;
+ }
}
public void init(FilterConfig filterConfig) throws ServletException {}
+
public void destroy() {}
}
diff --git a/src/com/google/inject/servlet/ServletModule.java b/src/com/google/inject/servlet/ServletModule.java
index c47bc92..fb07713 100644
--- a/src/com/google/inject/servlet/ServletModule.java
+++ b/src/com/google/inject/servlet/ServletModule.java
@@ -17,17 +17,75 @@
package com.google.inject.servlet;
import com.google.inject.AbstractModule;
-import static com.google.inject.servlet.ServletScopes.*;
+import com.google.inject.Factory;
+import com.google.inject.TypeLiteral;
+import static com.google.inject.servlet.ServletScopes.REQUEST;
+import static com.google.inject.servlet.ServletScopes.REQUEST_NAME;
+import static com.google.inject.servlet.ServletScopes.SESSION;
+import static com.google.inject.servlet.ServletScopes.SESSION_NAME;
+
+import java.util.Map;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
/**
- * Configures the servlet scopes.
+ * Configures the servlet scopes and creates bindings for the servlet API
+ * objects so you can inject the request, response, session, etc.
*
* @author crazybob@google.com (Bob Lee)
*/
public class ServletModule extends AbstractModule {
+ /**
+ * Name of the request parameters binding. The type is {@code
+ * Map<String, String[]>}.
+ */
+ public static final String REQUEST_PARAMETERS = "requestParameters";
+
protected void configure() {
+ // Scopes.
scope(REQUEST_NAME, REQUEST);
scope(SESSION_NAME, SESSION);
+
+ // Bind request.
+ Factory<HttpServletRequest> requestFactory =
+ new Factory<HttpServletRequest>() {
+ public HttpServletRequest get() {
+ return GuiceFilter.getRequest();
+ }
+ };
+ bind(HttpServletRequest.class).to(requestFactory);
+ bind(ServletRequest.class).to(requestFactory);
+
+ // Bind response.
+ Factory<HttpServletResponse> responseFactory =
+ new Factory<HttpServletResponse>() {
+ public HttpServletResponse get() {
+ return GuiceFilter.getResponse();
+ }
+ };
+ bind(HttpServletResponse.class).to(responseFactory);
+ bind(ServletResponse.class).to(responseFactory);
+
+ // Bind session.
+ bind(HttpSession.class).to(new Factory<HttpSession>() {
+ public HttpSession get() {
+ return GuiceFilter.getRequest().getSession();
+ }
+ });
+
+ // Bind request parameters.
+ bind(new TypeLiteral<Map<String, String[]>>() {})
+ .named(REQUEST_PARAMETERS)
+ .to(new Factory<Map<String, String[]>>() {
+ @SuppressWarnings({"unchecked"})
+ public Map<String, String[]> get() {
+ return GuiceFilter.getRequest().getParameterMap();
+ }
+ });
}
}
diff --git a/struts2/example/root/WEB-INF/Counter.jsp b/struts2/example/root/WEB-INF/Counter.jsp
new file mode 100644
index 0000000..0a1ead0
--- /dev/null
+++ b/struts2/example/root/WEB-INF/Counter.jsp
@@ -0,0 +1,9 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+<html>
+ <body>
+ <h1>Counter Example</h1>
+ <h3><b>Hits in this session:</b>
+ <s:property value="count"/></h3>
+ </body>
+</html>
\ No newline at end of file
diff --git a/struts2/example/root/WEB-INF/classes/struts.xml b/struts2/example/root/WEB-INF/classes/struts.xml
new file mode 100644
index 0000000..a09f87a
--- /dev/null
+++ b/struts2/example/root/WEB-INF/classes/struts.xml
@@ -0,0 +1,17 @@
+<!DOCTYPE struts PUBLIC
+ "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
+ "http://struts.apache.org/dtds/struts-2.0.dtd">
+
+<struts>
+
+ <constant name="guice.module"
+ value="com.google.inject.struts2.example.ExampleModule"/>
+
+ <package name="default" extends="struts-default">
+ <action name="Counter"
+ class="com.google.inject.struts2.example.CounterAction">
+ <result>/WEB-INF/Counter.jsp</result>
+ </action>
+ </package>
+
+</struts>
diff --git a/struts2/example/root/WEB-INF/web.xml b/struts2/example/root/WEB-INF/web.xml
new file mode 100644
index 0000000..b2d53fd
--- /dev/null
+++ b/struts2/example/root/WEB-INF/web.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+
+ <filter>
+ <filter-name>guice</filter-name>
+ <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
+ </filter>
+
+ <filter>
+ <filter-name>struts2</filter-name>
+ <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>guice</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name>struts2</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+</web-app>
diff --git a/src/com/google/inject/intercept/package-info.java b/struts2/example/src/com/google/inject/struts2/example/Counter.java
similarity index 67%
copy from src/com/google/inject/intercept/package-info.java
copy to struts2/example/src/com/google/inject/struts2/example/Counter.java
index 663ed7e..a3ad8a7 100644
--- a/src/com/google/inject/intercept/package-info.java
+++ b/struts2/example/src/com/google/inject/struts2/example/Counter.java
@@ -14,11 +14,20 @@
* limitations under the License.
*/
-/**
- * A simple and very efficient AOP Alliance-based interception framework for
- * Guice. To use with Guice, create a
- * {@link com.google.inject.intercept.ProxyFactory} and pass it to
- * {@link com.google.inject.ContainerBuilder}.
- */
+package com.google.inject.struts2.example;
-package com.google.inject.intercept;
\ No newline at end of file
+import com.google.inject.servlet.SessionScoped;
+
+/**
+ * Counts requests per session.
+ */
+@SessionScoped
+public class Counter {
+
+ int count = 0;
+
+ /** Increments the count and returns the new value. */
+ public int increment() {
+ return count++;
+ }
+}
diff --git a/src/com/google/inject/spi/ConstructionProxyFactory.java b/struts2/example/src/com/google/inject/struts2/example/CounterAction.java
similarity index 60%
copy from src/com/google/inject/spi/ConstructionProxyFactory.java
copy to struts2/example/src/com/google/inject/struts2/example/CounterAction.java
index a5d2649..3df78b0 100644
--- a/src/com/google/inject/spi/ConstructionProxyFactory.java
+++ b/struts2/example/src/com/google/inject/struts2/example/CounterAction.java
@@ -14,19 +14,26 @@
* limitations under the License.
*/
-package com.google.inject.spi;
+package com.google.inject.struts2.example;
-import java.lang.reflect.Constructor;
+import com.google.inject.Inject;
-/**
- * Creates {@link ConstructionProxy} instances.
- *
- * @author crazybob@google.com (Bob Lee)
- */
-public interface ConstructionProxyFactory {
+import static com.opensymphony.xwork2.Action.SUCCESS;
- /**
- * Gets a construction proxy for the given constructor.
- */
- <T> ConstructionProxy<T> get(Constructor<T> constructor);
+public class CounterAction {
+
+ final Counter counter;
+
+ @Inject
+ public CounterAction(Counter counter) {
+ this.counter = counter;
+ }
+
+ public String execute() {
+ return SUCCESS;
+ }
+
+ public int getCount() {
+ return counter.increment();
+ }
}
diff --git a/src/com/google/inject/spi/ConstructionProxyFactory.java b/struts2/example/src/com/google/inject/struts2/example/ExampleModule.java
similarity index 68%
copy from src/com/google/inject/spi/ConstructionProxyFactory.java
copy to struts2/example/src/com/google/inject/struts2/example/ExampleModule.java
index a5d2649..4989efc 100644
--- a/src/com/google/inject/spi/ConstructionProxyFactory.java
+++ b/struts2/example/src/com/google/inject/struts2/example/ExampleModule.java
@@ -14,19 +14,18 @@
* limitations under the License.
*/
-package com.google.inject.spi;
+package com.google.inject.struts2.example;
-import java.lang.reflect.Constructor;
+import com.google.inject.AbstractModule;
/**
- * Creates {@link ConstructionProxy} instances.
+ * Example application module.
*
* @author crazybob@google.com (Bob Lee)
*/
-public interface ConstructionProxyFactory {
+public class ExampleModule extends AbstractModule {
- /**
- * Gets a construction proxy for the given constructor.
- */
- <T> ConstructionProxy<T> get(Constructor<T> constructor);
+ protected void configure() {
+ bind(Counter.class);
+ }
}
diff --git a/struts2/example/src/com/google/inject/struts2/example/Main.java b/struts2/example/src/com/google/inject/struts2/example/Main.java
new file mode 100644
index 0000000..60fd0be
--- /dev/null
+++ b/struts2/example/src/com/google/inject/struts2/example/Main.java
@@ -0,0 +1,42 @@
+/**
+ * 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.struts2.example;
+
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+
+/**
+ * Starts the example web server on port 8080. Run from "./struts2/example".
+ */
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+ Server server = new Server();
+
+ Connector connector = new SelectChannelConnector();
+ connector.setPort(8080);
+ server.setConnectors(new Connector[] { connector });
+
+ WebAppContext webapp = new WebAppContext("./root", "/example");
+ server.addHandler(webapp);
+
+ server.start();
+ server.join();
+ }
+}
diff --git a/struts2/lib/ant-1.6.5.jar b/struts2/lib/ant-1.6.5.jar
new file mode 100644
index 0000000..3beb3b8
--- /dev/null
+++ b/struts2/lib/ant-1.6.5.jar
Binary files differ
diff --git a/struts2/lib/commons-logging-1.0.4.jar b/struts2/lib/commons-logging-1.0.4.jar
new file mode 100644
index 0000000..b73a80f
--- /dev/null
+++ b/struts2/lib/commons-logging-1.0.4.jar
Binary files differ
diff --git a/struts2/lib/core-3.1.1.jar b/struts2/lib/core-3.1.1.jar
new file mode 100644
index 0000000..ae0b635
--- /dev/null
+++ b/struts2/lib/core-3.1.1.jar
Binary files differ
diff --git a/struts2/lib/freemarker-2.3.8.jar b/struts2/lib/freemarker-2.3.8.jar
new file mode 100644
index 0000000..737bfb5
--- /dev/null
+++ b/struts2/lib/freemarker-2.3.8.jar
Binary files differ
diff --git a/struts2/lib/jetty-6.1.0.jar b/struts2/lib/jetty-6.1.0.jar
new file mode 100644
index 0000000..6b01acd
--- /dev/null
+++ b/struts2/lib/jetty-6.1.0.jar
Binary files differ
diff --git a/struts2/lib/jetty-util-6.1.0.jar b/struts2/lib/jetty-util-6.1.0.jar
new file mode 100644
index 0000000..b2afbc0
--- /dev/null
+++ b/struts2/lib/jetty-util-6.1.0.jar
Binary files differ
diff --git a/struts2/lib/jsp-2.1.jar b/struts2/lib/jsp-2.1.jar
new file mode 100644
index 0000000..c07d0f9
--- /dev/null
+++ b/struts2/lib/jsp-2.1.jar
Binary files differ
diff --git a/struts2/lib/jsp-api-2.1.jar b/struts2/lib/jsp-api-2.1.jar
new file mode 100644
index 0000000..3ecd2f5
--- /dev/null
+++ b/struts2/lib/jsp-api-2.1.jar
Binary files differ
diff --git a/struts2/lib/ognl-2.6.9.jar b/struts2/lib/ognl-2.6.9.jar
new file mode 100644
index 0000000..0f1c0fb
--- /dev/null
+++ b/struts2/lib/ognl-2.6.9.jar
Binary files differ
diff --git a/struts2/lib/servlet-api-2.5.jar b/struts2/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..fb52493
--- /dev/null
+++ b/struts2/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/struts2/lib/struts-2.0.5-lib.zip b/struts2/lib/struts-2.0.5-lib.zip
new file mode 100644
index 0000000..d5d75bf
--- /dev/null
+++ b/struts2/lib/struts-2.0.5-lib.zip
Binary files differ
diff --git a/struts2/lib/struts2-api-2.0.5.jar b/struts2/lib/struts2-api-2.0.5.jar
new file mode 100644
index 0000000..0d59962
--- /dev/null
+++ b/struts2/lib/struts2-api-2.0.5.jar
Binary files differ
diff --git a/struts2/lib/struts2-core-2.0.5.jar b/struts2/lib/struts2-core-2.0.5.jar
new file mode 100644
index 0000000..5e8702b
--- /dev/null
+++ b/struts2/lib/struts2-core-2.0.5.jar
Binary files differ
diff --git a/struts2/lib/xwork-2.0.0.jar b/struts2/lib/xwork-2.0.0.jar
new file mode 100644
index 0000000..1418069
--- /dev/null
+++ b/struts2/lib/xwork-2.0.0.jar
Binary files differ
diff --git a/struts2/plugin/src/com/google/inject/struts2/GuiceObjectFactory.java b/struts2/plugin/src/com/google/inject/struts2/GuiceObjectFactory.java
new file mode 100644
index 0000000..b8f7288
--- /dev/null
+++ b/struts2/plugin/src/com/google/inject/struts2/GuiceObjectFactory.java
@@ -0,0 +1,73 @@
+/**
+ * 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.struts2;
+
+import com.google.inject.Container;
+import com.google.inject.ContainerBuilder;
+import com.google.inject.ContainerCreationException;
+import com.google.inject.Module;
+import com.google.inject.servlet.ServletModule;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.inject.Inject;
+
+import java.util.Map;
+
+public class GuiceObjectFactory extends ObjectFactory {
+
+ Container container;
+
+ @Inject
+ public GuiceObjectFactory(
+ @Inject("guice.module") String moduleName,
+ @Inject("struts.devMode") String developmentMode) {
+ ContainerBuilder builder = new ContainerBuilder();
+
+ // Configure default servlet bindings.
+ builder.install(new ServletModule());
+
+ try {
+ // Instantiate user's module and install it.
+ @SuppressWarnings({"unchecked"})
+ Class<? extends Module> moduleClass =
+ (Class<? extends Module>) Class.forName(moduleName);
+
+ Module module = moduleClass.newInstance();
+
+ module.configure(builder);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ System.err.println("devMode: " + developmentMode);
+
+ try {
+ container = builder.create(false);
+ } catch (ContainerCreationException e) {
+ System.err.println(e.getMessage());
+ System.exit(1);
+ }
+ }
+
+ public Object buildBean(String clazz, Map map) throws Exception {
+ return container.getCreator(Class.forName(clazz)).get();
+ }
+
+ public boolean isNoArgConstructorRequired() {
+ return false;
+ }
+}
diff --git a/struts2/plugin/src/struts-plugin.xml b/struts2/plugin/src/struts-plugin.xml
new file mode 100644
index 0000000..8fcef1c
--- /dev/null
+++ b/struts2/plugin/src/struts-plugin.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!DOCTYPE struts PUBLIC
+ "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
+ "http://struts.apache.org/dtds/struts-2.0.dtd">
+
+<struts>
+
+ <bean type="com.opensymphony.xwork2.ObjectFactory"
+ name="guice"
+ class="com.google.inject.struts2.GuiceObjectFactory"/>
+
+ <!-- Make the Guice object factory the automatic default -->
+ <constant name="struts.objectFactory" value="guice" />
+
+</struts>
diff --git a/struts2/struts2.iml b/struts2/struts2.iml
new file mode 100644
index 0000000..bc98934
--- /dev/null
+++ b/struts2/struts2.iml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4" relativePaths="true" type="JAVA_MODULE">
+ <component name="ModuleRootManager" />
+ <component name="NewModuleRootManager" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/classes" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/example/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/plugin/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/commons-logging-1.0.4.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/xwork-2.0.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/struts-2.0.5-lib.zip!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/freemarker-2.3.8.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/struts2-core-2.0.5.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/ognl-2.6.9.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module" module-name="guice" />
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/jetty-util-6.1.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/jetty-6.1.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/servlet-api-2.5.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/core-3.1.1.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/jsp-api-2.1.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/jsp-2.1.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/ant-1.6.5.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/struts2-api-2.0.5.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntryProperties />
+ </component>
+</module>
+
diff --git a/test/com/google/inject/AllTests.java b/test/com/google/inject/AllTests.java
index 1071145..4d4b4c1 100644
--- a/test/com/google/inject/AllTests.java
+++ b/test/com/google/inject/AllTests.java
@@ -16,14 +16,12 @@
package com.google.inject;
-import com.google.inject.intercept.ProxyFactoryTest;
-import com.google.inject.intercept.QueryTest;
-import com.google.inject.intercept.IntegrationTest;
+import com.google.inject.query.QueryTest;
+import com.google.inject.servlet.ServletTest;
import com.google.inject.util.FinalizableReferenceQueueTest;
import com.google.inject.util.ReferenceCacheTest;
import com.google.inject.util.ReferenceMapTest;
import com.google.inject.util.ReferenceMapTestSuite;
-import com.google.inject.servlet.ServletTest;
import junit.framework.Test;
import junit.framework.TestSuite;
diff --git a/test/com/google/inject/intercept/IntegrationTest.java b/test/com/google/inject/IntegrationTest.java
similarity index 76%
rename from test/com/google/inject/intercept/IntegrationTest.java
rename to test/com/google/inject/IntegrationTest.java
index 4f24e87..f1aaa46 100644
--- a/test/com/google/inject/intercept/IntegrationTest.java
+++ b/test/com/google/inject/IntegrationTest.java
@@ -14,13 +14,9 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject;
-import static com.google.inject.intercept.Queries.*;
-import com.google.inject.ContainerBuilder;
-import com.google.inject.Container;
-import com.google.inject.ContainerCreationException;
-import com.google.inject.Key;
+import static com.google.inject.query.Queries.any;
import junit.framework.TestCase;
@@ -34,12 +30,10 @@
public void testIntegration() throws ContainerCreationException {
CountingInterceptor counter = new CountingInterceptor();
- ProxyFactoryBuilder proxyFactoryBuilder = new ProxyFactoryBuilder();
- proxyFactoryBuilder.intercept(any(), any(), counter);
- ProxyFactory proxyFactory = proxyFactoryBuilder.create();
- ContainerBuilder containerBuilder = new ContainerBuilder(proxyFactory);
+ ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.bind(Foo.class);
+ containerBuilder.intercept(any(), any(), counter);
Container container = containerBuilder.create(false);
Foo foo = container.getFactory(Key.get(Foo.class)).get();
diff --git a/test/com/google/inject/intercept/ProxyFactoryTest.java b/test/com/google/inject/ProxyFactoryTest.java
similarity index 97%
rename from test/com/google/inject/intercept/ProxyFactoryTest.java
rename to test/com/google/inject/ProxyFactoryTest.java
index ca64b01..b2d66ec 100644
--- a/test/com/google/inject/intercept/ProxyFactoryTest.java
+++ b/test/com/google/inject/ProxyFactoryTest.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject;
-import com.google.inject.spi.ConstructionProxy;
-import static com.google.inject.intercept.Queries.*;
+import com.google.inject.ConstructionProxy;
+import static com.google.inject.query.Queries.*;
import com.google.inject.Factory;
import junit.framework.TestCase;
diff --git a/test/com/google/inject/intercept/QueryTest.java b/test/com/google/inject/query/QueryTest.java
similarity index 96%
rename from test/com/google/inject/intercept/QueryTest.java
rename to test/com/google/inject/query/QueryTest.java
index 2a91d97..3b90e33 100644
--- a/test/com/google/inject/intercept/QueryTest.java
+++ b/test/com/google/inject/query/QueryTest.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.google.inject.intercept;
+package com.google.inject.query;
-import static com.google.inject.intercept.Queries.*;
+import static com.google.inject.query.Queries.*;
import junit.framework.TestCase;