com.sun.jersey.server.impl.application.WebApplicationImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.jersey.server.impl.application;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;
import com.sun.jersey.api.NotFoundException;
import com.sun.jersey.api.container.ContainerException;
import com.sun.jersey.api.container.MappableContainerException;
import com.sun.jersey.api.container.filter.UriConnegFilter;
import com.sun.jersey.api.core.ExtendedUriInfo;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.api.core.InjectParam;
import com.sun.jersey.api.core.ParentRef;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.api.core.ResourceConfigurator;
import com.sun.jersey.api.core.ResourceContext;
import com.sun.jersey.api.model.AbstractResource;
import com.sun.jersey.api.model.AbstractResourceMethod;
import com.sun.jersey.api.model.AbstractResourceModelContext;
import com.sun.jersey.api.model.AbstractResourceModelListener;
import com.sun.jersey.api.model.AbstractSubResourceLocator;
import com.sun.jersey.api.model.ResourceModelIssue;
import com.sun.jersey.core.header.MediaTypes;
import com.sun.jersey.core.reflection.ReflectionHelper;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.core.spi.component.ProviderFactory;
import com.sun.jersey.core.spi.component.ProviderServices;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProcessor;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProcessorFactory;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProcessorFactoryInitializer;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;
import com.sun.jersey.core.spi.component.ioc.IoCProviderFactory;
import com.sun.jersey.core.spi.factory.ContextResolverFactory;
import com.sun.jersey.core.spi.factory.MessageBodyFactory;
import com.sun.jersey.core.util.FeaturesAndProperties;
import com.sun.jersey.impl.ImplMessages;
import com.sun.jersey.server.impl.BuildId;
import com.sun.jersey.server.impl.ThreadLocalHttpContext;
import com.sun.jersey.server.impl.component.IoCResourceFactory;
import com.sun.jersey.server.impl.component.ResourceFactory;
import com.sun.jersey.server.impl.container.filter.FilterFactory;
import com.sun.jersey.server.impl.inject.ServerInjectableProviderContext;
import com.sun.jersey.server.impl.inject.ServerInjectableProviderFactory;
import com.sun.jersey.server.impl.model.ResourceUriRules;
import com.sun.jersey.server.impl.model.RulesMap;
import com.sun.jersey.server.impl.model.parameter.CookieParamInjectableProvider;
import com.sun.jersey.server.impl.model.parameter.FormParamInjectableProvider;
import com.sun.jersey.server.impl.model.parameter.HeaderParamInjectableProvider;
import com.sun.jersey.server.impl.model.parameter.HttpContextInjectableProvider;
import com.sun.jersey.server.impl.model.parameter.MatrixParamInjectableProvider;
import com.sun.jersey.server.impl.model.parameter.PathParamInjectableProvider;
import com.sun.jersey.server.impl.model.parameter.QueryParamInjectableProvider;
import com.sun.jersey.server.impl.model.parameter.multivalued.MultivaluedParameterExtractorFactory;
import com.sun.jersey.server.impl.model.parameter.multivalued.MultivaluedParameterExtractorProvider;
import com.sun.jersey.server.impl.model.parameter.multivalued.StringReaderFactory;
import com.sun.jersey.server.impl.modelapi.annotation.IntrospectionModeller;
import com.sun.jersey.server.impl.modelapi.validation.BasicValidator;
import com.sun.jersey.server.impl.monitoring.MonitoringProviderFactory;
import com.sun.jersey.server.impl.resource.PerRequestFactory;
import com.sun.jersey.server.impl.template.TemplateFactory;
import com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule;
import com.sun.jersey.server.impl.wadl.WadlApplicationContextInjectionProxy;
import com.sun.jersey.server.impl.wadl.WadlFactory;
import com.sun.jersey.server.spi.component.ResourceComponentInjector;
import com.sun.jersey.server.spi.component.ResourceComponentProvider;
import com.sun.jersey.server.wadl.WadlApplicationContext;
import com.sun.jersey.spi.MessageBodyWorkers;
import com.sun.jersey.spi.StringReaderWorkers;
import com.sun.jersey.spi.container.*;
import com.sun.jersey.spi.inject.Errors;
import com.sun.jersey.spi.inject.Inject;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
import com.sun.jersey.spi.inject.InjectableProviderContext;
import com.sun.jersey.spi.inject.ServerSide;
import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
import com.sun.jersey.spi.monitoring.DispatchingListener;
import com.sun.jersey.spi.monitoring.RequestListener;
import com.sun.jersey.spi.monitoring.ResponseListener;
import com.sun.jersey.spi.service.ServiceFinder;
import com.sun.jersey.spi.template.TemplateContext;
import com.sun.jersey.spi.uri.rules.UriRule;
import com.sun.jersey.spi.uri.rules.UriRules;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
/**
* A Web application that contains a set of resources, each referenced by
* an absolute URI template.
*
* @author [email protected]
*/
public final class WebApplicationImpl implements WebApplication {
private static final Logger LOGGER = Logger.getLogger(WebApplicationImpl.class.getName());
private final Map abstractResourceMap =
new HashMap();
private final ConcurrentMap> rulesMap =
new ConcurrentHashMap>();
private final ConcurrentMap providerMap =
new ConcurrentHashMap();
private static class ClassAnnotationKey {
private final Class c;
private final Set as;
public ClassAnnotationKey(Class c, Annotation[] as) {
this.c = c;
this.as = new HashSet(Arrays.asList(as));
}
@Override
public int hashCode() {
int hash = 5;
hash = 67 * hash + (this.c != null ? this.c.hashCode() : 0);
hash = 67 * hash + (this.as != null ? this.as.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ClassAnnotationKey other = (ClassAnnotationKey) obj;
if (this.c != other.c && (this.c == null || !this.c.equals(other.c))) {
return false;
}
if (this.as != other.as && (this.as == null || !this.as.equals(other.as))) {
return false;
}
return true;
}
}
private final ConcurrentMap providerWithAnnotationKeyMap =
new ConcurrentHashMap();
private final ThreadLocalHttpContext context;
private final CloseableServiceFactory closeableFactory;
private boolean initiated;
private ResourceConfig resourceConfig;
private RootResourceClassesRule rootsRule;
private ServerInjectableProviderFactory injectableFactory;
private ProviderFactory cpFactory;
private ResourceFactory rcpFactory;
private IoCComponentProviderFactory provider;
private List providerFactories;
private Providers providers;
private MessageBodyFactory bodyFactory;
private StringReaderFactory stringReaderFactory;
private TemplateContext templateContext;
private ExceptionMapperFactory exceptionFactory;
private ResourceMethodDispatchProvider dispatcherFactory;
private ResourceContext resourceContext;
private Set abstractRootResources;
private Map explicitAbstractRootResources;
private final AbstractResourceModelContext armContext = new AbstractResourceModelContext() {
@Override
public Set getAbstractRootResources() {
return abstractRootResources;
}
};
private FilterFactory filterFactory;
private WadlFactory wadlFactory;
private boolean isTraceEnabled;
private RequestListener requestListener;
private DispatchingListenerProxy dispatchingListener;
private ResponseListener responseListener;
public WebApplicationImpl() {
this.context = new ThreadLocalHttpContext();
InvocationHandler requestHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(context.getRequest(), args);
} catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
};
InvocationHandler uriInfoHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(context.getUriInfo(), args);
} catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
};
// Create injectable provider factory
this.injectableFactory = new ServerInjectableProviderFactory();
injectableFactory.add(new ContextInjectableProvider(
InjectableProviderContext.class, injectableFactory));
injectableFactory.add(new ContextInjectableProvider(
ServerInjectableProviderContext.class, injectableFactory));
// Add proxied injectables
final Map m = new HashMap();
m.put(HttpContext.class, context);
m.put(HttpHeaders.class, createProxy(HttpHeaders.class, requestHandler));
m.put(UriInfo.class, createProxy(UriInfo.class, uriInfoHandler));
m.put(ExtendedUriInfo.class, createProxy(ExtendedUriInfo.class, uriInfoHandler));
m.put(Request.class, createProxy(Request.class, requestHandler));
m.put(SecurityContext.class, createProxy(SecurityContext.class, requestHandler));
injectableFactory.add(new InjectableProvider() {
@Override
public ComponentScope getScope() {
return ComponentScope.Singleton;
}
@Override
public Injectable getInjectable(ComponentContext ic, Context a, Type c) {
final Object o = m.get(c);
if (o != null) {
return new Injectable() {
@Override
public Object getValue() {
return o;
}
};
} else
return null;
}
});
injectableFactory.add(new InjectableProvider() {
@Override
public ComponentScope getScope() {
return ComponentScope.Singleton;
}
@Override
public Injectable getInjectable(ComponentContext ic, Context a, Type c) {
if (c instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)c;
if (pt.getRawType() == Injectable.class) {
if (pt.getActualTypeArguments().length == 1) {
final Injectable> i = injectableFactory.getInjectable(
a.annotationType(),
ic,
a,
pt.getActualTypeArguments()[0],
ComponentScope.PERREQUEST_UNDEFINED_SINGLETON);
if (i == null)
return null;
return new Injectable() {
@Override
public Injectable getValue() {
return i;
}
};
}
}
}
return null;
}
});
injectableFactory.add(new InjectableProvider() {
@Override
public ComponentScope getScope() {
return ComponentScope.Singleton;
}
@Override
public Injectable getInjectable(ComponentContext ic, Inject a, Type c) {
if (c instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)c;
if (pt.getRawType() == Injectable.class) {
if (pt.getActualTypeArguments().length == 1) {
final Injectable> i = injectableFactory.getInjectable(
a.annotationType(),
ic,
a,
pt.getActualTypeArguments()[0],
ComponentScope.PERREQUEST_UNDEFINED_SINGLETON);
if (i == null)
return null;
return new Injectable() {
@Override
public Injectable getValue() {
return i;
}
};
}
}
}
return null;
}
});
injectableFactory.add(new InjectableProvider() {
@Override
public ComponentScope getScope() {
return ComponentScope.Singleton;
}
@Override
public Injectable getInjectable(ComponentContext ic, InjectParam a, Type c) {
if (c instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)c;
if (pt.getRawType() == Injectable.class) {
if (pt.getActualTypeArguments().length == 1) {
final Injectable> i = injectableFactory.getInjectable(
a.annotationType(),
ic,
a,
pt.getActualTypeArguments()[0],
ComponentScope.PERREQUEST_UNDEFINED_SINGLETON);
if (i == null)
return null;
return new Injectable() {
@Override
public Injectable getValue() {
return i;
}
};
}
}
}
return null;
}
});
closeableFactory = new CloseableServiceFactory(context);
injectableFactory.add(closeableFactory);
}
private class ComponentProcessorImpl implements IoCComponentProcessor {
private final ResourceComponentInjector rci;
ComponentProcessorImpl(ResourceComponentInjector rci) {
this.rci = rci;
}
@Override
public void preConstruct() {
}
@Override
public void postConstruct(Object o) {
rci.inject(context.get(), o);
}
}
private static final IoCComponentProcessor NULL_COMPONENT_PROCESSOR = new IoCComponentProcessor() {
@Override
public void preConstruct() {
}
@Override
public void postConstruct(Object o) {
}
};
private class ComponentProcessorFactoryImpl implements IoCComponentProcessorFactory {
private final ConcurrentMap componentProcessorMap =
new ConcurrentHashMap();
@Override
public ComponentScope getScope(Class c) {
return rcpFactory.getScope(c);
}
@Override
public IoCComponentProcessor get(final Class c, final ComponentScope scope) {
IoCComponentProcessor cp = componentProcessorMap.get(c);
if (cp != null) {
return (cp == NULL_COMPONENT_PROCESSOR) ? null : cp;
}
synchronized (abstractResourceMap) {
cp = componentProcessorMap.get(c);
if (cp != null) {
return (cp == NULL_COMPONENT_PROCESSOR) ? null : cp;
}
final ResourceComponentInjector rci = Errors.processWithErrors(new Errors.Closure() {
@Override
public ResourceComponentInjector f() {
return new ResourceComponentInjector(
injectableFactory, scope, getAbstractResource(c));
}
});
if (rci.hasInjectableArtifacts()) {
cp = new ComponentProcessorImpl(rci);
componentProcessorMap.put(c, cp);
} else {
cp = null;
componentProcessorMap.put(c, NULL_COMPONENT_PROCESSOR);
}
}
return cp;
}
}
@Override
public FeaturesAndProperties getFeaturesAndProperties() {
return resourceConfig;
}
@Override
public WebApplication clone() {
WebApplicationImpl wa = new WebApplicationImpl();
wa.initiate(resourceConfig, provider);
return wa;
}
/* package */ UriRules getUriRules(final Class c) {
assert c != null;
// Try the non-blocking read, the most common operation
UriRules r = rulesMap.get(c);
if (r != null) {
return r;
}
// Not present use a synchronized block to ensure that only one
// instance is created and put to the map
synchronized (abstractResourceMap) {
// One or more threads may have been blocking on the synchronized
// block, re-check the map
r = rulesMap.get(c);
if (r != null) {
return r;
}
r = Errors.processWithErrors(new Errors.Closure() {
@Override
public ResourceUriRules f() {
return newResourceUriRules(getAbstractResource(c));
}
}).getRules();
rulesMap.put(c, r);
}
return r;
}
/* package */ ResourceComponentProvider getResourceComponentProvider(final Class c) {
assert c != null;
// Try the non-blocking read, the most common operation
ResourceComponentProvider rcp = providerMap.get(c);
if (rcp != null) {
return rcp;
}
// Not present use a synchronized block to ensure that only one
// instance is created and put to the map
synchronized (abstractResourceMap) {
// One or more threads may have been blocking on the synchronized
// block, re-check the map
rcp = providerMap.get(c);
if (rcp != null) {
return rcp;
}
final ResourceComponentProvider _rcp = rcp = rcpFactory.getComponentProvider(null, c);
Errors.processWithErrors(new Errors.Closure() {
@Override
public Void f() {
_rcp.init(getAbstractResource(c));
return null;
}
});
providerMap.put(c, rcp);
}
return rcp;
}
/* package */ ResourceComponentProvider getResourceComponentProvider(final ComponentContext cc, final Class c) {
assert c != null;
if (cc == null || cc.getAnnotations().length == 0)
return getResourceComponentProvider(c);
if (cc.getAnnotations().length == 1) {
final Annotation a = cc.getAnnotations()[0];
if (a.annotationType() == Inject.class) {
final Inject i = Inject.class.cast(a);
final String value = (i.value() != null)
? i.value().trim()
: "";
if (value.isEmpty())
return getResourceComponentProvider(c);
} else if (a.annotationType() == InjectParam.class) {
final InjectParam i = InjectParam.class.cast(a);
final String value = (i.value() != null)
? i.value().trim()
: "";
if (value.isEmpty())
return getResourceComponentProvider(c);
}
}
final ClassAnnotationKey cak = new ClassAnnotationKey(c,
cc.getAnnotations());
// Try the non-blocking read, the most common operation
ResourceComponentProvider rcp = providerWithAnnotationKeyMap.get(cak);
if (rcp != null) {
return rcp;
}
// Not present use a synchronized block to ensure that only one
// instance is created and put to the map
synchronized (abstractResourceMap) {
// One or more threads may have been blocking on the synchronized
// block, re-check the map
rcp = providerWithAnnotationKeyMap.get(cak);
if (rcp != null) {
return rcp;
}
final ResourceComponentProvider _rcp = rcp = rcpFactory.getComponentProvider(cc, c);
Errors.processWithErrors(new Errors.Closure() {
@Override
public Void f() {
_rcp.init(getAbstractResource(c));
return null;
}
});
providerWithAnnotationKeyMap.put(cak, rcp);
}
return rcp;
}
/* package */ void initiateResource(AbstractResource ar) {
initiateResource(ar.getResourceClass());
}
/* package */ void initiateResource(Class c) {
getUriRules(c);
getResourceComponentProvider(c);
}
/* package */ void initiateResource(AbstractResource ar, final Object resource) {
final Class c = ar.getResourceClass();
getUriRules(c);
if (!providerMap.containsKey(c)) {
providerMap.put(c, new ResourceComponentProvider() {
@Override
public void init(AbstractResource abstractResource) {
}
@Override
public ComponentScope getScope() {
return ComponentScope.Singleton;
}
@Override
public Object getInstance(HttpContext hc) {
return getInstance();
}
@Override
public void destroy() {
}
@Override
public Object getInstance() {
return resource;
}
});
}
}
/* package */ Set getAbstractRootResources() {
return abstractRootResources;
}
/* package */ Map getExplicitAbstractRootResources() {
return explicitAbstractRootResources;
}
private ResourceUriRules newResourceUriRules(final AbstractResource ar) {
assert null != ar;
BasicValidator validator = new BasicValidator();
validator.validate(ar);
for (ResourceModelIssue issue : validator.getIssueList()) {
Errors.error(issue.getMessage(), issue.isFatal());
}
return new ResourceUriRules(
resourceConfig,
getDispatchProvider(),
injectableFactory,
filterFactory,
wadlFactory,
dispatchingListener,
ar);
}
protected ResourceMethodDispatchProvider getDispatchProvider() {
return dispatcherFactory;
}
@Override
public RequestListener getRequestListener() {
return requestListener;
}
@Override
public DispatchingListener getDispatchingListener() {
return dispatchingListener;
}
@Override
public ResponseListener getResponseListener() {
return responseListener;
}
/* package */ AbstractResource getAbstractResource(Object o) {
return getAbstractResource(o.getClass());
}
/* package */ AbstractResource getAbstractResource(Class c) {
AbstractResource ar = abstractResourceMap.get(c);
if (ar == null) {
ar = IntrospectionModeller.createResource(c);
abstractResourceMap.put(c, ar);
}
return ar;
}
private static class ContextInjectableProvider extends
SingletonTypeInjectableProvider {
ContextInjectableProvider(Type type, T instance) {
super(type, instance);
}
}
@Override
public boolean isInitiated () {
return initiated;
}
@Override
public void initiate(ResourceConfig resourceConfig) {
initiate(resourceConfig, null);
}
@Override
public void initiate(final ResourceConfig rc, final IoCComponentProviderFactory _provider) {
Errors.processWithErrors(new Errors.Closure() {
@Override
public Void f() {
Errors.setReportMissingDependentFieldOrMethod(false);
_initiate(rc, _provider);
return null;
}
});
}
private void _initiate(final ResourceConfig rc, final IoCComponentProviderFactory _provider) {
if (rc == null) {
throw new IllegalArgumentException("ResourceConfig instance MUST NOT be null");
}
if (initiated) {
throw new ContainerException(ImplMessages.WEB_APP_ALREADY_INITIATED());
}
this.initiated = true;
LOGGER.info("Initiating Jersey application, version '" + BuildId.getBuildId() + "'");
// If there are components defined in jaxrs-components then
// wrap resource config with appended set of classes
Class>[] components = ServiceFinder.find("jersey-server-components").toClassArray();
if (components.length > 0) {
if (LOGGER.isLoggable(Level.INFO)) {
StringBuilder b = new StringBuilder();
b.append("Adding the following classes declared in META-INF/services/jersey-server-components to the resource configuration:");
for (Class c : components)
b.append('\n').append(" ").append(c);
LOGGER.log(Level.INFO, b.toString());
}
this.resourceConfig = rc.clone();
this.resourceConfig.getClasses().addAll(Arrays.asList(components));
} else {
this.resourceConfig = rc;
}
this.provider = _provider;
this.providerFactories = new ArrayList(2);
for (Object o : resourceConfig.getProviderSingletons()) {
if (o instanceof IoCComponentProviderFactory) {
providerFactories.add((IoCComponentProviderFactory)o);
}
}
if (_provider != null)
providerFactories.add(_provider);
// Set up the component provider factory to be
// used with non-resource class components
this.cpFactory = (providerFactories.isEmpty())
? new ProviderFactory(injectableFactory)
: new IoCProviderFactory(injectableFactory, providerFactories);
// Set up the resource component provider factory
this.rcpFactory = (providerFactories.isEmpty())
? new ResourceFactory(this.resourceConfig, this.injectableFactory)
: new IoCResourceFactory(this.resourceConfig, this.injectableFactory, providerFactories);
// Initiate IoCComponentProcessorFactoryInitializer
for (IoCComponentProviderFactory f : providerFactories) {
IoCComponentProcessorFactory cpf;
if (f instanceof IoCComponentProcessorFactoryInitializer) {
cpf = new ComponentProcessorFactoryImpl();
IoCComponentProcessorFactoryInitializer i = (IoCComponentProcessorFactoryInitializer)f;
i.init(cpf);
}
}
this.resourceContext = new ResourceContext() {
@Override
public ExtendedUriInfo matchUriInfo(URI u) throws ContainerException {
try {
return handleMatchResourceRequest(u);
} catch (ContainerException ex) {
throw ex;
} catch (WebApplicationException ex) {
if (ex.getResponse().getStatus() == 404) {
return null;
} else {
throw new ContainerException(ex);
}
} catch (RuntimeException ex) {
throw new ContainerException(ex);
}
}
@Override
public Object matchResource(URI u) throws ContainerException {
ExtendedUriInfo ui = matchUriInfo(u);
return (ui != null) ? ui.getMatchedResources().get(0) : null;
}
@Override
public T matchResource(URI u, Class c) throws ContainerException, ClassCastException {
return c.cast(matchResource(u));
}
@Override
public T getResource(Class c) {
return c.cast(getResourceComponentProvider(c).getInstance(context));
}
};
final ProviderServices providerServices = new ProviderServices(
ServerSide.class,
this.cpFactory,
resourceConfig.getProviderClasses(),
resourceConfig.getProviderSingletons());
injectableFactory.add(new ContextInjectableProvider(
ProviderServices.class, providerServices));
injectableFactory.add(new ContextInjectableProvider(
ResourceMethodCustomInvokerDispatchFactory.class, new ResourceMethodCustomInvokerDispatchFactory(providerServices)));
// Add injectable provider for @ParentRef
injectableFactory.add(
new InjectableProvider() {
@Override
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}
@Override
public Injectable