Author: christian.bauer(a)jboss.com
Date: 2009-03-19 21:58:50 -0400 (Thu, 19 Mar 2009)
New Revision: 10193
Added:
trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyContextInjectionInterceptor.java
Modified:
trunk/build/root.pom.xml
trunk/doc/Seam_Reference_Guide/en-US/Webservices.xml
trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java
trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java
trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java
Log:
JBSEAM-3383, field injection of JAX RS @Context and upgrade to RESTEasy 1.1-RC1
Modified: trunk/build/root.pom.xml
===================================================================
--- trunk/build/root.pom.xml 2009-03-19 12:34:02 UTC (rev 10192)
+++ trunk/build/root.pom.xml 2009-03-20 01:58:50 UTC (rev 10193)
@@ -306,7 +306,7 @@
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
- <version>1.0.1.GA</version>
+ <version>1.1-RC1</version>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
@@ -336,6 +336,14 @@
<groupId>org.scannotation</groupId>
<artifactId>scannotation</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </exclusion>
</exclusions>
</dependency>
Modified: trunk/doc/Seam_Reference_Guide/en-US/Webservices.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Webservices.xml 2009-03-19 12:34:02 UTC (rev
10192)
+++ trunk/doc/Seam_Reference_Guide/en-US/Webservices.xml 2009-03-20 01:58:50 UTC (rev
10193)
@@ -480,7 +480,7 @@
Custom or checked exceptions are handled the same:
</para>
- <programlisting role="XML"><![CDATA[<exception
class="my.CustomException">
+ <programlisting role="XML"><![CDATA[<exception
class="my.CustomException" log="false">
<http-error error-code="503">
<message>The service is currently not available:
#{org.jboss.seam.handledException.message}</message>
</http-error>
Modified: trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java
===================================================================
--- trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java 2009-03-19 12:34:02
UTC (rev 10192)
+++ trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java 2009-03-20 01:58:50
UTC (rev 10193)
@@ -36,7 +36,7 @@
@Create
public void onStartup()
{
- log.info("deploying Resteasy providers and resources");
+ log.info("deploying RESTEasy providers and resources");
Collection<Class<?>> annotatedProviderClasses = null;
Collection<Class<?>> annotatedResourceClasses = null;
Added:
trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyContextInjectionInterceptor.java
===================================================================
--- trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyContextInjectionInterceptor.java
(rev 0)
+++
trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyContextInjectionInterceptor.java 2009-03-20
01:58:50 UTC (rev 10193)
@@ -0,0 +1,46 @@
+package org.jboss.seam.resteasy;
+
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.core.BijectionInterceptor;
+import org.jboss.seam.intercept.AbstractInterceptor;
+import org.jboss.seam.intercept.InvocationContext;
+import org.jboss.seam.Component;
+import org.jboss.resteasy.spi.PropertyInjector;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.HttpResponse;
+
+/**
+ * Runs after Seam injection and provides JAX RS @Context handling, required for
+ * field injection on the actual bean (not proxy) instance.
+ *
+ * @author Christian Bauer
+ */
+@Interceptor(stateless=true)
+public class ResteasyContextInjectionInterceptor extends AbstractInterceptor
+{
+
+ public static final String RE_HTTP_REQUEST_VAR =
"org.jboss.resteasy.spi.HttpRequest";
+ public static final String RE_HTTP_RESPONSE_VAR =
"org.jboss.resteasy.spi.HttpResponse";
+
+ private final PropertyInjector propertyInjector;
+
+ public ResteasyContextInjectionInterceptor(PropertyInjector propertyInjector)
+ {
+ this.propertyInjector = propertyInjector;
+ }
+
+ public Object aroundInvoke(InvocationContext ic) throws Exception
+ {
+ HttpRequest request = (HttpRequest) Component.getInstance(RE_HTTP_REQUEST_VAR);
+ HttpResponse response =
(HttpResponse)Component.getInstance(RE_HTTP_RESPONSE_VAR);
+
+ propertyInjector.inject(request, response, ic.getTarget());
+
+ return ic.proceed();
+ }
+
+ public boolean isInterceptorEnabled()
+ {
+ return true;
+ }
+}
Modified: trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java
===================================================================
--- trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java 2009-03-19 12:34:02
UTC (rev 10192)
+++ trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java 2009-03-20 01:58:50
UTC (rev 10193)
@@ -2,6 +2,7 @@
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
@@ -12,15 +13,12 @@
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.log.Log;
import org.jboss.resteasy.core.AsynchronousDispatcher;
+import org.jboss.resteasy.core.PropertyInjectorImpl;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory;
import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;
import org.jboss.resteasy.spi.*;
-import org.jboss.resteasy.util.Types;
-import java.lang.reflect.Type;
-import java.lang.reflect.ParameterizedType;
-
/**
* An extended version of the RESTEasy dispatcher, configured on Seam application
* startup with a custom JAX RS <tt>Application</tt> instance. Registers
custom resource
@@ -78,16 +76,20 @@
boolean isStringConverter = false;
for (Class componentIface : seamComponent.getBusinessInterfaces())
{
- if (StringConverter.class.isAssignableFrom(componentIface)) {
+ if (StringConverter.class.isAssignableFrom(componentIface))
+ {
isStringConverter = true;
break;
}
}
- if (isStringConverter) {
+ if (isStringConverter)
+ {
log.error("can't register Seam component as RESTEasy
StringConverter, see:
https://jira.jboss.org/jira/browse/JBSEAM-4020");
//log.debug("registering Seam component as custom RESTEasy
string converter provider: " + seamComponent.getName());
//providerFactory.addStringConverter((StringConverter)providerInstance);
- } else {
+ }
+ else
+ {
providerFactory.registerProviderInstance(providerInstance);
}
}
@@ -95,10 +97,13 @@
else
{
// Just plain RESTEasy, no Seam component lookup or lifecycle
- if (StringConverter.class.isAssignableFrom(providerClass)) {
+ if (StringConverter.class.isAssignableFrom(providerClass))
+ {
log.debug("registering as custom RESTEasy string converter
provider class: " + providerClass);
providerFactory.addStringConverter(providerClass);
- } else {
+ }
+ else
+ {
providerFactory.registerProvider(providerClass);
}
}
@@ -108,16 +113,16 @@
Registry registry = getDispatcher().getRegistry();
for (final Class resourceClass : application.getClasses())
{
+ log.debug("registering JAX RS resource class: " + resourceClass);
final Component seamComponent =
application.getResourceClassComponent(resourceClass);
if (seamComponent != null)
{
// Seam component lookup when call is dispatched to resource
+ log.debug("registering as Seam component resource factory: " +
resourceClass);
registry.addResourceFactory(
new ResourceFactory()
{
- private PropertyInjector propertyInjector;
-
public Class<?> getScannableClass()
{
return resourceClass;
@@ -125,14 +130,26 @@
public void registered(InjectorFactory factory)
{
- this.propertyInjector =
factory.createPropertyInjector(getScannableClass());
+ // Wrap the Resteasy PropertyInjectorImpl in a Seam
interceptor (for @Context injection)
+ seamComponent.addInterceptor(
+ new ResteasyContextInjectionInterceptor(
+ new
PropertyInjectorImpl(getScannableClass(), dispatcher.getProviderFactory())
+ )
+ );
+
+ // NOTE: Adding an interceptor to Component at this stage
means that the interceptor is
+ // always executed last in the chain. The sorting of
interceptors of a Component occurs
+ // only when the Component metadata is instantiated. This
is OK in this case, as the
+ // JAX RS @Context injection can occur last after all
other interceptors executed.
+
}
public Object createResource(HttpRequest request,
HttpResponse response, InjectorFactory factory)
{
- Object target =
Component.getInstance(seamComponent.getName());
- propertyInjector.inject(request, response, target);
- return target;
+ // Push this onto event context so we have it available
in ResteasyContextInjectionInterceptor
+
Contexts.getEventContext().set(ResteasyContextInjectionInterceptor.RE_HTTP_REQUEST_VAR,
request);
+
Contexts.getEventContext().set(ResteasyContextInjectionInterceptor.RE_HTTP_RESPONSE_VAR,
response);
+ return Component.getInstance(seamComponent.getName());
}
public void requestFinished(HttpRequest request, HttpResponse
response, Object resource)
Modified: trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java
===================================================================
--- trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java 2009-03-19
12:34:02 UTC (rev 10192)
+++ trunk/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java 2009-03-20
01:58:50 UTC (rev 10193)
@@ -98,7 +98,7 @@
Application appConfig =
(Application)Component.getInstance(Application.class);
if (appConfig.isStripSeamResourcePath()) {
- log.debug("removing SeamResourceServlet url-pattern and
dispatcher prefix from request path");
+ log.trace("removing SeamResourceServlet url-pattern and
dispatcher prefix from request path");
path =
path.substring(path.indexOf(getResourcePath())+getResourcePath().length());
}