001package jmri.jmrix.loconet.locomon;
002
003import jmri.InstanceManager;
004import jmri.TurnoutManager;
005import jmri.jmrix.loconet.LocoNetListener;
006import jmri.jmrix.loconet.LocoNetMessage;
007import jmri.jmrix.loconet.LocoNetSystemConnectionMemo;
008import jmri.jmrix.loconet.swing.LnPanelInterface;
009import org.slf4j.Logger;
010import org.slf4j.LoggerFactory;
011
012/**
013 * LocoNet Monitor pane displaying (and logging) LocoNet messages on a given TrafficController.
014 *
015 * @author Bob Jacobsen Copyright (C) 2001, 2008, 2010
016 */
017public class LocoMonPane extends jmri.jmrix.AbstractMonPane implements LocoNetListener, LnPanelInterface {
018
019    private String systemConnectionPrefix;
020    LocoNetSystemConnectionMemo memo;
021
022    public LocoMonPane() {
023        super();
024        // Temporarily pre-initialize the system connection prefix based on the
025        // default turnout manager's system name prefix.  This will be replaced
026        // with the correct style in #initComponents(LocoNetSystemConnectionMemo)
027        // but is needed here for Unit Testing
028        systemConnectionPrefix = InstanceManager.getDefault(TurnoutManager.class).getSystemPrefix();
029    }
030
031    @Override
032    public String getHelpTarget() {
033        return "package.jmri.jmrix.loconet.locomon.LocoMonFrame"; // NOI18N
034    }
035
036    @Override
037    public String getTitle() {
038        String uName = "";
039        if (memo != null) {
040            uName = memo.getUserName();
041            if (!"LocoNet".equals(uName)) { // NOI18N
042                uName = uName + ": ";
043            } else {
044                uName = "";
045            }
046        }
047        return uName + Bundle.getMessage("MenuItemLocoNetMonitor");
048    }
049
050    @Override
051    public void dispose() {
052        if (memo != null && memo.getLnTrafficController() != null) {
053            // disconnect from the LnTrafficController
054            memo.getLnTrafficController().removeLocoNetListener(~0, this);
055        }
056        // and unwind swing
057        super.dispose();
058    }
059
060    @Override
061    public void init() {
062    }
063
064
065    @Override
066    public void initContext(Object context) {
067        if (context instanceof LocoNetSystemConnectionMemo) {
068            initComponents((LocoNetSystemConnectionMemo) context);
069        }
070    }
071
072    @Override
073    public synchronized void initComponents(LocoNetSystemConnectionMemo memo) {
074        this.memo = memo;
075        // connect to the LnTrafficController
076        if (memo.getLnTrafficController() == null) {
077            log.error("No traffic controller is available");
078            return;
079        }
080        memo.getLnTrafficController().addLocoNetListener(~0, this);
081        systemConnectionPrefix = memo.getSystemPrefix();
082    }
083
084    @Override
085    public synchronized void message(LocoNetMessage l) { // receive a LocoNet message and log it
086        // send the raw data, to display if requested
087        String raw = l.toString();
088        log.debug("message received");
089        // format the message text, expect it to provide consistent \n after each line
090        String formatted = l.toMonitorString(systemConnectionPrefix);
091
092        // display the formatted data in the monitor pane
093        nextLine(formatted, raw);
094
095        // include LocoNet monitoring in session.log if TRACE enabled
096        if (log.isTraceEnabled()) {
097            log.trace("message: {}", formatted.substring(0, formatted.length() - 1)); // removes trailing newline
098        }
099    }
100
101    /**
102     * Get hex opcode for filtering.
103     *
104     * @param raw byte sequence
105     * @return the first byte pair
106     */
107    @Override
108    protected String getOpCodeForFilter(String raw) {
109        // note: LocoNet raw is formatted like "BB 01 00 45", so extract the correct bytes from it (BB) for comparison
110        if (raw != null && raw.length() >= 2) {
111            return raw.substring(0, 2);
112        } else {
113            return null;
114        }
115    }
116
117    private final static Logger log = LoggerFactory.getLogger(LocoMonPane.class);
118
119}