/**
** Copyright (C) SAS Institute, All rights reserved.
** General Public License: http://www.opensource.org/licenses/gpl-license.php
**/
package com.jayway.android.robotium.remotecontrol.solo;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.InvalidObjectException;
import java.util.Properties;
import org.safs.sockets.AbstractProtocolRunner;
import org.safs.sockets.SocketProtocolListener;
import org.safs.sockets.android.DroidSocketProtocol;
public class SoloRemoteControlRunner extends AbstractProtocolRunner implements SocketProtocolListener{
/**
* a convenient wrapper to {@link AbstractProtocolRunner#protocolserver}
* we should use this field instead of {@link AbstractProtocolRunner#protocolserver}
*/
public DroidSocketProtocol droidprotocolserver = null;
private SoloRemoteControlRunner() {
protocolserver = droidprotocolserver = new DroidSocketProtocol(this);
}
public SoloRemoteControlRunner(SocketProtocolListener listener){
this();
setListenerName(listener.getListenerName());
addListener(listener);
}
@Override
public void processProtocolMessage(String message) {
int sepindex = -1;
String lcprefix;
// route message to appropriate listener callbacks
if(message != null && message.length() > 0){
sepindex = message.indexOf(Message.msg_sep);
if(sepindex < 1){
if(message.equalsIgnoreCase(Message.msg_connected)){
onReceiveConnection();
}else
if(message.equalsIgnoreCase(Message.msg_ready)){
onReceiveReady();
}else
if(message.equalsIgnoreCase(Message.msg_running)){
onReceiveRunning();
}else{
//unknown message
onReceiveMessage(message);
}
}else{
try{
lcprefix = message.substring(0, sepindex).toLowerCase();
if(lcprefix.equals(Message.msg_debug)){
onReceiveDebug(message.substring(sepindex + 1));
}else
if(lcprefix.equals(Message.msg_exception)){
onReceiveException(message.substring(sepindex + 1));
}else
if(lcprefix.equals(Message.msg_result)){
String tempmsg = message.substring(sepindex +1);
String rcmsg = null;
String infomsg = null;
// "-1" or
// "-1:statusinfo"
sepindex = tempmsg.indexOf(Message.msg_sep);
if(sepindex < 1){
rcmsg = tempmsg.trim();
}
else{
rcmsg = tempmsg.substring(0, sepindex);
try{ infomsg = tempmsg.substring(sepindex+1);}
catch(Exception x){infomsg="";}
}
int rc = -99;
try{ rc = Integer.parseInt(rcmsg); }
catch(NumberFormatException x){
debug("Received immproperly formatted Result code: "+ rcmsg);
onReceiveMessage(message);
}
onReceiveResult(rc, infomsg);
}else
if(lcprefix.equals(Message.msg_resultprops)){
Properties props = new Properties();
try{
props.load(new CharArrayReader(message.substring(sepindex + 1).toCharArray()));
onReceiveResultProperties(props);
}catch(Exception x){
debug("Error loading results Properties: "+
x.getClass().getSimpleName()+", "+ x.getMessage());
onReceiveMessage(message);
}
}else
if(lcprefix.equals(Message.msg_remoteshutdown)){
String tempmsg = message.substring(sepindex +1);
int rc = -99;
try{ rc = Integer.parseInt(tempmsg); }
catch(NumberFormatException x){
debug("Received immproperly formatted Remote Shutdown cause: "+ tempmsg);
onReceiveMessage(message);
}
onReceiveRemoteShutdown(rc);
//shutdownThread(); // ???
}else
if(lcprefix.equals(Message.msg_shutdown)){
String tempmsg = message.substring(sepindex +1);
int rc = -99;
try{ rc = Integer.parseInt(tempmsg); }
catch(NumberFormatException x){
debug("Received immproperly formatted Shutdown cause: "+ tempmsg);
onReceiveMessage(message);
}
onReceiveLocalShutdown(rc);
//shutdownThread(); // ???
}else
if(lcprefix.equals(Message.msg_message)){
onReceiveMessage(message.substring(sepindex +1));
}else{
// unknown message type
onReceiveMessage(message);
}
}catch(Exception x){// unknown or malformed message
// unknown message type
onReceiveMessage(message);
}
}
}
}
public void onReceiveReady() {
boolean sent = false;
for(int n = 0; n < runnerlisteners.size(); n++){
try{
((SocketProtocolListener)runnerlisteners.get(n)).onReceiveReady();
sent = true;
}catch(ClassCastException e){}
}
if(!sent) System.out.println("Received a remote Ready signal.");
}
public void onReceiveRunning() {
boolean sent = false;
for(int n = 0; n < runnerlisteners.size(); n++){
try{
((SocketProtocolListener)runnerlisteners.get(n)).onReceiveRunning();
sent = true;
}catch(ClassCastException e){}
}
if(!sent) System.out.println("Received a remote Running signal.");
}
public void onReceiveResult(int rc, String info) {
boolean sent = false;
for(int n = 0; n < runnerlisteners.size(); n++){
try{
((SocketProtocolListener)runnerlisteners.get(n)).onReceiveResult(rc, info);
sent = true;
}catch(ClassCastException e){}
}
if(!sent) System.out.println("Received a remote Result: "+ rc +", "+ info);
}
public void onReceiveResultProperties(Properties props) {
boolean sent = false;
for(int n = 0; n < runnerlisteners.size(); n++){
try{
((SocketProtocolListener)runnerlisteners.get(n)).onReceiveResultProperties(props);
sent = true;
}catch(ClassCastException e){}
}
if(!sent) System.out.println("Received a remote Result Properties: "+ props.toString());
}
public void onReceiveMessage(String message) {
boolean sent = false;
for(int n = 0; n < runnerlisteners.size(); n++){
try{
((SocketProtocolListener)runnerlisteners.get(n)).onReceiveMessage(message);
sent = true;
}catch(ClassCastException e){}
}
if(!sent) System.out.println("Received a remote Message: "+ message);
}
public void onReceiveException(String message) {
boolean sent = false;
for(int n = 0; n < runnerlisteners.size(); n++){
try{
((SocketProtocolListener)runnerlisteners.get(n)).onReceiveException(message);
sent = true;
}catch(ClassCastException e){}
}
if(!sent) System.out.println("Received a Remote Exception: "+ message);
}
@Override
public boolean sendShutdown() {
try{ return sendProtocolMessage(Message.msg_remoteshutdown);}
catch(InvalidObjectException x){ return false;}
}
@Override
public boolean sendDispatchProps(Properties trd) {
try{
StringBuffer buffer = new StringBuffer(Message.msg_dispatchprops+ Message.msg_sep);
CharArrayWriter writer = new CharArrayWriter();
trd.store(writer, "testRecordData");
buffer.append(writer.toCharArray());
return sendProtocolMessage(buffer.toString());
}
catch(Exception x){ return false; }
}
@Override
public boolean sendDispatchFile(String filepath) {
try{ return sendProtocolMessage(Message.msg_dispatchfile+ Message.msg_sep + filepath);}
catch(InvalidObjectException x){ return false;}
}
/**
* Send the remote client and arbitrary MESSAGE content.
* <p>
* The remote client is expected to forward the message to the test app with
* the "message:" prefix stripped off. These messages are NOT part of the standard
* protocol and it is up to the local and remote code to know what to do with
* them.
* @param message
* @return true if the message was successfully sent.
*/
public boolean sendMessage(String message){
String fullmsg = Message.msg_message + Message.msg_sep;
if(message != null && message.length() > 0) fullmsg += message;
try{ return sendProtocolMessage(fullmsg);}
catch(InvalidObjectException x){ return false;}
}
}