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"));
}