You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

169 lines
3.7 KiB

package de.srsoftware.web4rail;
import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* handles SRCP commands and their replies received from the SRCP daemon
* @author Stephan Richter, SRSoftware
*
*/
public class Command {
private static final Logger LOG = LoggerFactory.getLogger(Command.class);
private String command;
private Reply reply = null;
/**
* encapsulates a reply received from the SRCP daemon
*
*/
public static class Reply{
private long secs;
private int milis;
private int code;
private String message;
/**
* parses a reply from the SRCP daemon
* @param scanner
*/
public Reply(Scanner scanner) {
String word = scanner.next();
secs = Long.parseLong(word.substring(0, word.length()-4));
milis = Integer.parseInt(word.substring(word.length()-3));
code = scanner.nextInt();
message = scanner.nextLine().trim();
LOG.info("recv {}.{} {} {}.",secs,milis,code,message);
}
/**
* creates a reply with given data
* @param code
* @param message
*/
public Reply(int code, String message) {
secs = new Date().getTime();
milis = (int) (secs % 1000);
secs /= 1000;
this.code = code;
this.message = message;
}
/**
* checks if a response has a specific code
* @param code
* @return true if the given code equals the response's code
*/
public boolean is(int code) {
return code == this.code;
}
/**
* @return true, if the response code is between 200 and 300
*/
public boolean succeeded() {
return (code > 199 && code < 300);
}
/**
* @return the message passed along with the response from the SRCP deameon
*/
public String message() {
return message;
}
@Override
public String toString() {
return "Reply("+secs+"."+milis+" / "+code+" / "+message+")";
}
}
/**
* encapsulates a command to be send to the SRCP daemon
* @param command
*/
public Command(String command) {
this.command = command;
LOG.debug("Created new Command({}).",command);
}
/**
* called, if the response indicates an error
* @param reply
*/
protected void onFailure(Reply reply) {
LOG.warn("onFailure({})",command);
}
/**
* called, when a response from the SRCP daemon is received
* @param reply
*/
public void onResponse(Reply reply) {
this.reply = reply;
if (reply.succeeded()) {
onSuccess();
} else onFailure(reply);
}
/**
* called, when the response from the SRCP daemon indicates success of the operation
*/
public void onSuccess(){
LOG.debug("onSuccess({})",command);
}
/**
* parses the reply from the SRCP daemon
* @param scanner
*/
public void readReplyFrom(Scanner scanner) {
onResponse(new Reply(scanner));
}
/**
* waits for the reply from the SRCP daemon for one second
* @return
* @throws TimeoutException
*/
public Reply reply() throws TimeoutException {
return reply(100);
}
/**
* waits for the reply from the SRCP daemon for a given timeout
* @param timeout time (in 10ms units) to wait, before a timeout is thrown
* @return
* @throws TimeoutException
*/
public Reply reply(int timeout) throws TimeoutException {
int counter = 0;
while (reply == null) try {
if (counter++ > timeout) timeout();
Thread.sleep(10);
} catch (InterruptedException e) {
LOG.warn("wait() interrupted!",e);
}
return reply;
}
/**
* generate a timeout exception
* @throws TimeoutException
*/
private void timeout() throws TimeoutException {
String msg = command;
command = null;
throw new TimeoutException("\""+msg+"\" timed out!");
}
@Override
public String toString() {
return command;
}
}