| /******************************************************************************* |
| * Copyright (c) 2011, 2012 EclipseSource and others. |
| * 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: |
| * EclipseSource - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.rap.rwt.internal.lifecycle; |
| |
| import java.io.IOException; |
| |
| import org.eclipse.rap.rwt.internal.application.ApplicationContextImpl; |
| import org.eclipse.rap.rwt.internal.service.ContextProvider; |
| import org.eclipse.rap.rwt.internal.service.ServiceContext; |
| import org.eclipse.rap.rwt.internal.service.UISessionImpl; |
| import org.eclipse.rap.rwt.lifecycle.PhaseId; |
| import org.eclipse.rap.rwt.lifecycle.PhaseListener; |
| import org.eclipse.rap.rwt.service.UISession; |
| import org.eclipse.swt.internal.widgets.IDisplayAdapter; |
| import org.eclipse.swt.widgets.Display; |
| |
| |
| public class SimpleLifeCycle extends LifeCycle { |
| |
| private final ApplicationContextImpl applicationContext; |
| private final PhaseListenerManager phaseListenerManager; |
| private final IPhase[] phases; |
| |
| public SimpleLifeCycle( ApplicationContextImpl applicationContext ) { |
| super( applicationContext ); |
| this.applicationContext = applicationContext; |
| this.phaseListenerManager = new PhaseListenerManager( this ); |
| this.phases = new IPhase[] { |
| new PrepareUIRoot( applicationContext ), |
| new ReadData(), |
| new ProcessAction(), |
| new Render() |
| }; |
| } |
| |
| @Override |
| public void execute() throws IOException { |
| installSessionShutdownAdapter(); |
| UISession uiSession = ContextProvider.getUISession(); |
| attachThread( LifeCycleUtil.getSessionDisplay(), uiSession ); |
| try { |
| PhaseExecutor phaseExecutor = new SessionDisplayPhaseExecutor( phaseListenerManager, phases ); |
| phaseExecutor.execute( PhaseId.PREPARE_UI_ROOT ); |
| } finally { |
| detachThread( LifeCycleUtil.getSessionDisplay(), uiSession ); |
| } |
| } |
| |
| @Override |
| public void requestThreadExec( Runnable runnable ) { |
| runnable.run(); |
| } |
| |
| @Override |
| public void addPhaseListener( PhaseListener phaseListener ) { |
| phaseListenerManager.addPhaseListener( phaseListener ); |
| } |
| |
| @Override |
| public void removePhaseListener( PhaseListener phaseListener ) { |
| phaseListenerManager.removePhaseListener( phaseListener ); |
| } |
| |
| @Override |
| public void sleep() { |
| String msg = "Display#sleep() not supported in current operation mode."; |
| throw new UnsupportedOperationException( msg ); |
| } |
| |
| private void installSessionShutdownAdapter() { |
| UISessionImpl uiSession = ( UISessionImpl )ContextProvider.getUISession(); |
| if( uiSession.getShutdownAdapter() == null ) { |
| uiSession.setShutdownAdapter( new SimpleSessionShutdownAdapter( applicationContext ) ); |
| } |
| } |
| |
| private static void attachThread( Display display, UISession uiSession ) { |
| if( display != null ) { |
| IDisplayAdapter displayAdapter = display.getAdapter( IDisplayAdapter.class ); |
| displayAdapter.attachThread(); |
| } |
| IUIThreadHolder uiThreadHolder = new SimpleUIThreadHolder( Thread.currentThread() ); |
| LifeCycleUtil.setUIThread( uiSession, uiThreadHolder ); |
| } |
| |
| private static void detachThread( Display display, UISession uiSession ) { |
| if( display != null ) { |
| IDisplayAdapter displayAdapter = display.getAdapter( IDisplayAdapter.class ); |
| displayAdapter.detachThread(); |
| } |
| LifeCycleUtil.setUIThread( uiSession, null ); |
| } |
| |
| private static class SessionDisplayPhaseExecutor extends PhaseExecutor { |
| |
| SessionDisplayPhaseExecutor( PhaseListenerManager phaseListenerManager, IPhase[] phases ) { |
| super( phaseListenerManager, phases ); |
| } |
| |
| @Override |
| Display getDisplay() { |
| return LifeCycleUtil.getSessionDisplay(); |
| } |
| } |
| |
| private static class SimpleUIThreadHolder implements IUIThreadHolder { |
| private final Thread thread; |
| |
| public SimpleUIThreadHolder( Thread thread ) { |
| this.thread = thread; |
| } |
| |
| public void updateServiceContext() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void terminateThread() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void switchThread() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void setServiceContext( ServiceContext serviceContext ) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public Thread getThread() { |
| return thread; |
| } |
| |
| public Object getLock() { |
| throw new UnsupportedOperationException(); |
| } |
| } |
| |
| private static class SimpleSessionShutdownAdapter implements ISessionShutdownAdapter { |
| private final ApplicationContextImpl applicationContext; |
| private Runnable shutdownCallback; |
| private UISession uiSession; |
| |
| SimpleSessionShutdownAdapter( ApplicationContextImpl applicationContext ) { |
| this.applicationContext = applicationContext; |
| } |
| |
| public void setShutdownCallback( Runnable shutdownCallback ) { |
| this.shutdownCallback = shutdownCallback; |
| } |
| |
| public void setUISession( UISession uiSession ) { |
| this.uiSession = uiSession; |
| } |
| |
| public void interceptShutdown() { |
| final Display display = LifeCycleUtil.getSessionDisplay( uiSession ); |
| ContextUtil.runNonUIThreadWithFakeContext( uiSession, new Runnable() { |
| public void run() { |
| if( isDisplayActive( display ) && isApplicationContextActive() ) { |
| attachThread( display, uiSession ); |
| CurrentPhase.set( PhaseId.PROCESS_ACTION ); |
| display.dispose(); |
| } |
| shutdownCallback.run(); |
| } |
| } ); |
| } |
| |
| public void processShutdown() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| private static boolean isDisplayActive( Display display ) { |
| return display != null && !display.isDisposed(); |
| } |
| |
| private boolean isApplicationContextActive() { |
| return applicationContext != null && applicationContext.isActive(); |
| } |
| } |
| |
| } |