/******************************************************************************* * Copyright (c) 2010 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.protocol; import java.io.PrintWriter; import java.util.Map; /** * One {@link ProtocolMessageWriter} per request!!! */ public abstract class ProtocolMessageWriter { private PrintWriter decoratedWriter; private boolean hasMessageStarted; private boolean isFirstPayload; private String currentWidgetId; private String currentPayloadType; private boolean isPayloadOpen; private boolean isFirstPayloadValue; public ProtocolMessageWriter( final PrintWriter decoratedWriter ) { this.decoratedWriter = decoratedWriter; hasMessageStarted = false; isFirstPayload = true; } protected void write( final String s ) { handleMessageStart(); decoratedWriter.write( s ); } public void finish() { handleMessageStart(); handleEndPayload(); appendEndMessage(); decoratedWriter.flush(); } private void handleEndPayload() { if( isPayloadOpen ) { appendEndPayloadValue(); appendEndPayload(); isPayloadOpen = false; isFirstPayloadValue = true; } } protected abstract void appendEndMessage(); protected abstract void appendEndPayloadValue(); public final void appendPayload( final String widgetId, final String payloadType, final String key, final Object value ) { handleMessageStart(); if( currentWidgetId != null && widgetId.equals( currentWidgetId ) ) { addValueToSameWidgetPayload( widgetId, payloadType, key, value ); } else { createNewPayloadAndAddValue( widgetId, payloadType, key, value ); } currentPayloadType = payloadType; currentWidgetId = widgetId; decoratedWriter.flush(); } private void handleMessageStart() { if( !hasMessageStarted ) { hasMessageStarted = true; appendStartMessage(); } } public boolean isStarted() { return hasMessageStarted; } protected abstract void appendStartMessage(); private void addValueToSameWidgetPayload( final String widgetId, final String payloadType, final String key, final Object value ) { if( currentPayloadType != null && payloadType.equals( currentPayloadType ) ) { addKeyValueToCurrentPayload( widgetId, payloadType, key, value ); } else { createNewPayloadAndAddValue( widgetId, payloadType, key, value ); } } private void addKeyValueToCurrentPayload( final String widgetId, final String payloadType, final String key, final Object value ) { if( !isPayloadOpen ) { setUpPayload( widgetId ); appendPayloadType( payloadType ); isPayloadOpen = true; } handlePayloadValueSeparator(); appendPayloadValue( key, value ); } private void createNewPayloadAndAddValue( final String widgetId, final String payloadType, final Object key, final Object value ) { setUpPayload( widgetId ); appendPayloadType( payloadType ); handlePayloadValueSeparator(); appendPayloadValue( key, value ); isPayloadOpen = true; } protected abstract void appendPayloadType( final String payloadType ); private void handlePayloadValueSeparator() { if( isPayloadOpen && !isFirstPayloadValue ) { appendPayloadValueSeparator(); } isFirstPayloadValue = false; } protected abstract void appendPayloadValueSeparator(); protected abstract void appendPayloadValue( final Object key, final Object value ); public final void addConstructPayload( final String widgetId, final String parentId, final String type, final String[] styles, final Object[] arguments ) { setUpPayload( widgetId ); appendConstructPayload( widgetId, parentId, type, styles, arguments ); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendConstructPayload( final String widgetId, final String parentId, final String type, final String[] styles, final Object[] arguments ); public final void addDestroyPaylod( final String widgetId ) { setUpPayload( widgetId ); appendDestroyPayload(); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendDestroyPayload(); public final void addSychronizePayload( final String widgetId, final Map properties ) { setUpPayload( widgetId ); appendSynchronizePayload( properties ); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendSynchronizePayload( final Map properties ); public final void addMultipleSychronizePayload( final String[] widgetIds, final Map properties ) { setUpPayload( null ); appendMultipleSynchronizePayload( widgetIds, properties ); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendMultipleSynchronizePayload( final String[] widgetIds, final Map properties ); public final void addListenPayload( final String widgetId, final Map listeners ) { setUpPayload( widgetId ); appendListenPayload( listeners ); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendListenPayload( final Map listeners ); public final void addFireEventPayload( final String widgetId, final String event ) { setUpPayload( widgetId ); appendEventPayload( event ); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendEventPayload( final String event ); public final void addExecutePayload( final String widgetId, final String methodName, final Object[] arguments ) { setUpPayload( widgetId ); appendExecutePayload( methodName, arguments ); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendExecutePayload( final String methodName, final Object[] arguments ); public final void addExecuteScript( final String widgetId, final String scriptType, final String script ) { setUpPayload( widgetId ); appendExecuteScript( scriptType, script ); appendEndPayload(); decoratedWriter.flush(); } protected abstract void appendExecuteScript( final String scriptType, final String script ); private void setUpPayload( final String widgetId ) { handleEndPayload(); handleFirstPayload(); appendStartPayload( widgetId ); } private void handleFirstPayload() { if( !isFirstPayload ) { appendPayloadSeparator(); } isFirstPayload = false; } protected abstract void appendPayloadSeparator(); protected abstract void appendStartPayload( final String widgetId ); protected abstract void appendEndPayload(); }