blob: 352529a9974c38850f1ec7f1ec7fc33345286ecc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2013 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.protocol;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.eclipse.rap.json.JsonArray;
import org.eclipse.rap.json.JsonObject;
import org.eclipse.rap.json.JsonValue;
import org.eclipse.rap.rwt.internal.util.ParamCheck;
public class ClientMessage {
public static final String PROP_HEAD = "head";
public static final String PROP_OPERATIONS = "operations";
public static final String OPERATION_SET = "set";
public static final String OPERATION_NOTIFY = "notify";
public static final String OPERATION_CALL = "call";
private final JsonObject message;
private final JsonObject head;
private final HashMap<String,List<Operation>> operationsMap;
private final List<Operation> operationsList;
public ClientMessage( JsonObject json ) {
ParamCheck.notNull( json, "json" );
message = json;
try {
head = message.get( PROP_HEAD ).asObject();
} catch( Exception exception ) {
throw new IllegalArgumentException( "Missing header object: " + json );
}
JsonArray operations;
try {
operations = message.get( PROP_OPERATIONS ).asArray();
} catch( Exception exception ) {
throw new IllegalArgumentException( "Missing operations array: " + json );
}
try {
operationsMap = new HashMap<String,List<Operation>>();
operationsList = new ArrayList<Operation>();
processOperations( operations );
} catch( UnsupportedOperationException exception ) {
throw new IllegalArgumentException( "Invalid operations array: " + json );
}
}
public JsonValue getHeader( String key ) {
return head.get( key );
}
public List<Operation> getAllOperations() {
return Collections.unmodifiableList( operationsList );
}
public List<Operation> getAllOperationsFor( String target ) {
List<Operation> operations = operationsMap.get( target );
if( operations == null ) {
return Collections.emptyList();
}
return Collections.unmodifiableList( operations );
}
public List<CallOperation> getAllCallOperationsFor( String target, String methodName ) {
List<CallOperation> result = new ArrayList<CallOperation>();
List<Operation> operations = target == null ? operationsList : operationsMap.get( target );
if( operations != null ) {
for( Operation operation : operations ) {
if( operation instanceof CallOperation ) {
CallOperation currentOperation = ( CallOperation )operation;
if( methodName == null || currentOperation.getMethodName().equals( methodName ) ) {
result.add( currentOperation );
}
}
}
}
return result;
}
public SetOperation getLastSetOperationFor( String target, String property ) {
SetOperation result = null;
List<Operation> operations = target == null ? operationsList : operationsMap.get( target );
if( operations != null ) {
for( Operation operation : operations ) {
if( operation instanceof SetOperation ) {
SetOperation currentOperation = ( SetOperation )operation;
if( property == null || operation.getPropertyNames().contains( property ) ) {
result = currentOperation;
}
}
}
}
return result;
}
public NotifyOperation getLastNotifyOperationFor( String target, String eventName ) {
NotifyOperation result = null;
List<Operation> operations = target == null ? operationsList : operationsMap.get( target );
if( operations != null ) {
for( Operation operation : operations ) {
if( operation instanceof NotifyOperation ) {
NotifyOperation currentOperation = ( NotifyOperation )operation;
if( eventName == null || currentOperation.getEventName().equals( eventName ) ) {
result = currentOperation;
}
}
}
}
return result;
}
@Override
public String toString() {
return message.toString();
}
private void processOperations( JsonArray operations ) {
for( int i = 0; i < operations.size(); i++ ) {
Operation operation = createOperation( operations.get( i ).asArray() );
appendOperation( operation );
}
}
private Operation createOperation( JsonArray data ) {
Operation result = null;
String action = getOperationAction( data );
if( action.equals( OPERATION_SET ) ) {
result = new SetOperation( data );
} else if( action.equals( OPERATION_NOTIFY ) ) {
result = new NotifyOperation( data );
} else if( action.equals( OPERATION_CALL ) ) {
result = new CallOperation( data );
} else {
throw new IllegalArgumentException( "Unknown operation action: " + action );
}
return result;
}
private void appendOperation( Operation operation ) {
String target = operation.getTarget();
List<Operation> targetOperations = operationsMap.get( target );
if( targetOperations == null ) {
targetOperations = new ArrayList<Operation>();
}
targetOperations.add( operation );
operationsMap.put( target, targetOperations );
operationsList.add( operation );
}
private String getOperationAction( JsonArray operation ) {
String result;
try {
result = operation.get( 0 ).asString();
} catch( Exception e ) {
throw new IllegalArgumentException( "Could not find action for operation " + operation );
}
return result;
}
public abstract class Operation {
private final String target;
private Operation( JsonArray operation ) {
try {
target = operation.get( 1 ).asString();
} catch( Exception e ) {
throw new IllegalArgumentException( "Invalid operation target", e );
}
}
public String getTarget() {
return target;
}
public List<String> getPropertyNames() {
return getProperties().names();
}
public JsonValue getProperty( String key ) {
return getProperties().get( key );
}
abstract public JsonObject getProperties();
}
public final class SetOperation extends Operation {
private final JsonObject properties;
private SetOperation( JsonArray operation ) {
super( operation );
try {
properties = operation.get( 2 ).asObject();
} catch( Exception e ) {
throw new IllegalArgumentException( "Properties object missing in operation", e );
}
}
@Override
public JsonObject getProperties() {
return properties;
}
}
public final class NotifyOperation extends Operation {
private final String eventName;
private final JsonObject properties;
private NotifyOperation( JsonArray operation ) {
super( operation );
try {
eventName = operation.get( 2 ).asString();
} catch( Exception e ) {
throw new IllegalArgumentException( "Event type missing in operation", e );
}
try {
properties = operation.get( 3 ).asObject();
} catch( Exception e ) {
throw new IllegalArgumentException( "Properties object missing in operation", e );
}
}
public String getEventName() {
return eventName;
}
@Override
public JsonObject getProperties() {
return properties;
}
}
public final class CallOperation extends Operation {
private final String methodName;
private final JsonObject properties;
private CallOperation( JsonArray operation ) {
super( operation );
try {
methodName = operation.get( 2 ).asString();
} catch( Exception e ) {
throw new IllegalArgumentException( "Method name missing in operation", e );
}
try {
properties = operation.get( 3 ).asObject();
} catch( Exception e ) {
throw new IllegalArgumentException( "Properties object missing in operation", e );
}
}
public String getMethodName() {
return methodName;
}
@Override
public JsonObject getProperties() {
return properties;
}
}
}