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<IoCComponentProviderFactory>(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> T matchResource(URI u, Class<T> c) throws ContainerException, ClassCastException {
return c.cast(matchResource(u));
}
@Override
public <T> T getResource(Class<T> 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>(
ProviderServices.class, providerServices));
injectableFactory.add(new ContextInjectableProvider<ResourceMethodCustomInvokerDispatchFactory>(
ResourceMethodCustomInvokerDispatchFactory.class, new ResourceMethodCustomInvokerDispatchFactory(providerServices)));
// Add injectable provider for @ParentRef
injectableFactory.add(
new InjectableProvider<ParentRef, Type>() {
@Override
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}
@Override
public Injectable<Object> getInjectable(ComponentContext cc, ParentRef a, Type t) {
if (!(t instanceof Class))
return null;
final Class target = ReflectionHelper.getDeclaringClass(cc.getAccesibleObject());
final Class inject = (Class)t;
return new Injectable<Object>() {
@Override
public Object getValue() {
final UriInfo ui = context.getUriInfo();
final List l = ui.getMatchedResources();
final Object parent = getParent(l, target);
if (parent == null) return null;
try {
return inject.cast(parent);
} catch (ClassCastException ex) {
throw new ContainerException(
"The parent resource is expected to be of class " + inject.getName() +
" but is of class " + parent.getClass().getName(),
ex);
}
}