![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.wink.server.internal.DeploymentConfiguration Maven / Gradle / Ivy
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*******************************************************************************/
package org.apache.wink.server.internal;
import java.io.IOException;
import java.io.InputStream;
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.Properties;
import java.util.Set;
import java.util.Map.Entry;
import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Application;
import org.apache.commons.lang.ClassUtils;
import org.apache.wink.common.internal.WinkConfiguration;
import org.apache.wink.common.internal.application.ApplicationValidator;
import org.apache.wink.common.internal.i18n.Messages;
import org.apache.wink.common.internal.lifecycle.JSR250LifecycleManager;
import org.apache.wink.common.internal.lifecycle.LifecycleManagersRegistry;
import org.apache.wink.common.internal.lifecycle.ObjectFactory;
import org.apache.wink.common.internal.lifecycle.ScopeLifecycleManager;
import org.apache.wink.common.internal.registry.InjectableFactory;
import org.apache.wink.common.internal.registry.ProvidersRegistry;
import org.apache.wink.common.internal.utils.FileLoader;
import org.apache.wink.server.handlers.Handler;
import org.apache.wink.server.handlers.HandlersFactory;
import org.apache.wink.server.handlers.MediaTypeMapperFactory;
import org.apache.wink.server.handlers.RequestHandler;
import org.apache.wink.server.handlers.RequestHandlersChain;
import org.apache.wink.server.handlers.ResponseHandler;
import org.apache.wink.server.handlers.ResponseHandlersChain;
import org.apache.wink.server.internal.application.ApplicationProcessor;
import org.apache.wink.server.internal.handlers.CheckLocationHeaderHandler;
import org.apache.wink.server.internal.handlers.CreateInvocationParametersHandler;
import org.apache.wink.server.internal.handlers.FindResourceMethodHandler;
import org.apache.wink.server.internal.handlers.FindRootResourceHandler;
import org.apache.wink.server.internal.handlers.FlushResultHandler;
import org.apache.wink.server.internal.handlers.HeadMethodHandler;
import org.apache.wink.server.internal.handlers.InvokeMethodHandler;
import org.apache.wink.server.internal.handlers.OptionsMethodHandler;
import org.apache.wink.server.internal.handlers.PopulateErrorResponseHandler;
import org.apache.wink.server.internal.handlers.PopulateResponseMediaTypeHandler;
import org.apache.wink.server.internal.handlers.PopulateResponseStatusHandler;
import org.apache.wink.server.internal.handlers.SearchResultHandler;
import org.apache.wink.server.internal.log.Requests;
import org.apache.wink.server.internal.log.ResourceInvocation;
import org.apache.wink.server.internal.log.Responses;
import org.apache.wink.server.internal.registry.ResourceRegistry;
import org.apache.wink.server.internal.registry.ServerInjectableFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* This class implements a default deployment configuration for Wink. In order
* to change this configuration, extend this class and override the relevant
* methods. In general it's possible to override any methods of this class, but
* the best practices are to override methods the "init" methods. See the
* javadoc for each method for more details.
*/
public class DeploymentConfiguration implements WinkConfiguration {
private static final Logger logger =
LoggerFactory
.getLogger(DeploymentConfiguration.class);
private static final String ALTERNATIVE_SHORTCUTS =
"META-INF/wink-alternate-shortcuts.properties"; //$NON-NLS-1$
private static final String HTTP_METHOD_OVERRIDE_HEADERS_PROP =
"wink.httpMethodOverrideHeaders"; //$NON-NLS-1$
private static final String HANDLERS_FACTORY_CLASS_PROP =
"wink.handlersFactoryClass"; //$NON-NLS-1$
private static final String MEDIATYPE_MAPPER_FACTORY_CLASS_PROP =
"wink.mediaTypeMapperFactoryClass"; //$NON-NLS-1$
private static final String VALIDATE_LOCATION_HEADER =
"wink.validateLocationHeader"; //$NON-NLS-1$
private static final String DEFAULT_RESPONSE_CHARSET =
"wink.response.defaultCharset"; // $NON-NLS-1$
private static final String USE_ACCEPT_CHARSET =
"wink.response.useAcceptCharset"; // $NON-NLS-1$
// handler chains
private boolean isChainInitialized = false;
private RequestHandlersChain requestHandlersChain;
private ResponseHandlersChain responseHandlersChain;
private ResponseHandlersChain errorHandlersChain;
private List requestUserHandlers;
private List responseUserHandlers;
private List errorUserHandlers;
// registries
private ProvidersRegistry providersRegistry;
private ResourceRegistry resourceRegistry;
private LifecycleManagersRegistry ofFactoryRegistry;
// mappers
private MediaTypeMapper mediaTypeMapper;
private Map alternateShortcutMap;
// external properties
private Properties properties;
// servlet configuration
private ServletConfig servletConfig;
private ServletContext servletContext;
private FilterConfig filterConfig;
// jax-rs application subclass
private List applications;
private String[] httpMethodOverrideHeaders;
private Set> appObjectFactories;
private boolean isUseAcceptCharset = false;
private boolean isDefaultResponseCharset = false;
/**
* Makes sure that the object was properly initialized. Should be invoked
* AFTER all the setters were invoked.
*/
public void init() {
if (properties == null) {
properties = new Properties();
}
appObjectFactories = new HashSet>(8);
logger.trace("Deployment configuration properties: {}", properties); //$NON-NLS-1$
// check to see if an override property was specified. if so, then
// configure
// the headers from there using a comma delimited string.
String httpMethodOverrideHeadersProperty =
properties.getProperty(HTTP_METHOD_OVERRIDE_HEADERS_PROP);
httpMethodOverrideHeaders =
(httpMethodOverrideHeadersProperty != null && httpMethodOverrideHeadersProperty
.length() > 0) ? httpMethodOverrideHeadersProperty.split(",") : null; //$NON-NLS-1$
initRegistries();
initAlternateShortcutMap();
initMediaTypeMapper();
initHandlers();
// this next code is to dump the config to trace after initialization
if (logger.isDebugEnabled()) {
try {
logger.debug("Configuration Settings:");
logger.trace("Request Handlers Chain : {}", requestHandlersChain);
logger.trace("Response Handlers Chain: {}", responseHandlersChain);
logger.trace("Error Handlers Chain: {}", errorHandlersChain);
logger.debug("Request User Handlers: {}", String
.format("%1$s", requestUserHandlers));
logger.debug("Response User Handlers: {}", String.format("%1$s",
responseUserHandlers));
logger.debug("Error User Handlers: {}", String.format("%1$s", errorUserHandlers));
logger.trace("LifecycleManagerRegistry: {}", this.ofFactoryRegistry
.getLifecycleManagers());
logger.debug("MediaTypeMapper: {}", this.mediaTypeMapper); // TODO
// add
// toString
// method
// for
// MediaTypeMapper
logger.debug("AlternateShortcutMap: {}", this.alternateShortcutMap);
logger.debug("Properties: {}", this.properties);
logger.trace("ServletConfig: {}", this.servletConfig);
logger.trace("ServletContext: {}", this.servletContext);
logger.trace("FilterConfig: {}", this.filterConfig);
logger.trace("Applications: {}", this.applications);
List httpMethodOverrideHeadersList = new ArrayList();
if (this.httpMethodOverrideHeaders != null) {
for (int i = 0; i < this.httpMethodOverrideHeaders.length; ++i)
httpMethodOverrideHeadersList.add(this.httpMethodOverrideHeaders[i]);
}
logger.debug("HttpMethodOverrideHeaders: {}", httpMethodOverrideHeadersList);
} catch (Exception e) {
// make sure we don't fail in case anything wrong happens here
logger.debug("An Exception occurred when logging the configuration {}", e);
}
}
}
public RequestHandlersChain getRequestHandlersChain() {
if (!isChainInitialized) {
initHandlersChain();
}
return requestHandlersChain;
}
public void setRequestHandlersChain(RequestHandlersChain requestHandlersChain) {
this.requestHandlersChain = requestHandlersChain;
}
public ResponseHandlersChain getResponseHandlersChain() {
if (!isChainInitialized) {
initHandlersChain();
}
return responseHandlersChain;
}
public void setResponseHandlersChain(ResponseHandlersChain responseHandlersChain) {
this.responseHandlersChain = responseHandlersChain;
}
public ResponseHandlersChain getErrorHandlersChain() {
if (!isChainInitialized) {
initHandlersChain();
}
return errorHandlersChain;
}
public void setErrorHandlersChain(ResponseHandlersChain errorHandlersChain) {
this.errorHandlersChain = errorHandlersChain;
}
public ProvidersRegistry getProvidersRegistry() {
return providersRegistry;
}
public ResourceRegistry getResourceRegistry() {
return resourceRegistry;
}
public MediaTypeMapper getMediaTypeMapper() {
return mediaTypeMapper;
}
public void setMediaTypeMapper(MediaTypeMapper mediaTypeMapper) {
this.mediaTypeMapper = mediaTypeMapper;
}
public void setOfFactoryRegistry(LifecycleManagersRegistry ofFactoryRegistry) {
this.ofFactoryRegistry = ofFactoryRegistry;
}
public LifecycleManagersRegistry getOfFactoryRegistry() {
return ofFactoryRegistry;
}
public Map getAlternateShortcutMap() {
return alternateShortcutMap;
}
public void setAlternateShortcutMap(Map alternateShortcutMap) {
this.alternateShortcutMap = alternateShortcutMap;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
String val = properties.getProperty(USE_ACCEPT_CHARSET);
isUseAcceptCharset = Boolean.valueOf(val).booleanValue();
val = properties.getProperty(DEFAULT_RESPONSE_CHARSET);
isDefaultResponseCharset = Boolean.valueOf(val).booleanValue();
}
public ServletConfig getServletConfig() {
return servletConfig;
}
public void setServletConfig(ServletConfig servletConfig) {
this.servletConfig = servletConfig;
}
public FilterConfig getFilterConfig() {
return filterConfig;
}
public void setFilterConfig(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public ServletContext getServletContext() {
return servletContext;
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public void setRequestUserHandlers(List requestUserHandlers) {
this.requestUserHandlers = requestUserHandlers;
}
public void setResponseUserHandlers(List responseUserHandlers) {
this.responseUserHandlers = responseUserHandlers;
}
public List getResponseUserHandlers() {
return responseUserHandlers;
}
public List getRequestUserHandlers() {
return requestUserHandlers;
}
public void setErrorUserHandlers(List errorUserHandlers) {
this.errorUserHandlers = errorUserHandlers;
}
public List getErrorUserHandlers() {
return errorUserHandlers;
}
public void addApplication(Application application, boolean isSystemApplication) {
if (applications == null) {
applications = new ArrayList(1);
}
new ApplicationProcessor(application, resourceRegistry, providersRegistry,
isSystemApplication).process();
applications.add(application);
}
public List getApplications() {
return applications;
}
// init methods
/**
* Initializes registries. Usually there should be no need to override this
* method. When creating Resources or Providers registry, ensure that they
* use the same instance of the ApplicationValidator.
*/
protected void initRegistries() {
InjectableFactory.setInstance(new ServerInjectableFactory());
if (ofFactoryRegistry == null) {
ofFactoryRegistry = new LifecycleManagersRegistry();
ofFactoryRegistry.addFactoryFactory(new ScopeLifecycleManager