/******************************************************************************* * Copyright (c) 2002, 2009 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 ******************************************************************************/ package org.eclipse.rwt; import java.io.*; import java.lang.reflect.Field; import javax.servlet.http.*; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import junit.framework.Assert; import org.eclipse.rwt.branding.AbstractBranding; import org.eclipse.rwt.internal.*; 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.ThemeManager; import org.eclipse.rwt.lifecycle.*; import org.eclipse.rwt.service.ISessionStore; import org.eclipse.swt.internal.graphics.ResourceFactory; import org.eclipse.swt.internal.widgets.WidgetAdapter; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Widget; import org.xml.sax.SAXException; public class Fixture { public final static File TEMP_DIR = new File( System.getProperty( "java.io.tmpdir" ) ); public final static File CONTEXT_DIR = new File( TEMP_DIR, "testapp" ); public static final String IMAGE1 = "resources/images/image1.gif"; public static final String IMAGE2 = "resources/images/image2.gif"; public static final String IMAGE3 = "resources/images/image3.gif"; public static final String IMAGE_100x50 = "resources/images/test-100x50.png"; public static final String IMAGE_50x100 = "resources/images/test-50x100.png"; private static LifeCycleAdapterFactory lifeCycleAdapterFactory; private static PhaseListener currentPhaseListener = new CurrentPhase.Listener(); private Fixture() { // prevent instantiation } public static void setUp() { // standard setup commonSetUp(); System.setProperty( IInitialization.PARAM_LIFE_CYCLE, RWTLifeCycle.class.getName() ); ThemeManager.getInstance().initialize(); registerAdapterFactories(); PhaseListenerRegistry.add( Fixture.currentPhaseListener ); // registration of mockup resource manager registerResourceManager(); SettingStoreManager.register( new MemorySettingStoreFactory() ); } public static void setUpWithoutResourceManager() { // standard setup commonSetUp(); System.setProperty( IInitialization.PARAM_LIFE_CYCLE, RWTLifeCycle.class.getName() ); // registration of adapter factories registerAdapterFactories(); } private static void commonSetUp() { // disable js-versioning by default to make comparison easier System.setProperty( SystemProps.USE_VERSIONED_JAVA_SCRIPT, "false" ); clearSingletons(); try { ConfigurationReader.setConfigurationFile( null ); } catch( Throwable shouldNotHappen ) { throw new RuntimeException( shouldNotHappen ); } TestResponse response = new TestResponse(); TestRequest request = new TestRequest(); request.setSession( new TestSession() ); fakeContextProvider( response, request ); } public static void tearDown() { // deregistration of mockup resource manager deregisterResourceManager(); // deregistration of adapter factories deregisterAdapterFactories(); AdapterFactoryRegistry.clear(); // Keep the ThemeManager instance alive to speed up the TestSuite, // but reset it if any custom themes have been registered ThemeManager themeManager = ThemeManager.getInstance(); if( themeManager.getRegisteredThemeIds().length != 1 ) { ThemeManager.resetInstance(); } // clear Graphics resources ResourceFactory.clear(); // remove all registered entry points String[] entryPoints = EntryPointManager.getEntryPoints(); for( int i = 0; i < entryPoints.length; i++ ) { EntryPointManager.deregister( entryPoints[ i ] ); } // standard teardown HttpSession session = ContextProvider.getRequest().getSession(); ContextProvider.disposeContext(); session.invalidate(); clearSingletons(); System.getProperties().remove( IInitialization.PARAM_LIFE_CYCLE ); AbstractBranding[] all = BrandingManager.getAll(); for( int i = 0; i < all.length; i++ ) { BrandingManager.deregister( all[ i ] ); } LifeCycleFactory.destroy(); PhaseListenerRegistry.clear(); } public static void clearSingletons() { setPrivateField( ResourceManagerImpl.class, null, "_instance", null ); setPrivateField( LifeCycleFactory.class, null, "globalLifeCycle", null ); setPrivateField( SettingStoreManager.class, null, "factory", null ); } public static void createContext( final boolean fake ) throws IOException, FactoryConfigurationError, ParserConfigurationException, SAXException { if( fake ) { setPrivateField( ResourceManagerImpl.class, null, "_instance", new TestResourceManager() ); } else { createContextWithoutResourceManager(); String webAppBase = CONTEXT_DIR.toString(); String deliverFromDisk = IInitialization.RESOURCES_DELIVER_FROM_DISK; ResourceManagerImpl.createInstance( webAppBase, deliverFromDisk ); } } public static void createContextWithoutResourceManager() throws FileNotFoundException, IOException, FactoryConfigurationError, ParserConfigurationException, SAXException { CONTEXT_DIR.mkdirs(); File webInf = new File( CONTEXT_DIR, "WEB-INF" ); webInf.mkdirs(); File conf = new File( webInf, "conf" ); conf.mkdirs(); File classes = new File( webInf, "classes" ); classes.mkdirs(); File libDir = new File( webInf, "lib" ); libDir.mkdirs(); File w4tXml = new File( conf, "W4T.xml" ); copyTestResource( "resources/w4t_fixture.xml", w4tXml ); String webAppBase = CONTEXT_DIR.toString(); EngineConfig engineConfig = new EngineConfig( webAppBase ); ConfigurationReader.setEngineConfig( engineConfig ); } public static void removeContext() { if( CONTEXT_DIR.exists() ) { delete( CONTEXT_DIR ); } } private static void delete( final File toDelete ) { if( toDelete.isDirectory() ) { File[] children = toDelete.listFiles(); for( int i = 0; i < children.length; i++ ) { delete( children[ i ] ); } } toDelete.delete(); } public static void copyTestResource( final String resourceName, final File destination ) throws FileNotFoundException, IOException { ClassLoader loader = Fixture.class.getClassLoader(); InputStream is = loader.getResourceAsStream( resourceName ); try { OutputStream out = new FileOutputStream( destination ); try { int c = is.read(); while( c != -1 ) { out.write( c ); c = is.read(); } } finally { out.close(); } } finally { is.close(); } } public static File getWebAppBase() throws Exception { File result = CONTEXT_DIR; if( !result.exists() ) { createContextWithoutResourceManager(); result = CONTEXT_DIR; } return result; } public static void fakeRequestParam( final String key, final String value ) { TestRequest request = ( TestRequest )ContextProvider.getRequest(); request.setParameter( key, value ); } public static void fakeContextProvider( final HttpServletResponse response, final HttpServletRequest request ) { ServiceContext context = new ServiceContext( request, response ); ServiceStateInfo stateInfo = new ServiceStateInfo(); context.setStateInfo( stateInfo ); ContextProvider.setContext( context ); } public static void setPrivateField( final Class clazz, final Object object, final String fieldName, final Object value ) { Field[] fields = clazz.getDeclaredFields(); Field field = null; for( int i = 0; field == null && i < fields.length; i++ ) { if( fields[ i ].getName().equals( fieldName ) ) { field = fields[ i ]; } } if ( field == null ) { Assert.fail( "Private field " + clazz.getName() + "#" + fieldName + " could not be found." ); } field.setAccessible( true ); try { field.set( object, value ); } catch( Exception e ) { e.printStackTrace(); Assert.fail( "Failed to set value of private field " + clazz.getName() + "#" + fieldName ); } } public static String getAllMarkup() { IServiceStateInfo stateInfo = ContextProvider.getStateInfo(); HtmlResponseWriter writer = stateInfo.getResponseWriter(); return getAllMarkup( writer ); } public static String getAllMarkup( final HtmlResponseWriter writer ) { StringBuffer buffer = new StringBuffer(); for( int i = 0; i < writer.getBodySize(); i++ ) { buffer.append( writer.getBodyToken( i ) ); } return buffer.toString(); } public static void fakeResponseWriter() { HtmlResponseWriter writer = new HtmlResponseWriter(); IServiceStateInfo stateInfo = ContextProvider.getStateInfo(); stateInfo.setResponseWriter( writer ); } public static void fakePhase( final PhaseId phase ) { IServiceStateInfo stateInfo = ContextProvider.getStateInfo(); stateInfo.setAttribute( CurrentPhase.class.getName() + "#value", phase ); } public static void fakeContext() { TestRequest request = new TestRequest(); TestResponse response = new TestResponse(); TestSession session = new TestSession(); request.setSession( session ); ServiceContext context = new ServiceContext( request, response ); ContextProvider.setContext( context ); } public static void readDataAndProcessAction( final Display display ) { IDisplayLifeCycleAdapter displayLCA = DisplayUtil.getLCA( display ); fakePhase( PhaseId.READ_DATA ); displayLCA.readData( display ); Fixture.preserveWidgets(); fakePhase( PhaseId.PROCESS_ACTION ); displayLCA.processAction( display ); } public static void readDataAndProcessAction( final Widget widget ) { AbstractWidgetLCA widgetLCA = WidgetUtil.getLCA( widget ); fakePhase( PhaseId.READ_DATA ); widgetLCA.readData( widget ); fakePhase( PhaseId.PROCESS_ACTION ); Display display = widget.getDisplay(); IDisplayLifeCycleAdapter displayLCA = DisplayUtil.getLCA( display ); displayLCA.processAction( display ); } public static void fakeNewRequest() { HttpSession session = ContextProvider.getRequest().getSession(); TestRequest request = new TestRequest(); request.setSession( session ); TestResponse response = new TestResponse(); ServiceContext serviceContext = new ServiceContext( request, response ); serviceContext.setStateInfo( new ServiceStateInfo() ); ContextProvider.disposeContext(); ContextProvider.setContext( serviceContext ); fakeResponseWriter(); LifeCycleServiceHandler.initializeSession(); } public static void markInitialized( final Widget widget ) { Object adapter = widget.getAdapter( IWidgetAdapter.class ); WidgetAdapter widgetAdapter = ( WidgetAdapter )adapter; widgetAdapter.setInitialized( true ); } public static void markInitialized( final Display display ) { Object adapter = display.getAdapter( IWidgetAdapter.class ); WidgetAdapter widgetAdapter = ( WidgetAdapter )adapter; widgetAdapter.setInitialized( true ); } public static void preserveWidgets() { PreserveWidgetsPhaseListener listener = new PreserveWidgetsPhaseListener(); RWTLifeCycle lifeCycle = ( RWTLifeCycle )LifeCycleFactory.getLifeCycle(); PhaseEvent event = new PhaseEvent( lifeCycle, PhaseId.READ_DATA ); listener.afterPhase( event ); } public static void clearPreserved() { PreserveWidgetsPhaseListener listener = new PreserveWidgetsPhaseListener(); ILifeCycle lifeCycle = LifeCycleFactory.getLifeCycle(); PhaseEvent event = new PhaseEvent( lifeCycle, PhaseId.RENDER ); listener.afterPhase( event ); } public static void registerResourceManager() { ResourceManager.register( new TestResourceManagerFactory() ); // clear Graphics resources ResourceFactory.clear(); } public static void deregisterResourceManager() { setPrivateField( ResourceManager.class, null, "_instance", null ); setPrivateField( ResourceManager.class, null, "factory", null ); } public static void registerAdapterFactories() { AdapterManager manager = AdapterManagerImpl.getInstance(); Fixture.lifeCycleAdapterFactory = new LifeCycleAdapterFactory(); manager.registerAdapters( Fixture.lifeCycleAdapterFactory, Display.class ); manager.registerAdapters( Fixture.lifeCycleAdapterFactory, Widget.class ); } public static void deregisterAdapterFactories() { AdapterManager manager = AdapterManagerImpl.getInstance(); manager.deregisterAdapters( Fixture.lifeCycleAdapterFactory, Display.class ); manager.deregisterAdapters( Fixture.lifeCycleAdapterFactory, Widget.class ); } public static void executeLifeCycleFromServerThread() { final RWTLifeCycle lifeCycle = ( RWTLifeCycle )LifeCycleFactory.getLifeCycle(); final IUIThreadHolder threadHolder = new IUIThreadHolder() { private Thread thread = Thread.currentThread(); public void setServiceContext( ServiceContext serviceContext ) { } public void switchThread() { synchronized( getLock() ) { notifyAll(); try { wait(); } catch( InterruptedException e ) { throw new RuntimeException( e ); } } } public void updateServiceContext() { } public void terminateThread() { } public Thread getThread() { return thread; } public Object getLock() { return this; } }; ISessionStore session = ContextProvider.getSession(); session.setAttribute( RWTLifeCycle.UI_THREAD, threadHolder ); final ServiceContext context = ContextProvider.getContext(); Thread serverThread = new Thread( new Runnable() { public void run() { synchronized( threadHolder.getLock() ) { ContextProvider.setContext( context ); try { try { lifeCycle.execute(); lifeCycle.setPhaseOrder( null ); } catch( IOException e ) { throw new RuntimeException( e ); } } finally { ContextProvider.releaseContextHolder(); threadHolder.notifyAll(); } } } }, "ServerThread" ); synchronized( threadHolder.getLock() ) { serverThread.start(); try { lifeCycle.sleep(); } catch( ThreadDeath e ) { throw new RuntimeException( e ); } } while( RWTLifeCycle.getSessionDisplay().readAndDispatch() ) { } lifeCycle.sleep(); } }