/******************************************************************************* * Copyright (c) 2009 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.rwt.internal.widgets; import java.io.IOException; import org.eclipse.rwt.internal.lifecycle.*; import org.eclipse.rwt.internal.service.ContextProvider; import org.eclipse.rwt.internal.service.IServiceStateInfo; import org.eclipse.rwt.lifecycle.*; import org.eclipse.swt.widgets.Display; /** * A utility class providing an interface to add Javascript to the response. * Currently, the Javascript is only added once at the current request, but it * can be extended to add the Javascript at each response. * @since 1.3 */ public class JSExecutor { private static final String JS_EXECUTOR = JSExecutor.class.getName() + "#instance"; private final Display display; private final StringBuffer code; private JSExecutor() { this( Display.getCurrent() ); } private JSExecutor( final Display display ) { this.display = display; this.code = new StringBuffer(); LifeCycleFactory.getLifeCycle().addPhaseListener( new PhaseListener() { private static final long serialVersionUID = 1L; private final StringBuffer code = JSExecutor.this.code; private final Display display = JSExecutor.this.display; public void beforePhase( final PhaseEvent event ) { // do nothing } public void afterPhase( final PhaseEvent event ) { if( display == RWTLifeCycle.getSessionDisplay() ) { IServiceStateInfo stateInfo = ContextProvider.getStateInfo(); HtmlResponseWriter writer = stateInfo.getResponseWriter(); try { writer.write( code.toString(), 0, code.length() ); } catch( IOException e ) { // TODO [rh] proper exception handling - think about adding throws // IOException to after/beforePhase as there are various places // like this throw new RuntimeException( e ); } finally { LifeCycleFactory.getLifeCycle().removePhaseListener( this ); } } } public PhaseId getPhaseId() { return PhaseId.RENDER; } } ); } private void append( final String command ) { code.append( command ); } /** * Adds some Javascript to the response stream. */ public static void executeJS( final String code ) { final IServiceStateInfo stateInfo = ContextProvider.getStateInfo(); JSExecutor jsExecutor = ( JSExecutor )stateInfo.getAttribute( JS_EXECUTOR ); if( null == jsExecutor ) { jsExecutor = new JSExecutor(); stateInfo.setAttribute( JS_EXECUTOR, jsExecutor ); } jsExecutor.append( code ); } }