/*******************************************************************************
* Copyright (c) 2002-2006 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 com.w4t.engine.service;
import java.util.List;
import java.util.Vector;
import javax.servlet.http.HttpSession;
import junit.framework.TestCase;
import org.eclipse.rwt.internal.browser.Default;
import org.eclipse.rwt.internal.browser.Ie6;
import org.eclipse.rwt.internal.service.*;
import org.eclipse.rwt.lifecycle.*;
import org.eclipse.rwt.service.ISessionStore;
import com.w4t.*;
import com.w4t.IWindowManager.IWindow;
import com.w4t.W4TFixture.*;
import com.w4t.engine.util.WindowManager;
import com.w4t.internal.adaptable.IFormAdapter;
public class LifeCycleServiceHandler_Test extends TestCase {
private final class ThreadController implements PhaseListener {
private final List order;
private final Thread worker1;
private final Thread worker2;
private static final long serialVersionUID = 1L;
private ThreadController( final List order,
final Thread worker1,
final Thread worker2 )
{
this.order = order;
this.worker1 = worker1;
this.worker2 = worker2;
}
public void beforePhase( final PhaseEvent event ) {
Thread currentThread = Thread.currentThread();
if( currentThread == worker1 ) {
try {
worker2.start();
Thread.sleep( 250 );
} catch( final InterruptedException ex ) {
throw new RuntimeException( ex );
}
}
}
public void afterPhase( final PhaseEvent event ) {
order.add( Thread.currentThread() );
}
public PhaseId getPhaseId() {
return PhaseId.RENDER;
}
}
private class Worker implements Runnable {
private ServiceContext context;
private Throwable throwable;
private final WebForm form;
private Worker( final HttpSession session, final WebForm form ) {
this.form = form;
TestRequest request = new TestRequest();
request.setSession( session );
TestResponse response = new TestResponse();
response.setOutputStream( new TestServletOutputStream() );
context = new ServiceContext( request, response );
context.setStateInfo( new ServiceStateInfo() );
}
public void run() {
try {
prepareRequest();
ServiceManager.getHandler().service();
} catch( final Throwable thr ) {
this.throwable = thr;
}
}
private void prepareRequest() {
ContextProvider.setContext( context );
W4TFixture.fakeRequestParam( RequestParams.STARTUP, null );
if( W4TContext.getBrowser().isAjaxEnabled() ) {
W4TFixture.fakeRequestParam( RequestParams.IS_AJAX_REQUEST, "true" );
} else {
W4TFixture.fakeRequestParam( RequestParams.IS_AJAX_REQUEST, "false" );
}
IWindow window = WindowManager.getInstance().findWindow( form );
String formId = form.getUniqueID();
IFormAdapter adapter = W4TFixture.getFormAdapter( form );
int requestCounter = adapter.getRequestCounter();
String reqCounterValue = String.valueOf( requestCounter - 1 );
W4TFixture.fakeFormRequestParams( reqCounterValue, window.getId(), formId );
}
}
protected void setUp() throws Exception {
W4TFixture.setUp();
W4TFixture.createContext( false );
}
protected void tearDown() throws Exception {
W4TFixture.tearDown();
W4TFixture.removeContext();
}
public void testSameFormSyncLock() throws Exception {
WebForm form = newForm();
HttpSession session = ContextProvider.getRequest().getSession();
W4TFixture.fakeBrowser( new Ie6( true, true ) );
Worker worker1 = new Worker( session, form );
final Thread thread1 = newThread( worker1, "worker1" );
Worker worker2 = new Worker( session, form );
final Thread thread2 = newThread( worker2, "worker2" );
final List executionOrder = new Vector();
PhaseListener listener
= new ThreadController( executionOrder, thread1, thread2 );
W4TContext.getLifeCycle().addPhaseListener( listener );
thread1.start();
thread1.join();
thread2.join();
assertNotNull( worker1.context );
assertNull( worker1.throwable );
assertNotNull( worker2.context );
assertNull( worker2.throwable );
assertFalse( getStateInfo( worker1 ).isExpired() );
assertTrue( getStateInfo( worker2 ).isExpired() );
assertEquals( 2, executionOrder.size() );
assertSame( executionOrder.get( 0 ), thread1 );
assertSame( executionOrder.get( 1 ), thread2 );
}
public void testDifferentFormsSyncLock() throws Exception {
WebForm form1 = newForm();
WebForm form2 = newForm();
HttpSession session = ContextProvider.getRequest().getSession();
W4TFixture.fakeBrowser( new Ie6( true, true ) );
Worker worker1 = new Worker( session, form1 );
final Thread thread1 = newThread( worker1, "worker1" );
Worker worker2 = new Worker( session, form2 );
final Thread thread2 = newThread( worker2, "worker2" );
final List executionOrder = new Vector();
PhaseListener listener
= new ThreadController( executionOrder, thread1, thread2 );
W4TContext.getLifeCycle().addPhaseListener( listener );
thread1.start();
thread1.join();
thread2.join();
assertNotNull( worker1.context );
assertNull( worker1.throwable );
assertNotNull( worker2.context );
assertNull( worker2.throwable );
assertFalse( getStateInfo( worker1 ).isExpired() );
assertFalse( getStateInfo( worker2 ).isExpired() );
assertEquals( 2, executionOrder.size() );
assertSame( executionOrder.get( 0 ), thread1 );
assertSame( executionOrder.get( 1 ), thread2 );
}
/**
* <p>Simulates a parameterless request within an existing session.</p>
* <p>Expected behaviour is to reset the session and as a consequence thereof
* render the internal browser survey.</p>
*/
public void testEmptyRequest() throws Exception {
newForm();
ISessionStore session = ContextProvider.getSession();
session.setAttribute( "test-attribute", "test-attribute-value" );
TestResponse response = ( TestResponse )ContextProvider.getResponse();
response.setOutputStream( new TestServletOutputStream() );
ServiceManager.getHandler().service();
HttpSession httpSession = ContextProvider.getRequest().getSession();
httpSession.setAttribute( SessionStoreImpl.ID_SESSION_STORE, session );
assertEquals( null, session.getAttribute( "test-attribute" ) );
String markup = W4TFixture.getAllMarkup();
assertTrue( markup.indexOf( "Startup Page" ) > -1 );
}
public void testStartupRequestInExistingSession() throws Exception {
newForm();
W4TFixture.fakeBrowser( new Default( true, true ) );
ISessionStore session = ContextProvider.getSession();
session.setAttribute( "test-attribute", "test-attribute-value" );
TestResponse response = ( TestResponse )ContextProvider.getResponse();
response.setOutputStream( new TestServletOutputStream() );
ServiceManager.getHandler().service();
HttpSession httpSession = ContextProvider.getRequest().getSession();
httpSession.setAttribute( SessionStoreImpl.ID_SESSION_STORE, session );
assertEquals( null, session.getAttribute( "test-attribute" ) );
String markup = W4TFixture.getAllMarkup();
assertTrue( markup.indexOf( "Startup Page" ) > -1 );
}
private static IServiceStateInfo getStateInfo( final Worker worker ) {
return worker.context.getStateInfo();
}
private static WebForm newForm() {
WebForm result = W4TFixture.loadStartupForm();
WindowManager.getInstance().create( result );
return result;
}
private static Thread newThread( final Worker worker, final String name ) {
Thread result = new Thread( worker, name );
result.setDaemon( true );
return result;
}
}