You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2013/05/01 23:26:07 UTC
svn commit: r1478196 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/
systests/jaxrs/src/test/java/org/apac...
Author: sergeyb
Date: Wed May 1 21:26:07 2013
New Revision: 1478196
URL: http://svn.apache.org/r1478196
Log:
[CXF-4988] Support for instantiating providers with non default constructors, more updates
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java?rev=1478196&r1=1478195&r2=1478196&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java Wed May 1 21:26:07 2013
@@ -171,7 +171,6 @@ public class JAXRSServerFactoryBean exte
ServerProviderFactory factory = setupFactory(ep);
ep.put(Application.class.getName(), appProvider);
- factory.setApplicationProvider(appProvider);
factory.setRequestPreprocessor(
new RequestPreprocessor(languageMappings, extensionMappings));
ep.put(Bus.class.getName(), getBus());
@@ -216,6 +215,7 @@ public class JAXRSServerFactoryBean exte
protected ServerProviderFactory setupFactory(Endpoint ep) {
ServerProviderFactory factory = ServerProviderFactory.createInstance(getBus());
setBeanInfo(factory);
+ factory.setApplicationProvider(appProvider);
super.setupFactory(factory, ep);
return factory;
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java?rev=1478196&r1=1478195&r2=1478196&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java Wed May 1 21:26:07 2013
@@ -20,6 +20,7 @@
package org.apache.cxf.jaxrs.provider;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -28,9 +29,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
@@ -56,11 +59,13 @@ import org.apache.cxf.jaxrs.ext.ContextP
import org.apache.cxf.jaxrs.impl.HttpHeadersImpl;
import org.apache.cxf.jaxrs.impl.ReaderInterceptorMBR;
import org.apache.cxf.jaxrs.impl.WriterInterceptorMBW;
+import org.apache.cxf.jaxrs.impl.tl.ThreadLocalProxy;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.ProviderInfo;
import org.apache.cxf.jaxrs.utils.AnnotationUtils;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
@@ -457,42 +462,56 @@ public abstract class ProviderFactory {
}
//CHECKSTYLE:OFF
+ @SuppressWarnings("unchecked")
protected void setProviders(Object... providers) {
for (Object o : providers) {
if (o == null) {
continue;
}
- Class<?> oClass = ClassHelper.getRealClass(o);
- if (MessageBodyReader.class.isAssignableFrom(oClass)) {
- messageReaders.add(new ProviderInfo<MessageBodyReader<?>>((MessageBodyReader<?>)o, bus));
+ ProviderInfo<? extends Object> provider = null;
+ Class<?> providerCls = null;
+ Object realObject = null;
+ if (o instanceof ProviderInfo) {
+ provider = (ProviderInfo<? extends Object>)o;
+ providerCls = provider.getProvider().getClass();
+ realObject = provider;
+ } else {
+ providerCls = ClassHelper.getRealClass(o);
+ provider = new ProviderInfo<Object>(o, getBus());
+ realObject = o;
+ }
+
+
+ if (MessageBodyReader.class.isAssignableFrom(providerCls)) {
+ messageReaders.add((ProviderInfo<MessageBodyReader<?>>)provider);
}
- if (MessageBodyWriter.class.isAssignableFrom(oClass)) {
- messageWriters.add(new ProviderInfo<MessageBodyWriter<?>>((MessageBodyWriter<?>)o, bus));
+ if (MessageBodyWriter.class.isAssignableFrom(providerCls)) {
+ messageWriters.add((ProviderInfo<MessageBodyWriter<?>>)provider);
}
- if (ContextResolver.class.isAssignableFrom(oClass)) {
- contextResolvers.add(new ProviderInfo<ContextResolver<?>>((ContextResolver<?>)o, bus));
+ if (ContextResolver.class.isAssignableFrom(providerCls)) {
+ contextResolvers.add((ProviderInfo<ContextResolver<?>>)provider);
}
- if (ContextProvider.class.isAssignableFrom(oClass)) {
- contextProviders.add(new ProviderInfo<ContextProvider<?>>((ContextProvider<?>)o, bus));
+ if (ContextProvider.class.isAssignableFrom(providerCls)) {
+ contextProviders.add((ProviderInfo<ContextProvider<?>>)provider);
}
- if (ReaderInterceptor.class.isAssignableFrom(oClass)) {
- readerInterceptors.add(
- new ProviderInfo<ReaderInterceptor>((ReaderInterceptor)o, bus));
+ if (ReaderInterceptor.class.isAssignableFrom(providerCls)) {
+ readerInterceptors.add((ProviderInfo<ReaderInterceptor>)provider);
}
- if (WriterInterceptor.class.isAssignableFrom(oClass)) {
- writerInterceptors.add(
- new ProviderInfo<WriterInterceptor>((WriterInterceptor)o, bus));
+ if (WriterInterceptor.class.isAssignableFrom(providerCls)) {
+ writerInterceptors.add((ProviderInfo<WriterInterceptor>)provider);
}
- if (ParamConverterProvider.class.isAssignableFrom(oClass)) {
- newParamConverter = (ParamConverterProvider)o;
+ if (ParamConverterProvider.class.isAssignableFrom(providerCls)) {
+ //TODO: review the possibility of ParamConverterProvider needing to have Contexts injected
+ Object converter = realObject == provider ? provider.getProvider() : realObject;
+ newParamConverter = (ParamConverterProvider)converter;
}
}
sortReaders();
@@ -948,5 +967,26 @@ public abstract class ProviderFactory {
}
}
-
+ protected ProviderInfo<Object> createProviderFromConstructor(Constructor<?> c,
+ Map<Class<?>, Object> values) {
+ Object[] cArgs = ResourceUtils.createConstructorArguments(c, null, false, values);
+ Object instance = null;
+ try {
+ instance = c.newInstance(cArgs);
+ } catch (Throwable ex) {
+ throw new RuntimeException("Resource or provider class " + c.getDeclaringClass().getName()
+ + " can not be instantiated");
+ }
+ Map<Class<?>, ThreadLocalProxy<?>> proxies =
+ new HashMap<Class<?>, ThreadLocalProxy<?>>();
+ Class<?>[] paramTypes = c.getParameterTypes();
+ for (int i = 0; i < paramTypes.length; i++) {
+ if (cArgs[i] instanceof ThreadLocalProxy) {
+ @SuppressWarnings("unchecked")
+ ThreadLocalProxy<Object> proxy = (ThreadLocalProxy<Object>)cArgs[i];
+ proxies.put(paramTypes[i], proxy);
+ }
+ }
+ return new ProviderInfo<Object>(instance, proxies, getBus());
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java?rev=1478196&r1=1478195&r2=1478196&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java Wed May 1 21:26:07 2013
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.jaxrs.provider;
+import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -49,6 +50,7 @@ import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.common.util.ClassHelper;
import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.impl.RequestPreprocessor;
import org.apache.cxf.jaxrs.impl.ResourceInfoImpl;
@@ -219,9 +221,9 @@ public final class ServerProviderFactory
}
//CHECKSTYLE:OFF
+ @SuppressWarnings("unchecked")
@Override
protected void setProviders(Object... providers) {
- super.setProviders(providers);
List<ProviderInfo<ContainerRequestFilter>> postMatchRequestFilters =
new LinkedList<ProviderInfo<ContainerRequestFilter>>();
List<ProviderInfo<ContainerResponseFilter>> postMatchResponseFilters =
@@ -231,25 +233,40 @@ public final class ServerProviderFactory
if (o == null) {
continue;
}
- Class<?> oClass = ClassHelper.getRealClass(o);
+ ProviderInfo<? extends Object> provider = null;
+ Class<?> providerCls = null;
+ Object realObject = null;
+ if (o instanceof Constructor) {
+ Map<Class<?>, Object> values = CastUtils.cast((application == null ? null
+ : Collections.singletonMap(Application.class, application.getProvider())));
+ provider = createProviderFromConstructor((Constructor<?>)o, values);
+ providerCls = provider.getProvider().getClass();
+ realObject = provider;
+ } else {
+ providerCls = ClassHelper.getRealClass(o);
+ provider = new ProviderInfo<Object>(o, getBus());
+ realObject = o;
+ }
+ super.setProviders(realObject);
- if (ContainerRequestFilter.class.isAssignableFrom(oClass)) {
- addContainerRequestFilter(postMatchRequestFilters,
- new ProviderInfo<ContainerRequestFilter>((ContainerRequestFilter)o, getBus()));
+ if (ContainerRequestFilter.class.isAssignableFrom(providerCls)) {
+ addContainerRequestFilter(postMatchRequestFilters,
+ (ProviderInfo<ContainerRequestFilter>)provider);
}
- if (ContainerResponseFilter.class.isAssignableFrom(oClass)) {
- postMatchResponseFilters.add(
- new ProviderInfo<ContainerResponseFilter>((ContainerResponseFilter)o, getBus()));
+ if (ContainerResponseFilter.class.isAssignableFrom(providerCls)) {
+ postMatchResponseFilters.add((ProviderInfo<ContainerResponseFilter>)provider);
}
- if (DynamicFeature.class.isAssignableFrom(oClass)) {
- dynamicFeatures.add((DynamicFeature)o);
+ if (DynamicFeature.class.isAssignableFrom(providerCls)) {
+ //TODO: review the possibility of DynamicFeatures needing to have Contexts injected
+ Object feature = realObject == provider ? provider.getProvider() : realObject;
+ dynamicFeatures.add((DynamicFeature)feature);
}
- if (ExceptionMapper.class.isAssignableFrom(oClass)) {
- exceptionMappers.add(new ProviderInfo<ExceptionMapper<?>>((ExceptionMapper<?>)o, getBus()));
+ if (ExceptionMapper.class.isAssignableFrom(providerCls)) {
+ exceptionMappers.add((ProviderInfo<ExceptionMapper<?>>)provider);
}
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java?rev=1478196&r1=1478195&r2=1478196&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java Wed May 1 21:26:07 2013
@@ -614,7 +614,16 @@ public final class ResourceUtils {
return op;
}
- public static Object[] createConstructorArguments(Constructor<?> c, Message m, boolean perRequest) {
+ public static Object[] createConstructorArguments(Constructor<?> c,
+ Message m,
+ boolean perRequest) {
+ return createConstructorArguments(c, m, perRequest, null);
+ }
+
+ public static Object[] createConstructorArguments(Constructor<?> c,
+ Message m,
+ boolean perRequest,
+ Map<Class<?>, Object> contextValues) {
Class<?>[] params = c.getParameterTypes();
Annotation[][] anns = c.getParameterAnnotations();
Type[] genericTypes = c.getGenericParameterTypes();
@@ -624,10 +633,15 @@ public final class ResourceUtils {
Object[] values = new Object[params.length];
for (int i = 0; i < params.length; i++) {
if (AnnotationUtils.getAnnotation(anns[i], Context.class) != null) {
- if (perRequest) {
- values[i] = JAXRSUtils.createContextValue(m, genericTypes[i], params[i]);
+ Object contextValue = contextValues != null ? contextValues.get(params[i]) : null;
+ if (contextValue == null) {
+ if (perRequest) {
+ values[i] = JAXRSUtils.createContextValue(m, genericTypes[i], params[i]);
+ } else {
+ values[i] = InjectionUtils.createThreadLocalProxy(params[i]);
+ }
} else {
- values[i] = InjectionUtils.createThreadLocalProxy(params[i]);
+ values[i] = contextValue;
}
} else {
// this branch won't execute for singletons given that the found constructor
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java?rev=1478196&r1=1478195&r2=1478196&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java Wed May 1 21:26:07 2013
@@ -85,13 +85,18 @@ public class BookApplication extends App
public static class BookRequestFilter implements ContainerRequestFilter {
private UriInfo ui;
+ private Application ap;
- public BookRequestFilter(@Context UriInfo ui) {
+ public BookRequestFilter(@Context UriInfo ui, @Context Application ap) {
this.ui = ui;
+ this.ap = ap;
}
@Override
public void filter(ContainerRequestContext context) throws IOException {
+ if (ap == null) {
+ throw new RuntimeException();
+ }
if (ui.getRequestUri().toString().endsWith("/application11/thebooks/bookstore2/bookheaders")) {
context.getHeaders().put("BOOK", Arrays.asList("1", "2", "3"));
}