com.sun.jersey.spi.container.servlet.WebComponent 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.spi.container.servlet;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.net.URI;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.SecurityContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.jersey.api.container.ContainerException;
import com.sun.jersey.api.container.MappableContainerException;
import com.sun.jersey.api.core.ApplicationAdapter;
import com.sun.jersey.api.core.ClasspathResourceConfig;
import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.api.core.TraceInformation;
import com.sun.jersey.api.core.servlet.WebAppResourceConfig;
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.core.header.InBoundHeaders;
import com.sun.jersey.core.header.MediaTypes;
import com.sun.jersey.core.reflection.ReflectionHelper;
import com.sun.jersey.core.util.ReaderWriter;
import com.sun.jersey.server.impl.InitialContextHelper;
import com.sun.jersey.server.impl.ThreadLocalInvoker;
import com.sun.jersey.server.impl.application.DeferredResourceConfig;
import com.sun.jersey.server.impl.cdi.CDIComponentProviderFactoryInitializer;
import com.sun.jersey.server.impl.container.servlet.JSPTemplateProcessor;
import com.sun.jersey.server.impl.ejb.EJBComponentProviderFactoryInitilizer;
import com.sun.jersey.server.impl.managedbeans.ManagedBeanComponentProviderFactoryInitilizer;
import com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider;
import com.sun.jersey.server.impl.monitoring.GlassFishMonitoringInitializer;
import com.sun.jersey.server.probes.UriRuleProbeProvider;
import com.sun.jersey.spi.container.ContainerListener;
import com.sun.jersey.spi.container.ContainerNotifier;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseWriter;
import com.sun.jersey.spi.container.ReloadListener;
import com.sun.jersey.spi.container.WebApplication;
import com.sun.jersey.spi.container.WebApplicationFactory;
import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
/**
* An abstract Web component that may be extended a Servlet and/or
* Filter implementation, or encapsulated by a Servlet or Filter implementation.
*
* @author [email protected]
*/
public class WebComponent implements ContainerListener {
/**
* The servlet initialization property whose value is a fully qualified
* class name of a class that implements {@link ResourceConfig} or
* {@link Application}.
*/
public static final String APPLICATION_CONFIG_CLASS =
"javax.ws.rs.Application";
/**
* The servlet initialization property whose value is a fully qualified
* class name of a class that implements {@link ResourceConfig} or
* {@link Application}.
*/
public static final String RESOURCE_CONFIG_CLASS =
"com.sun.jersey.config.property.resourceConfigClass";
/**
* The base path in the Web Pages where JSP templates, associated with
* viewables of resource classes, are located.
*
* If this property is not set then the base path will be the root path
* of the Web Pages.
*/
public static final String JSP_TEMPLATES_BASE_PATH =
"com.sun.jersey.config.property.JSPTemplatesBasePath";
private static final Logger LOGGER =
Logger.getLogger(WebComponent.class.getName());
private final ThreadLocalInvoker requestInvoker =
new ThreadLocalInvoker();
private final ThreadLocalInvoker responseInvoker =
new ThreadLocalInvoker();
private WebConfig config;
private ResourceConfig resourceConfig;
private boolean useSetStatusOn404 = false;
private WebApplication application;
public WebComponent() {
}
public WebComponent(Application app) {
if (app == null)
throw new IllegalArgumentException();
if (app instanceof ResourceConfig) {
resourceConfig = (ResourceConfig) app;
} else {
resourceConfig = new ApplicationAdapter(app);
}
}
/**
* Get the Web configuration.
*
* @return the Web configuration.
*/
public WebConfig getWebConfig() {
return config;
}
/**
* Get the resource configuration.
*
* @return the resource configuration.
*/
public ResourceConfig getResourceConfig() {
return resourceConfig;
}
/**
* Initiate the Web component.
*
* @param webConfig the Web configuration.
* @throws javax.servlet.ServletException in case of any initialization error
*/
public void init(WebConfig webConfig) throws ServletException {
config = webConfig;
if (resourceConfig == null)
resourceConfig = createResourceConfig(config);
if (config.getConfigType() == WebConfig.ConfigType.FilterConfig &&
resourceConfig.getFeature(ServletContainer.FEATURE_FILTER_FORWARD_ON_404)) {
useSetStatusOn404 = true;
}
load();
Object o = resourceConfig.getProperties().get(
ResourceConfig.PROPERTY_CONTAINER_NOTIFIER);
if (o instanceof List) {
List list = (List) o;
for (Object elem : list) {
if (elem instanceof ContainerNotifier) {
ContainerNotifier crf = (ContainerNotifier) elem;
crf.addListener(this);
}
}
} else if (o instanceof ContainerNotifier) {
ContainerNotifier crf = (ContainerNotifier) o;
crf.addListener(this);
}
}
/**
* Destroy this Web component.
*
* This will destroy the Web application created by this this Web component.
*/
public void destroy() {
if (application != null)
application.destroy();
}
private final static class Writer extends OutputStream implements ContainerResponseWriter {
final HttpServletResponse response;
final boolean useSetStatusOn404;
ContainerResponse cResponse;
long contentLength;
OutputStream out;
boolean statusAndHeadersWritten = false;
Writer(boolean useSetStatusOn404, HttpServletResponse response) {
this.useSetStatusOn404 = useSetStatusOn404;
this.response = response;
}
public OutputStream writeStatusAndHeaders(long contentLength,
ContainerResponse cResponse) throws IOException {
this.contentLength = contentLength;
this.cResponse = cResponse;
this.statusAndHeadersWritten = false;
return this;
}
public void finish() throws IOException {
if (statusAndHeadersWritten)
return;
// Note that the writing of headers MUST be performed before
// the invocation of sendError as on some Servlet implementations
// modification of the response headers will have no effect
// after the invocation of sendError.
writeHeaders();
if (cResponse.getStatus() >= 400) {
if (useSetStatusOn404 && cResponse.getStatus() == 404) {
response.setStatus(cResponse.getStatus());
} else {
final String reason = cResponse.getStatusType().getReasonPhrase();
if (reason == null || reason.isEmpty()) {
response.sendError(cResponse.getStatus());
} else {
response.sendError(cResponse.getStatus(), reason);
}
}
} else {
response.setStatus(cResponse.getStatus());
}
}
public void write(int b) throws IOException {
initiate();
out.write(b);
}
@Override
public void write(byte b[]) throws IOException {
if (b.length > 0) {
initiate();
out.write(b);
}
}
@Override
public void write(byte b[], int off, int len) throws IOException {
if (len > 0) {
initiate();
out.write(b, off, len);
}
}
@Override
public void flush() throws IOException {
writeStatusAndHeaders();
if (out != null)
out.flush();
}
@Override
public void close() throws IOException {
initiate();
out.close();
}
void initiate() throws IOException {
if (out == null) {
writeStatusAndHeaders();
out = response.getOutputStream();
}
}
void writeStatusAndHeaders() {
if (statusAndHeadersWritten)
return;
writeHeaders();
response.setStatus(cResponse.getStatus());
statusAndHeadersWritten = true;
}
void writeHeaders() {
if (contentLength != -1 && contentLength < Integer.MAX_VALUE)
response.setContentLength((int) contentLength);
MultivaluedMap headers = cResponse.getHttpHeaders();
for (Map.Entry> e : headers.entrySet()) {
for (Object v : e.getValue()) {
response.addHeader(e.getKey(), ContainerResponse.getHeaderValue(v));
}
}
}
}
/**
* Dispatch client requests to a resource class.
*
* @param baseUri the base URI of the request.
* @param requestUri the URI of the request.
* @param request the {@link HttpServletRequest} object that
* contains the request the client made to
* the Web component.
* @param response the {@link HttpServletResponse} object that
* contains the response the Web component returns
* to the client.
* @return the status code of the response.
* @throws IOException if an input or output error occurs
* while the Web component is handling the
* HTTP request.
* @throws ServletException if the HTTP request cannot
* be handled.
*/
public int service(URI baseUri, URI requestUri,
final HttpServletRequest request,
final HttpServletResponse response)
throws ServletException, IOException {
// Copy the application field to local instance to ensure that the
// currently loaded web application is used to process
// request
final WebApplication _application = application;
final ContainerRequest cRequest = createRequest(
_application,
request,
baseUri,
requestUri);
cRequest.setSecurityContext(new SecurityContext() {
public Principal getUserPrincipal() {
return request.getUserPrincipal();
}
public boolean isUserInRole(String role) {
return request.isUserInRole(role);
}
public boolean isSecure() {
return request.isSecure();
}
public String getAuthenticationScheme() {
return request.getAuthType();
}
});
// Check if any servlet filters have consumed a request entity
// of the media type application/x-www-form-urlencoded
// This can happen if a filter calls request.getParameter(...)
filterFormParameters(request, cRequest);
try {
UriRuleProbeProvider.requestStart(requestUri);
requestInvoker.set(request);
responseInvoker.set(response);
final Writer w = new Writer(useSetStatusOn404, response);
_application.handleRequest(cRequest, w);
return w.cResponse.getStatus();
} catch (MappableContainerException ex) {
traceOnException(cRequest, response);
throw new ServletException(ex.getCause());
} catch (ContainerException ex) {
traceOnException(cRequest, response);
// TODO: this needs to become generic (not servlet specific only)
// responseListener.onError(Thread.currentThread().getId(), ex);
throw new ServletException(ex);
} catch (RuntimeException ex) {
traceOnException(cRequest, response);
// TODO: this needs to become generic (not servlet specific only)
// responseListener.onError(Thread.currentThread().getId(), ex);
throw ex;
} finally {
UriRuleProbeProvider.requestEnd();
requestInvoker.set(null);
responseInvoker.set(null);
}
}
/**
* Extension point for creating your custom container request.
*
* @param app the web app
* @param request the current servlet api request
* @param baseUri the base uri
* @param requestUri the request uri
* @return the request container
* @throws IOException if any error occurs when getting the input stream
*/
protected ContainerRequest createRequest(WebApplication app,
HttpServletRequest request, URI baseUri, URI requestUri) throws IOException {
return new ContainerRequest(
app,
request.getMethod(),
baseUri,
requestUri,
getHeaders(request),
request.getInputStream());
}
private void traceOnException(final ContainerRequest cRequest, final HttpServletResponse response) {
if (cRequest.isTracingEnabled()) {
final TraceInformation ti = (TraceInformation) cRequest.getProperties().
get(TraceInformation.class.getName());
ti.addTraceHeaders(new TraceInformation.TraceHeaderListener() {
public void onHeader(String name, String value) {
response.addHeader(name, value);
}
});
}
}
/**
* Create a new instance of a {@link WebApplication}.
*
* @return the {@link WebApplication} instance.
*/
protected WebApplication create() {
return WebApplicationFactory.createWebApplication();
}
/**
* A helper class for creating an injectable provider that supports
* {@link Context} with a type and constant value.
*
* @param the type of the constant value.
*/
protected static class ContextInjectableProvider extends
SingletonTypeInjectableProvider {
/**
* Create a new instance.
*
* @param type the type of the constant value.
* @param instance the constant value.
*/
protected ContextInjectableProvider(Type type, T instance) {
super(type, instance);
}
}
/**
* Configure the {@link ResourceConfig}.
*
* The {@link ResourceConfig} is configured such that the following classes
* may be injected onto the field of a root resource class or a parameter
* of a method of root resource class that is annotated with
* {@link javax.ws.rs.core.Context}: {@link HttpServletRequest}, {@link HttpServletResponse}
* , {@link ServletContext} and {@link WebConfig}.
*
* Any root resource class in registered in the resource configuration
* that is an interface is processed as follows.
* If the class is an interface and there exists a JNDI named object
* with the fully qualified class name as the JNDI name then that named
* object is added as a singleton root resource and the class is removed
* from the set of root resource classes.
*
* An inheriting class may override this method to configure the
* {@link ResourceConfig} to provide alternative or additional instances
* that are resource or provider classes or instances, and may modify the
* features and properties of the {@link ResourceConfig}. For an inheriting
* class to extend configuration behaviour the overriding method MUST call
* super.configure(servletConfig, rc, wa)
as the first statement
* of that method.
*
* This method will be called only once at initiation. Subsequent
* reloads of the Web application will not result in subsequence calls to
* this method.
*
* @param wc the Web configuration
* @param rc the Resource configuration
* @param wa the Web application
*/
protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa) {
configureJndiResources(rc);
rc.getSingletons().add(new ContextInjectableProvider(
HttpServletRequest.class,
(HttpServletRequest) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[]{HttpServletRequest.class},
requestInvoker)));
rc.getSingletons().add(new ContextInjectableProvider(
HttpServletResponse.class,
(HttpServletResponse) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[]{HttpServletResponse.class},
responseInvoker)));
GenericEntity> requestThreadLocal =
new GenericEntity>(requestInvoker.getImmutableThreadLocal()) {
};
rc.getSingletons().add(new ContextInjectableProvider>(
requestThreadLocal.getType(), requestThreadLocal.getEntity()));
GenericEntity> responseThreadLocal =
new GenericEntity>(responseInvoker.getImmutableThreadLocal()) {
};
rc.getSingletons().add(new ContextInjectableProvider>(
responseThreadLocal.getType(), responseThreadLocal.getEntity()));
rc.getSingletons().add(new ContextInjectableProvider(
ServletContext.class,
wc.getServletContext()));
rc.getSingletons().add(new ContextInjectableProvider(
WebConfig.class,
wc));
rc.getClasses().add(JSPTemplateProcessor.class);
// TODO
// If CDI is enabled should EJB injection be disabled?
EJBComponentProviderFactoryInitilizer.initialize(rc);
CDIComponentProviderFactoryInitializer.initialize(wc, rc, wa);
// TODO
// If CDI is enabled then no need to initialize managed beans
ManagedBeanComponentProviderFactoryInitilizer.initialize(rc);
GlassFishMonitoringInitializer.initialize();
}
/**
* Initiate the {@link WebApplication}.
*
* This method will be called once at initiation and for
* each reload of the Web application.
*
* An inheriting class may override this method to initiate the
* Web application with different parameters.
*
* @param rc the Resource configuration
* @param wa the Web application
*/
protected void initiate(ResourceConfig rc, WebApplication wa) {
wa.initiate(rc);
}
/**
* Load the Web application. This will create, configure and initiate
* the web application.
*/
public void load() {
WebApplication _application = create();
configure(config, resourceConfig, _application);
initiate(resourceConfig, _application);
application = _application;
}
/**
* Get the default resource configuration if one is not declared in the
* web.xml.
*
* This implementation returns an instance of {@link WebAppResourceConfig}
* that scans in files and directories as declared by the
* {@link ClasspathResourceConfig#PROPERTY_CLASSPATH} if present, otherwise
* in the "WEB-INF/lib" and "WEB-INF/classes" directories.
*
* An inheriting class may override this method to supply a different
* default resource configuration implementation.
*
* @param props the properties to pass to the resource configuration.
* @param wc the web configuration.
* @return the default resource configuration.
* @throws javax.servlet.ServletException in case of any issues with providing \
* the default resource configuration
*/
protected ResourceConfig getDefaultResourceConfig(Map props,
WebConfig wc) throws ServletException {
return getWebAppResourceConfig(props, wc);
}
// ContainerListener
/**
* Reload the Web application. This will create and initiate the web
* application using the same {@link ResourceConfig} implementation
* that was used to load the Web application.
*
* This method may be called at runtime, more than once, to reload the
* Web application. For example, if a {@link ResourceConfig} implementation
* is capable of detecting changes to resource classes (addition or removal)
* or providers then this method may be invoked to reload the web
* application for such changes to take effect.
*
* If this method is called when there are pending requests then such
* requests will be processed using the previously loaded web application.
*/
public void onReload() {
WebApplication oldApplication = application;
WebApplication newApplication = create();
initiate(resourceConfig, newApplication);
application = newApplication;
if (resourceConfig instanceof ReloadListener)
((ReloadListener) resourceConfig).onReload();
oldApplication.destroy();
}
//
/* package */ ResourceConfig getWebAppResourceConfig(Map props,
WebConfig webConfig) throws ServletException {
// Default to using Web app resource config
return new WebAppResourceConfig(props, webConfig.getServletContext());
}
private ResourceConfig createResourceConfig(WebConfig webConfig)
throws ServletException {
final Map props = getInitParams(webConfig);
final ResourceConfig rc = createResourceConfig(webConfig, props);
rc.setPropertiesAndFeatures(props);
return rc;
}
private ResourceConfig createResourceConfig(WebConfig webConfig, Map props)
throws ServletException {
// Check if the resource config class property is present
String resourceConfigClassName = webConfig.getInitParameter(RESOURCE_CONFIG_CLASS);
// Otherwise check if the JAX-RS application config class property is
// present
if (resourceConfigClassName == null)
resourceConfigClassName = webConfig.getInitParameter(APPLICATION_CONFIG_CLASS);
// If no resource config class property is present
if (resourceConfigClassName == null) {
// If the packages property is present then
// use the packages resource config
String packages = webConfig.getInitParameter(
PackagesResourceConfig.PROPERTY_PACKAGES);
if (packages != null) {
props.put(PackagesResourceConfig.PROPERTY_PACKAGES, packages);
return new PackagesResourceConfig(props);
}
ResourceConfig defaultConfig = webConfig.getDefaultResourceConfig(props);
if (defaultConfig != null)
return defaultConfig;
return getDefaultResourceConfig(props, webConfig);
}
try {
Class> resourceConfigClass = ReflectionHelper.
classForNameWithException(resourceConfigClassName);
// TODO add support for WebAppResourceConfig
if (resourceConfigClass == ClasspathResourceConfig.class) {
String[] paths = getPaths(webConfig.getInitParameter(
ClasspathResourceConfig.PROPERTY_CLASSPATH));
props.put(ClasspathResourceConfig.PROPERTY_CLASSPATH, paths);
return new ClasspathResourceConfig(props);
} else if (ResourceConfig.class.isAssignableFrom(resourceConfigClass)) {
try {
Constructor constructor = resourceConfigClass.getConstructor(Map.class);
if (ClasspathResourceConfig.class.isAssignableFrom(resourceConfigClass)) {
String[] paths = getPaths(webConfig.getInitParameter(
ClasspathResourceConfig.PROPERTY_CLASSPATH));
props.put(ClasspathResourceConfig.PROPERTY_CLASSPATH, paths);
}
return (ResourceConfig) constructor.newInstance(props);
} catch (NoSuchMethodException ex) {
// Pass through and try the default constructor
} catch (Exception e) {
throw new ServletException(e);
}
return new DeferredResourceConfig(resourceConfigClass.asSubclass(ResourceConfig.class));
} else if (Application.class.isAssignableFrom(resourceConfigClass)) {
return new DeferredResourceConfig(resourceConfigClass.asSubclass(Application.class));
} else {
String message = "Resource configuration class, " + resourceConfigClassName +
", is not a super class of " + Application.class;
throw new ServletException(message);
}
} catch (ClassNotFoundException e) {
String message = "Resource configuration class, " + resourceConfigClassName +
", could not be loaded";
throw new ServletException(message, e);
}
}
private Map getInitParams(WebConfig webConfig) {
Map props = new HashMap();
Enumeration names = webConfig.getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
props.put(name, webConfig.getInitParameter(name));
}
return props;
}
private String[] getPaths(String classpath) throws ServletException {
final ServletContext context = config.getServletContext();
if (classpath == null) {
String[] paths = {
context.getRealPath("/WEB-INF/lib"),
context.getRealPath("/WEB-INF/classes")
};
if (paths[0] == null && paths[1] == null) {
String message = "The default deployment configuration that scans for " +
"classes in /WEB-INF/lib and /WEB-INF/classes is not supported " +
"for the application server." +
"Try using the package scanning configuration, see the JavaDoc for " +
PackagesResourceConfig.class.getName() + " and the property " +
PackagesResourceConfig.PROPERTY_PACKAGES + ".";
throw new ServletException(message);
}
return paths;
} else {
String[] virtualPaths = classpath.split(";");
List resourcePaths = new ArrayList();
for (String virtualPath : virtualPaths) {
virtualPath = virtualPath.trim();
if (virtualPath.length() == 0) continue;
String path = context.getRealPath(virtualPath);
if (path != null) resourcePaths.add(path);
}
if (resourcePaths.isEmpty()) {
String message = "None of the declared classpath locations, " +
classpath +
", could be resolved. " +
"This could be because the default deployment configuration that scans for " +
"classes in classpath locations is not supported. " +
"Try using the package scanning configuration, see the JavaDoc for " +
PackagesResourceConfig.class.getName() + " and the property " +
PackagesResourceConfig.PROPERTY_PACKAGES + ".";
throw new ServletException(message);
}
return resourcePaths.toArray(new String[resourcePaths.size()]);
}
}
private void configureJndiResources(ResourceConfig rc) {
// Obtain any instances that are registered in JNDI
// Assumes such instances are singletons
// Registered classes have to be interfaces
javax.naming.Context x = InitialContextHelper.getInitialContext();
if (x != null) {
Iterator> i = rc.getClasses().iterator();
while (i.hasNext()) {
Class> c = i.next();
if (!c.isInterface()) continue;
try {
Object o = x.lookup(c.getName());
if (o != null) {
i.remove();
rc.getSingletons().add(o);
LOGGER.log(Level.INFO,
"An instance of the class " + c.getName() +
" is found by JNDI look up using the class name as the JNDI name. " +
"The instance will be registered as a singleton.");
}
} catch (NamingException ex) {
LOGGER.log(Level.CONFIG,
"JNDI lookup failed for Jersey application resource " + c.getName(),
ex);
}
}
}
}
private void filterFormParameters(HttpServletRequest hsr, ContainerRequest cr) throws IOException {
if (MediaTypes.typeEquals(MediaType.APPLICATION_FORM_URLENCODED_TYPE, cr.getMediaType())
&& !isEntityPresent(cr)) {
Form f = new Form();
Enumeration e = hsr.getParameterNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String[] values = hsr.getParameterValues(name);
f.put(name, Arrays.asList(values));
}
if (!f.isEmpty()) {
cr.getProperties().put(FormDispatchProvider.FORM_PROPERTY, f);
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING,
"A servlet request, to the URI " + cr.getRequestUri() + ", " +
"contains form parameters in " +
"the request body but the request body has been consumed " +
"by the servlet or a servlet filter accessing the request " +
"parameters. Only resource methods using @FormParam " +
"will work as expected. Resource methods consuming the " +
"request body by other means will not work as expected.");
}
}
}
}
private boolean isEntityPresent(ContainerRequest cr) throws IOException {
InputStream in = cr.getEntityInputStream();
if (!in.markSupported()) {
in = new BufferedInputStream(in, ReaderWriter.BUFFER_SIZE);
cr.setEntityInputStream(in);
}
in.mark(1);
if (in.read() == -1)
return false;
else {
in.reset();
return true;
}
}
private InBoundHeaders getHeaders(HttpServletRequest request) {
InBoundHeaders rh = new InBoundHeaders();
for (Enumeration names = request.getHeaderNames(); names.hasMoreElements();) {
String name = names.nextElement();
List valueList = new LinkedList();
for (Enumeration values = request.getHeaders(name); values.hasMoreElements();) {
valueList.add(values.nextElement());
}
rh.put(name, valueList);
}
return rh;
}
}