/*******************************************************************************
* Copyright (c) 2002, 2010 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
* EclipseSource - ongoing development
******************************************************************************/
package org.eclipse.rwt.internal.engine;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.*;
import javax.servlet.*;
import org.eclipse.rwt.branding.AbstractBranding;
import org.eclipse.rwt.internal.AdapterFactoryRegistry;
import org.eclipse.rwt.internal.branding.BrandingManager;
import org.eclipse.rwt.internal.lifecycle.*;
import org.eclipse.rwt.internal.resources.*;
import org.eclipse.rwt.internal.service.*;
import org.eclipse.rwt.internal.theme.*;
import org.eclipse.rwt.internal.theme.css.CssFileReader;
import org.eclipse.rwt.internal.theme.css.StyleSheet;
import org.eclipse.rwt.lifecycle.PhaseListener;
import org.eclipse.rwt.resources.IResource;
import org.eclipse.rwt.resources.IResourceManagerFactory;
import org.eclipse.rwt.service.ISettingStoreFactory;
import org.eclipse.rwt.service.RWTFileSettingStoreFactory;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Widget;
public final class RWTServletContextListener implements ServletContextListener {
private static final String PREFIX = "org.eclipse.rwt.";
public static final String ENTRY_POINTS_PARAM
= PREFIX + "entryPoints";
public static final String THEMES_PARAM
= PREFIX + "themes";
public static final String RESOURCE_MANAGER_FACTORY_PARAM
= PREFIX + "resourceManagerFactory";
public static final String SETTING_STORE_FACTORY_PARAM
= PREFIX + "settingStoreFactory";
public static final String ADAPTER_FACTORIES_PARAM
= PREFIX + "adapterFactories";
public static final String PHASE_LISTENERS_PARAM
= PREFIX + "phaseListeners";
public static final String RESOURCES_PARAM
= PREFIX + "resources";
public static final String BRANDINGS_PARAM
= PREFIX + "brandings";
private static final String SEPARATOR = ",";
private static final String REGISTERED_ENTRY_POINTS
= RWTServletContextListener.class.getName() + "registeredEntryPoints";
private static final String REGISTERED_PHASE_LISTENERS
= RWTServletContextListener.class.getName() + "registeredPhaseListeners";
private static final String REGISTERED_RESOURCES
= RWTServletContextListener.class.getName() + "registeredResources";
private static final String REGISTERED_BRANDINGS
= RWTServletContextListener.class.getName() + "registeredBrandings";
///////////////////////////////////////////
// implementation of ServletContextListener
public void contextInitialized( final ServletContextEvent evt ) {
registerThemes( evt.getServletContext() );
registerBrandings( evt.getServletContext() );
registerEntryPoints( evt.getServletContext() );
registerResourceManagerFactory( evt.getServletContext() );
registerSettingStoreFactory( evt.getServletContext() );
registerAdapterFactories( evt.getServletContext() );
registerPhaseListener( evt.getServletContext() );
registerResources( evt.getServletContext() );
registerUICallBackServiceHandler();
registerJSLibraryServiceHandler();
StartupPage.configurer = new RWTStartupPageConfigurer();
ResourceUtil.startJsConcatenation();
}
public void contextDestroyed( final ServletContextEvent evt ) {
deregisterThemes( evt.getServletContext() );
deregisterBrandings( evt.getServletContext() );
deregisterEntryPoints( evt.getServletContext() );
deregisterPhaseListeners( evt.getServletContext() );
deregisterResources( evt.getServletContext() );
deregisterUICallBackServiceHandler();
deregisterJSLibraryServiceHandler();
LifeCycleFactory.destroy();
}
////////////////////////////////////////////////////////////
// helping methods - entry point registration/deregistration
private static void registerEntryPoints( final ServletContext context ) {
Set registeredEntryPoints = new HashSet();
String value = context.getInitParameter( ENTRY_POINTS_PARAM );
if( value != null ) {
String[] entryPoints = value.split( SEPARATOR );
for( int i = 0; i < entryPoints.length; i++ ) {
String entryPoint = entryPoints[ i ];
String[] parts = entryPoint.trim().split( "#" );
String className = parts[ 0 ];
String entryPointName = EntryPointManager.DEFAULT;
if( parts.length > 1 ) {
entryPointName = parts[ 1 ];
}
try {
Class clazz = Class.forName( className );
EntryPointManager.register( entryPointName, clazz );
registeredEntryPoints.add( entryPointName );
} catch( final Exception ex ) {
String text = "Failed to register entry point ''{0}''.";
Object[] args = new Object[] { entryPoint };
String msg = MessageFormat.format( text, args );
context.log( msg, ex );
}
}
}
setRegisteredEntryPoints( context, registeredEntryPoints );
}
private static void deregisterEntryPoints( final ServletContext context ) {
String[] entryPoints = getRegisteredEntryPoints( context );
if( entryPoints != null ) {
for( int i = 0; i < entryPoints.length; i++ ) {
EntryPointManager.deregister( entryPoints[ i ] );
}
}
}
private static void setRegisteredEntryPoints( final ServletContext ctx,
final Set entryPoints )
{
String[] value = new String[ entryPoints.size() ];
entryPoints.toArray( value );
ctx.setAttribute( REGISTERED_ENTRY_POINTS, value );
}
private static String[] getRegisteredEntryPoints( final ServletContext ctx ) {
return ( String[] )ctx.getAttribute( REGISTERED_ENTRY_POINTS );
}
//////////////////////////////////////////////////
// Helping methods - resource manager registration
private static void registerResourceManagerFactory(
final ServletContext context )
{
String factoryName
= context.getInitParameter( RESOURCE_MANAGER_FACTORY_PARAM );
if( factoryName != null ) {
try {
Class clazz = Class.forName( factoryName );
IResourceManagerFactory factory;
factory = ( IResourceManagerFactory )clazz.newInstance();
ResourceManager.register( factory );
} catch( final Exception ex ) {
String text = "Failed to register resource manager factory ''{0}''.";
String msg = MessageFormat.format( text, new Object[] { factoryName } );
context.log( msg, ex );
}
} else {
ResourceManager.register( new DefaultResourceManagerFactory() );
}
}
///////////////////////////////////////////////////////
// Helping methods - setting store factory registration
private static void registerSettingStoreFactory(
final ServletContext context )
{
if( !SettingStoreManager.hasFactory() ) {
String factoryName
= context.getInitParameter( SETTING_STORE_FACTORY_PARAM );
if( factoryName != null ) {
try {
Class clazz = Class.forName( factoryName );
ISettingStoreFactory factory;
factory = ( ISettingStoreFactory )clazz.newInstance();
SettingStoreManager.register( factory );
} catch( final Exception ex ) {
String text = "Failed to register setting store factory ''{0}''.";
String msg = MessageFormat.format( text, new Object[] { factoryName } );
context.log( msg, ex );
}
} else {
SettingStoreManager.register( new RWTFileSettingStoreFactory() );
}
}
}
/////////////////////////////////////////////////
// Helping methods - adapter factory registration
private static void registerAdapterFactories( final ServletContext context ) {
String initParam = context.getInitParameter( ADAPTER_FACTORIES_PARAM );
if( initParam != null ) {
String[] factoryParams = initParam.split( SEPARATOR );
for( int i = 0; i < factoryParams.length; i++ ) {
String[] classNames = factoryParams[ i ].trim().split( "#" );
if( classNames.length != 2 ) {
Object[] param = new Object[] { factoryParams[ i ] };
String text = "''{0}'' is not a valid factory-adaptable pair.";
String msg = MessageFormat.format( text, param );
context.log( msg );
} else {
try {
Class factoryClass = Class.forName( classNames[ 0 ] );
Class adaptableClass = Class.forName( classNames[ 1 ] );
AdapterFactoryRegistry.add( factoryClass, adaptableClass );
} catch( final Throwable thr ) {
Object[] param = new Object[] { factoryParams[ i ] };
String text;
text = "Could not register the factory-adaptable ''{0}'' pair.";
String msg = MessageFormat.format( text, param );
context.log( msg, thr );
}
}
}
} else {
AdapterFactoryRegistry.add( LifeCycleAdapterFactory.class,
Widget.class );
AdapterFactoryRegistry.add( LifeCycleAdapterFactory.class,
Display.class );
}
}
///////////////////////////////////////////////////////////////
// Helping methods - phase listener registration/deregistration
private static void registerPhaseListener( final ServletContext context ) {
List phaseListeners = new ArrayList();
String initParam = context.getInitParameter( PHASE_LISTENERS_PARAM );
if( initParam != null ) {
String[] listenerNames = initParam.split( SEPARATOR );
for( int i = 0; i < listenerNames.length; i++ ) {
String className = listenerNames[ i ].trim();
try {
Class clazz = Class.forName( className );
PhaseListener listener = ( PhaseListener )clazz.newInstance();
phaseListeners.add( listener );
} catch( final Throwable thr ) {
String text = "Failed to register phase listener ''{0}''.";
String msg = MessageFormat.format( text, new Object[] { className } );
context.log( msg, thr );
}
}
} else {
phaseListeners.add( new PreserveWidgetsPhaseListener() );
phaseListeners.add( new CurrentPhase.Listener() );
}
PhaseListener[] registeredListeners;
registeredListeners = new PhaseListener[ phaseListeners.size() ];
phaseListeners.toArray( registeredListeners );
for( int i = 0; i < registeredListeners.length; i++ ) {
PhaseListenerRegistry.add( registeredListeners[ i ] );
}
context.setAttribute( REGISTERED_PHASE_LISTENERS, registeredListeners );
}
private static void deregisterPhaseListeners( final ServletContext context ) {
PhaseListener[] listeners = getRegisteredPhaseListeners( context );
if( listeners != null ) {
for( int i = 0; i < listeners.length; i++ ) {
PhaseListenerRegistry.remove( listeners[ i ] );
}
}
}
private static PhaseListener[] getRegisteredPhaseListeners(
final ServletContext ctx )
{
return ( PhaseListener[] )ctx.getAttribute( REGISTERED_PHASE_LISTENERS );
}
//////////////////////////////////////////
// Helping methods - resource registration
private static void registerResources( final ServletContext context ) {
List resources = new ArrayList();
String initParam = context.getInitParameter( RESOURCES_PARAM );
if( initParam != null ) {
String[] resourceClassNames = initParam.split( SEPARATOR );
for( int i = 0; i < resourceClassNames.length; i++ ) {
String className = resourceClassNames[ i ].trim();
try {
Class clazz = Class.forName( className );
IResource resource = ( IResource )clazz.newInstance();
resources.add( resource );
} catch( final Throwable thr ) {
String text = "Failed to register resource ''{0}''.";
String msg = MessageFormat.format( text, new Object[] { className } );
context.log( msg, thr );
}
}
}
IResource[] registeredResources;
registeredResources = new IResource[ resources.size() ];
resources.toArray( registeredResources );
for( int i = 0; i < registeredResources.length; i++ ) {
ResourceRegistry.add( registeredResources[ i ] );
}
context.setAttribute( REGISTERED_RESOURCES, registeredResources );
}
private static void deregisterResources( final ServletContext context ) {
ResourceRegistry.clear();
}
///////////////////////////////////////
// Helping methods - theme registration
private static void registerThemes( final ServletContext context ) {
ThemeManager manager = ThemeManager.getInstance();
String value = context.getInitParameter( THEMES_PARAM );
ResourceLoader loader = new ResourceLoader() {
public InputStream getResourceAsStream( final String resourceName )
throws IOException
{
// IMPORTANT: use ClassLoader#getResourceAsStream instead of
// Class#getResourceAsStream to retrieve resource (see respective
// JavaDoc)
return getClass().getClassLoader().getResourceAsStream( resourceName );
}
};
if( value != null ) {
String[] themes = value.split( SEPARATOR );
for( int i = 0; i < themes.length; i++ ) {
String[] parts = themes[ i ].trim().split( "#" );
if( parts.length >= 2 ) {
String themeId = parts[ 0 ];
String fileName = parts[ 1 ];
try {
String themeName = "Unnamed Theme: " + themeId;
StyleSheet styleSheet
= CssFileReader.readStyleSheet( fileName, loader );
Theme theme = new Theme( themeId, themeName, styleSheet );
manager.registerTheme( theme );
} catch( Exception e ) {
String text = "Failed to register custom theme ''{0}'' "
+ "from resource ''{1}''";
Object[] args = new Object[] { themeId, fileName };
String msg = MessageFormat.format( text, args );
context.log( msg, e );
}
}
}
}
manager.initialize();
}
private static void deregisterThemes( final ServletContext servletContext ) {
ThemeManager.resetInstance();
}
////////////////////////////////////////////////
// Helping methods - UI callback service handler
private static void registerUICallBackServiceHandler() {
ServiceManager.registerServiceHandler( UICallBackServiceHandler.HANDLER_ID,
new UICallBackServiceHandler() );
}
private static void deregisterUICallBackServiceHandler() {
String id = UICallBackServiceHandler.HANDLER_ID;
ServiceManager.unregisterServiceHandler( id );
}
//////////////////////////////////////////
// Helping methods - branding registration
private static void registerBrandings( final ServletContext servletContext ) {
String value = servletContext.getInitParameter( BRANDINGS_PARAM );
if( value != null ) {
List registeredBrandings = new ArrayList();
String[] brandings = value.split( SEPARATOR );
for( int i = 0; i < brandings.length; i++ ) {
String className = brandings[ i ].trim();
try {
Object newInstance = Class.forName( className ).newInstance();
AbstractBranding branding = ( AbstractBranding )newInstance;
BrandingManager.register( branding );
registeredBrandings.add( branding );
} catch( Exception e ) {
String text = "Failed to register branding ''{0}''.";
String msg = MessageFormat.format( text, new Object[] { className } );
servletContext.log( msg, e );
}
}
setRegisteredBrandings( servletContext, registeredBrandings );
}
}
private static void setRegisteredBrandings( final ServletContext context,
final List brandings )
{
AbstractBranding[] registeredBrandings
= new AbstractBranding[ brandings.size() ];
brandings.toArray( registeredBrandings );
context.setAttribute( REGISTERED_BRANDINGS, registeredBrandings );
}
private static void deregisterBrandings( final ServletContext context ) {
AbstractBranding[] brandings
= ( AbstractBranding[] )context.getAttribute( REGISTERED_BRANDINGS );
if( brandings != null ) {
for( int i = 0; i < brandings.length; i++ ) {
BrandingManager.deregister( brandings[ i ] );
}
}
}
////////////////////////////////////////////////
// Helping methods - JS Library service handler
private static void registerJSLibraryServiceHandler() {
ServiceManager.registerServiceHandler( JSLibraryServiceHandler.HANDLER_ID,
new JSLibraryServiceHandler() );
}
private static void deregisterJSLibraryServiceHandler() {
String id = JSLibraryServiceHandler.HANDLER_ID;
ServiceManager.unregisterServiceHandler( id );
}
}