blob: 505236e4b5dc5b1ceb9056e520aaf8efc1ae0563 [file] [log] [blame]
/*******************************************************************************
* 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();
}
}
}