Package org.apache.wink.server.internal.servlet

Source Code of org.apache.wink.server.internal.servlet.RestServlet

/*******************************************************************************
* 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.servlet;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Application;

import org.apache.wink.common.internal.i18n.Messages;
import org.apache.wink.common.internal.lifecycle.ObjectFactory;
import org.apache.wink.common.internal.properties.WinkSystemProperties;
import org.apache.wink.common.internal.utils.ClassUtils;
import org.apache.wink.server.internal.DeploymentConfiguration;
import org.apache.wink.server.internal.RequestProcessor;
import org.apache.wink.server.internal.application.ServletWinkApplication;
import org.apache.wink.server.internal.log.Providers;
import org.apache.wink.server.internal.log.Resources;
import org.apache.wink.server.internal.utils.ServletFileLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <p>
* Main servlet that is used by the runtime to handle the incoming request.
* <p>
* The init-params are supported:
* <ul>
* <li><b>propertiesLocation</b> - custom properties file</li>
* <li><b>applicationConfigLocation</b> - locations of flat application
* configuration files. Relevant only if the no
* <tt>javax.ws.rs.core.Application</tt> is provided.</li>
* <li><b>deploymentConfiguration</b> - custom deployment configuration class
* name. The deployment configuration must extend
* <tt>org.apache.wink.server.internal.DeploymentConfiguration</tt>.</li>
* </ul>
* <p>
* <b>Important! The init-params are relevant only when working without the
* Spring support module.</b> When working with Spring, the
* <tt>org.springframework.web.context.ContextLoaderListener</tt> must be
* configured and the whole customization should occur via the spring context.
*/
public class RestServlet extends AbstractRestServlet {

    private static final long   serialVersionUID        = 8797036173835816706L;

    private static final Logger logger                  =
                                                            LoggerFactory
                                                                .getLogger(RestServlet.class);

    public static final String  APPLICATION_INIT_PARAM  = "javax.ws.rs.Application";          //$NON-NLS-1$
    public static final String  PROPERTIES_DEFAULT_FILE = "META-INF/wink-default.properties"; //$NON-NLS-1$
    public static final String  PROPERTIES_INIT_PARAM   = "propertiesLocation";               //$NON-NLS-1$
    public static final String  APP_LOCATION_PARAM      = "applicationConfigLocation";        //$NON-NLS-1$
    public static final String  DEPLOYMENT_CONF_PARAM   = "deploymentConfiguration";          //$NON-NLS-1$

    @Override
    public void init() throws ServletException {

        logger.trace("Initializing {} servlet", this); //$NON-NLS-1$

        try {
            super.init();
            // try to get the request processor
            // the request processor can be available if it was loaded by a
            // listener
            // or when working with Spring
            RequestProcessor requestProcessor = getRequestProcessor();
            if (requestProcessor == null) {
                // create the request processor
                requestProcessor = createRequestProcessor();
                if (requestProcessor == null) {
                    throw new IllegalStateException(Messages
                        .getMessage("restServletRequestProcessorCouldNotBeCreated")); //$NON-NLS-1$
                }
                storeRequestProcessorOnServletContext(requestProcessor);
            }
            if (requestProcessor.getConfiguration().getServletConfig() == null) {
                requestProcessor.getConfiguration().setServletConfig(getServletConfig());
            }
            if (requestProcessor.getConfiguration().getServletContext() == null) {
                requestProcessor.getConfiguration().setServletContext(getServletContext());
            }
        } catch (Exception e) {
            // when exception occurs during the servlet initialization
            // it should be marked as unavailable
            logger.error(e.getMessage(), e);
            throw new UnavailableException(e.getMessage());
        }
    }

    @Override
    protected void service(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse) throws ServletException,
        IOException {
        getRequestProcessor().handleRequest(httpServletRequest, httpServletResponse);
    }

    protected RequestProcessor createRequestProcessor() throws ClassNotFoundException,
        InstantiationException, IllegalAccessException, IOException {
        DeploymentConfiguration deploymentConfiguration = getDeploymentConfiguration();
        // order of next two lines is important to allow Application to have
        // control over priority order of Providers
        Application app = getApplication();
        if (app == null) {
            app = getApplication(deploymentConfiguration);
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Setting application to " + app.toString());
        }
        deploymentConfiguration.addApplication(app, false);

        if (!LoggerFactory.getLogger(Resources.class).isTraceEnabled()) {
            /*
             * if just debug or higher is enabled, then log only user
             * applications
             */
            new Resources(deploymentConfiguration.getResourceRegistry()).log();
        }

        if (!LoggerFactory.getLogger(Providers.class).isTraceEnabled()) {
            /*
             * if just debug or higher is enabled, then log only user
             * applications
             */
            new Providers(deploymentConfiguration.getProvidersRegistry()).log();
        }

        RequestProcessor requestProcessor = new RequestProcessor(deploymentConfiguration);
        logger.trace("Creating request processor {} for servlet {}", requestProcessor, this); //$NON-NLS-1$

        if (LoggerFactory.getLogger(Resources.class).isTraceEnabled()) {
            /*
             * if full trace is enabled, then log everything
             */

            new Resources(deploymentConfiguration.getResourceRegistry()).log();
        }

        if (LoggerFactory.getLogger(Providers.class).isTraceEnabled()) {
            /*
             * if full trace is enabled, then log everything
             */
            new Providers(deploymentConfiguration.getProvidersRegistry()).log();
        }

        return requestProcessor;
    }

    protected DeploymentConfiguration getDeploymentConfiguration() throws ClassNotFoundException,
        InstantiationException, IllegalAccessException, IOException {
        DeploymentConfiguration deploymentConfiguration = createDeploymentConfiguration();
        deploymentConfiguration.setServletConfig(getServletConfig());
        deploymentConfiguration.setServletContext(getServletContext());
        deploymentConfiguration.setProperties(getProperties());
        deploymentConfiguration.init();
        return deploymentConfiguration;
    }

    /**
     * order of loading and property precedence: wink-default.properties file
     * referred to by propertiesLocation init param (may override and add to
     * above set props) JVM system properties (only sets values for key/value
     * pairs where the value is null or empty)
     */
    protected Properties getProperties() throws IOException {
        Properties defaultProperties = loadProperties(PROPERTIES_DEFAULT_FILE, null);
        logger.trace("Default properties {} used in RestServlet {}", defaultProperties, this); //$NON-NLS-1$
        String propertiesLocation = getInitParameter(PROPERTIES_INIT_PARAM);
        if (propertiesLocation != null) {
            if (logger.isInfoEnabled()) {
                logger.info(Messages.getMessage("restServletUsePropertiesFileAtLocation", //$NON-NLS-1$
                                                propertiesLocation,
                                                PROPERTIES_INIT_PARAM));
            }

            // Load properties set on JVM. These should not override
            // the ones set in the configuration file.
            Properties properties = loadProperties(propertiesLocation, defaultProperties);
            properties.putAll(WinkSystemProperties.loadSystemProperties(properties));
            return properties;
        }
        logger.trace("Final properties {} used in RestServlet {}", defaultProperties, this); //$NON-NLS-1$

        // Load properties set on JVM. These should not override
        // the ones set in the configuration file.
        defaultProperties.putAll(WinkSystemProperties.loadSystemProperties(defaultProperties));

        return defaultProperties;
    }

    protected DeploymentConfiguration createDeploymentConfiguration()
        throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        String initParameter = getInitParameter(DEPLOYMENT_CONF_PARAM);
        if (initParameter != null) {
            if (logger.isInfoEnabled()) {
                logger.info(Messages.getMessage("restServletUseDeploymentConfigurationParam", //$NON-NLS-1$
                                                initParameter,
                                                DEPLOYMENT_CONF_PARAM));
            }
            // use ClassUtils.loadClass instead of Class.forName so we have
            // classloader visibility into the Web module in J2EE environments
            Class<?> confClass = ClassUtils.loadClass(initParameter);
            return (DeploymentConfiguration)confClass.newInstance();
        }
        return new DeploymentConfiguration();
    }

    @SuppressWarnings("unchecked")
    protected Application getApplication(DeploymentConfiguration configuration)
        throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<? extends Application> appClass = null;
        String initParameter = getInitParameter(APPLICATION_INIT_PARAM);
        if (initParameter != null) {
            if (logger.isInfoEnabled()) {
                logger.info(Messages.getMessage("restServletJAXRSApplicationInitParam", //$NON-NLS-1$
                                                initParameter,
                                                APPLICATION_INIT_PARAM));
            }
            // use ClassUtils.loadClass instead of Class.forName so we have
            // classloader visibility into the Web module in J2EE environments
            appClass = (Class<? extends Application>)ClassUtils.loadClass(initParameter);

            // let the lifecycle manager create the instance and process fields
            // for injection
            ObjectFactory of = configuration.getOfFactoryRegistry().getObjectFactory(appClass);
            configuration.addApplicationObjectFactory(of);

            return (Application)of.getInstance(null);
        }
        String appLocationParameter = getInitParameter(APP_LOCATION_PARAM);
        if (appLocationParameter == null) {
            if (logger.isWarnEnabled()) {
                logger.warn(Messages.getMessage("propertyNotDefined", APP_LOCATION_PARAM)); //$NON-NLS-1$
            }
        }
        if (logger.isInfoEnabled()) {
            logger.info(Messages.getMessage("restServletWinkApplicationInitParam", //$NON-NLS-1$
                                            appLocationParameter,
                                            APP_LOCATION_PARAM));
        }
        return new ServletWinkApplication(getServletContext(), appLocationParameter);
    }

    protected Application getApplication() throws ClassNotFoundException, InstantiationException,
        IllegalAccessException {
        /*
         * this is a legacy call. in the end, should call
         * getApplication(DeploymentConfiguration) by default but this is left
         * as a call for legacy
         */
        return null;
    }

    /**
     * loadProperties will try to load the properties from the resource,
     * overriding existing properties in defaultProperties, and adding new ones,
     * and return the result
     *
     * @param resourceName
     * @param defaultProperties
     * @return
     * @throws IOException
     */
    private Properties loadProperties(String resourceName, Properties defaultProperties)
        throws IOException {
        Properties properties =
            defaultProperties == null ? new Properties() : new Properties(defaultProperties);

        InputStream is = null;
        try {
            is = ServletFileLoader.loadFileAsStream(getServletContext(), resourceName);
            properties.load(is);
        } catch (FileNotFoundException e) {
            logger.debug("FileNotFoundException for {}", resourceName); //$NON-NLS-1$
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                if (logger.isWarnEnabled()) {
                    logger
                        .warn(Messages.getMessage("exceptionClosingFile") + ": " + resourceName, e); //$NON-NLS-1$ //$NON-NLS-2$
                }
            }
        }

        return properties;
    }

    @Override
    public void destroy() {
        getRequestProcessor().getConfiguration().getProvidersRegistry().removeAllProviders();
        getRequestProcessor().getConfiguration().getResourceRegistry().removeAllResources();
        for (ObjectFactory<?> of : getRequestProcessor().getConfiguration()
            .getApplicationObjectFactories()) {
            of.releaseAll(null);
        }

        /*
         * Be sure to call super.destroy()
         */
        super.destroy();
    }
}
TOP

Related Classes of org.apache.wink.server.internal.servlet.RestServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.