001package jmri.jmris.simpleserver;
002
003import java.io.DataInputStream;
004import java.io.DataOutputStream;
005import java.io.IOException;
006import jmri.InstanceManager;
007import jmri.JmriException;
008import jmri.Reporter;
009import jmri.jmris.AbstractReporterServer;
010import jmri.jmris.JmriConnection;
011
012/**
013 * Simple Server interface between the JMRI reporter manager and a network
014 * connection
015 *
016 * @author Paul Bender Copyright (C) 2011
017 * @author Randall Wood Copyright (C) 2013
018 */
019public class SimpleReporterServer extends AbstractReporterServer {
020
021    private static final String REPORTER = "REPORTER ";
022    private DataOutputStream output;
023    private JmriConnection connection;
024
025    public SimpleReporterServer(JmriConnection connection) {
026        super();
027        this.connection = connection;
028    }
029
030    public SimpleReporterServer(DataInputStream inStream, DataOutputStream outStream) {
031        super();
032        output = outStream;
033    }
034
035
036    /*
037     * Protocol Specific Abstract Functions
038     */
039    @Override
040    public void sendReport(String reporterName, Object r) throws IOException {
041        addReporterToList(reporterName);
042        if (r != null) {
043            if (r instanceof jmri.Reportable ) {
044               this.sendMessage(REPORTER + reporterName + " " + ((jmri.Reportable)r).toReportString() + "\n");
045            } else {
046               this.sendMessage(REPORTER + reporterName + " " + r.toString() + "\n");
047            }
048        } else {
049            this.sendMessage(REPORTER + reporterName + "\n");
050        }
051    }
052
053    @Override
054    public void sendErrorStatus(String reporterName) throws IOException {
055        this.sendMessage("REPORTER ERROR\n");
056    }
057
058    @Override
059    public void parseStatus(String statusString) throws JmriException, IOException {
060        int index;
061        int index2;
062        index = statusString.indexOf(' ' ) + 1;
063        index2 = statusString.indexOf(' ', index + 1);
064        int newlinepos = statusString.indexOf('\n');
065        String reporterName = statusString.substring(index, index2>0?index2:newlinepos);
066        initReporter(reporterName);
067        // the string should be "REPORTER xxxxxx REPORTSTRING\n\r"
068        // where xxxxxx is the reporter identifier and REPORTSTRING is
069        // the report, which may contain spaces.
070        if (index2 > 0 && ( newlinepos - (index2 + 1) > 0)) {
071            setReporterReport(reporterName, statusString.substring(index2 + 1,newlinepos));
072            // setReporterReport ALSO triggers sending the status report, so 
073            // no further action is required to echo the status to the client.
074        } else {
075            // send the current status if the report
076            try {
077               Reporter reporter = InstanceManager.getDefault(jmri.ReporterManager.class).provideReporter(reporterName);
078               sendReport(reporterName, reporter.getCurrentReport());
079            } catch (IllegalArgumentException ex) {
080                log.warn("Failed to provide Reporter \"{}\" in parseStatus", reporterName);
081            }
082        }
083    }
084
085    private void sendMessage(String message) throws IOException {
086        if (this.output != null) {
087            this.output.writeBytes(message);
088        } else {
089            this.connection.sendMessage(message);
090        }
091    }
092
093    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SimpleReporterServer.class);
094}