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 jersey-bundle Show documentation
Show all versions of jersey-bundle Show documentation
A bundle containing code of all jar-based modules that provide
JAX-RS and Jersey-related features. Such a bundle is *only intended* for
developers that do not use Maven's dependency system.
The bundle does not include code for contributes, tests and samples.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2013 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.Produces;
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.Provider;
import javax.ws.rs.ext.Providers;
import javax.xml.bind.JAXBContext;
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.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
import com.sun.jersey.spi.container.ContainerResponseWriter;
import com.sun.jersey.spi.container.ExceptionMapperContext;
import com.sun.jersey.spi.container.ResourceMethodCustomInvokerDispatchFactory;
import com.sun.jersey.spi.container.ResourceMethodDispatchProvider;
import com.sun.jersey.spi.container.WebApplication;
import com.sun.jersey.spi.container.WebApplicationListener;
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 java.security.AccessController;
import java.security.PrivilegedAction;
/**
* 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 final ConcurrentMap singletonMap =
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) {
return getOrCreateResourceComponentProvider(c, false);
}
/* package */ ResourceComponentProvider getOrCreateResourceComponentProvider(final Class c, final boolean create) {
assert c != null;
// Try the non-blocking read, the most common operation
ResourceComponentProvider rcp = providerMap.get(c);
if (rcp != null) {
return rcp;
}
if (!create && singletonMap.containsKey(c)) {
return singletonMap.get(c);
}
// 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 getOrCreateResourceComponentProvider(c, true);
}
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 getOrCreateResourceComponentProvider(c, true);
}
} 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 getOrCreateResourceComponentProvider(c, true);
}
}
}
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);
getOrCreateResourceComponentProvider(c, true);
}
/* package */ void initiateResource(AbstractResource ar, final Object resource) {
final Class c = ar.getResourceClass();
getUriRules(c);
if (!singletonMap.containsKey(c)) {
singletonMap.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