All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.stormpath.sdk.servlet.application.ApplicationLoader Maven / Gradle / Ivy

/*
 * Copyright 2014 Stormpath, Inc.
 *
 * Licensed 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 com.stormpath.sdk.servlet.application;

import com.stormpath.sdk.application.Application;
import com.stormpath.sdk.lang.Classes;
import com.stormpath.sdk.lang.Strings;
import com.stormpath.sdk.lang.UnknownClassException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContext;

/**
 * A {@code ApplicationLoader} is responsible for loading a web application's Stormpath {@link
 * com.stormpath.sdk.application.Application} resource at application startup and making it available in the {@code
 * ServletContext}.  Other ServletContext aware components loaded after this one can access the Application instance by
 * using the Application interface name as the servlet context attribute key:
 *
 * 
 * Application app = (Application)servletContext.getAttribute(Application.class.getName());
 * 
* *

ApplicationResolver

* *

The {@code ApplicationLoader} will delegate application instance lookup to an {@link ApplicationResolver * ApplicationResolver} implementation. By default, the {@link com.stormpath.sdk.servlet.application.DefaultApplicationResolver} * implementation will be used. See that implementation's {@link com.stormpath.sdk.servlet.application.DefaultApplicationResolver * JavaDoc} to learn about how it discovers the application instance.

* *

Custom {@code ApplicationResolver} Implementation

* *

If you need to create a custom ApplicationResolver implementation, you can implement the {@link * com.stormpath.sdk.servlet.application.ApplicationResolver ApplicationResolver} interface yourself and specify that * implementation class name as follows:

* *
 * <context-param>
 *     <param-name>stormpathApplicationResolverClass</param-name>
 *     <param-value>com.mycompany.myapp.stormpath.MyCustomApplicationResolver</param-value>
 * </context-param>
 * 
* *

And that class will be instantiated and used to lookup the Application instance.

* *

If you do not specify this context-param, {@link com.stormpath.sdk.servlet.application.DefaultApplicationResolver} * is assumed by default.

* * @see com.stormpath.sdk.servlet.application.ApplicationResolver * @see com.stormpath.sdk.servlet.application.DefaultApplicationResolver * @since 1.0.RC3 */ public class ApplicationLoader { /** * Servlet Context config param name used to specify the {@link com.stormpath.sdk.servlet.application.ApplicationResolver} * implementation class to use when obtaining the app's Stormpath {@link com.stormpath.sdk.application.Application * Application} resource at startup: {@code stormpathApplicationResolverClass} */ public static final String APP_RESOLVER_CLASS_PARAM_NAME = "stormpathApplicationResolverClass"; public static final String APP_ATTRIBUTE_NAME = Application.class.getName(); private static final Logger log = LoggerFactory.getLogger(ApplicationLoader.class); /** * Looks up and returns the web application's registered Stormpath {@link Application} instance and assigns that * instance to the ServletContext for that context's lifespan. * *

The app is obtained by instantiating a {@link com.stormpath.sdk.servlet.application.ApplicationResolver} * implementation class, and the class name can be specified as a {@code stormpathApplicationResolverClass} context * parameter. If this parameter is not specified, the default {@link com.stormpath.sdk.servlet.application.DefaultApplicationResolver} * implementation is assumed. * * @param servletContext current servlet context * @return the new Stormpath {@code Application} instance. * @throws IllegalStateException if an existing Application instance has already been initialized and associated * with the specified {@code ServletContext}. */ public Application getApplication(ServletContext servletContext) throws IllegalStateException { if (servletContext.getAttribute(APP_ATTRIBUTE_NAME) != null) { String msg = "There is already a Stormpath Application instance associated with the current " + "ServletContext. Check if you have multiple ApplicationLoader* definitions in your web.xml " + "or annotation config!"; throw new IllegalStateException(msg); } servletContext.log("Initializing Stormpath Application instance."); log.info("Starting Stormpath Application initialization."); long startTime = System.currentTimeMillis(); try { Application app = doGetApplication(servletContext); servletContext.setAttribute(APP_ATTRIBUTE_NAME, app); log.debug("Published Application resource as ServletContext attribute with name [{}]", APP_ATTRIBUTE_NAME); if (log.isInfoEnabled()) { long elapsed = System.currentTimeMillis() - startTime; log.info("Stormpath Application initialized in {} ms.", elapsed); } return app; } catch (RuntimeException ex) { log.error("Stormpath application initialization failed", ex); servletContext.setAttribute(APP_ATTRIBUTE_NAME, ex); throw ex; } catch (Error err) { log.error("Stormpath application initialization failed", err); servletContext.setAttribute(APP_ATTRIBUTE_NAME, err); throw err; } } /** * Return the {@link com.stormpath.sdk.servlet.application.ApplicationResolver} implementation class to use, either * the default {@link com.stormpath.sdk.servlet.application.DefaultApplicationResolver} or a custom class if * specified. * * @param servletContext current servlet context * @return the ApplicationResolver implementation class to use * @see #APP_RESOLVER_CLASS_PARAM_NAME * @see com.stormpath.sdk.servlet.application.DefaultApplicationResolver */ protected Class determineApplicationResolverClass(ServletContext servletContext) { String className = servletContext.getInitParameter(APP_RESOLVER_CLASS_PARAM_NAME); className = Strings.trimWhitespace(className); if (className != null) { try { return Classes.forName(className); } catch (UnknownClassException ex) { String msg = "Failed to load custom ApplicationResolver class [" + className + "]"; throw new IllegalStateException(msg, ex); } } else { return DefaultApplicationResolver.class; } } /** * Looks up an Application based on the specified ServletContext. * *

This implementation {@link #determineApplicationResolverClass(javax.servlet.ServletContext) determines} a * {@link com.stormpath.sdk.application.Application} implementation class to use. That class is instantiated, * returned, and invoked.

* *

This allows a custom {@code ApplicationResolver} implementation to be specified via a ServletContext * init-param if desired. If not specified, the default {@link com.stormpath.sdk.servlet.application.DefaultApplicationResolver} * implementation will be used.

* * @param sc current servlet context * @return the constructed Stormpath config instance */ protected Application doGetApplication(ServletContext sc) { Class clazz = determineApplicationResolverClass(sc); if (!ApplicationResolver.class.isAssignableFrom(clazz)) { throw new IllegalStateException("Custom ApplicationResolver class [" + clazz.getName() + "] is not of required type [" + ApplicationResolver.class.getName() + "]"); } ApplicationResolver resolver = (ApplicationResolver) Classes.newInstance(clazz); return resolver.getApplication(sc); } /** * Unbinds the {@link Application} instance for the given servlet context. * * @param servletContext the web apps servlet context */ public void removeApplication(ServletContext servletContext) { servletContext.log("Cleaning up Stormpath application."); servletContext.removeAttribute(APP_ATTRIBUTE_NAME); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy