001package jmri.implementation;
002
003import java.util.ArrayList;
004import java.util.HashMap;
005import jmri.Consist;
006import jmri.ConsistListListener;
007import jmri.ConsistListener;
008import jmri.ConsistManager;
009import jmri.LocoAddress;
010
011/**
012 * An Abstract Consist Manager on top of which system specific consist managers
013 * can be built.
014 *
015 * @author Paul Bender Copyright (C) 2004
016 * @author Randall Wood Copyright (C) 2013
017 */
018public abstract class AbstractConsistManager implements ConsistManager {
019
020    protected HashMap<LocoAddress, Consist> consistTable = null;
021    private ArrayList<ConsistListListener> changeListeners = null;
022
023    public AbstractConsistManager() {
024        consistTable = new HashMap<>();
025        changeListeners = new ArrayList<>();
026    }
027
028    /**
029     * Find a Consist with this consist address, and return it.
030     */
031    @Override
032    public Consist getConsist(LocoAddress address) {
033        if (consistTable.containsKey(address)) {
034            return (consistTable.get(address));
035        } else {
036            return (addConsist(address));
037        }
038    }
039
040    /**
041     * Add a new Consist with the given address.
042     *
043     * @param address consist address
044     * @return a consist at address; this will be the existing consist if a
045     *         consist is already known to exist at address
046     */
047    protected abstract  Consist addConsist(LocoAddress address);
048
049    // remove the old Consist
050    @Override
051    public void delConsist(LocoAddress address) {
052        consistTable.get(address).dispose();
053        consistTable.remove(address);
054        notifyConsistListChanged();
055    }
056
057    /**
058     * Return the list of consists we know about.
059     */
060    @Override
061    public ArrayList<LocoAddress> getConsistList() {
062        return new ArrayList<>(consistTable.keySet());
063    }
064
065    @Override
066    public String decodeErrorCode(int errorCode) {
067        StringBuilder buffer = new StringBuilder("");
068        if ((errorCode & ConsistListener.NotImplemented) != 0) {
069            buffer.append("Not Implemented ");
070        }
071        if ((errorCode & ConsistListener.OPERATION_SUCCESS) != 0) {
072            buffer.append("Operation Completed Successfully ");
073        }
074        if ((errorCode & ConsistListener.CONSIST_ERROR) != 0) {
075            buffer.append("Consist Error ");
076        }
077        if ((errorCode & ConsistListener.LOCO_NOT_OPERATED) != 0) {
078            buffer.append("Address not controled by this device.");
079        }
080        if ((errorCode & ConsistListener.ALREADY_CONSISTED) != 0) {
081            buffer.append("Locomotive already consisted");
082        }
083        if ((errorCode & ConsistListener.NOT_CONSISTED) != 0) {
084            buffer.append("Locomotive Not Consisted ");
085        }
086        if ((errorCode & ConsistListener.NONZERO_SPEED) != 0) {
087            buffer.append("Speed Not Zero ");
088        }
089        if ((errorCode & ConsistListener.NOT_CONSIST_ADDR) != 0) {
090            buffer.append("Address Not Conist Address ");
091        }
092        if ((errorCode & ConsistListener.DELETE_ERROR) != 0) {
093            buffer.append("Delete Error ");
094        }
095        if ((errorCode & ConsistListener.STACK_FULL) != 0) {
096            buffer.append("Stack Full ");
097        }
098
099        String retval = buffer.toString();
100        if (retval.equals("")) {
101            return "Unknown Status Code: " + errorCode;
102        } else {
103            return retval;
104        }
105    }
106
107    @Override
108    public void requestUpdateFromLayout() {
109    }
110
111    /**
112     * Allow a request for consist updates from the layout.
113     *
114     * If not overridden by a concrete subclass, this method always returns
115     * true.
116     *
117     * @return true if the request can be made, false if not
118     */
119    protected boolean shouldRequestUpdateFromLayout() {
120        return true;
121    }
122
123    /*
124     * register a ConsistListListener object with this Consist
125     * Manager
126     * @param listener a Consist List Listener object.
127     */
128    @Override
129    public void addConsistListListener(ConsistListListener l) {
130        changeListeners.add(l);
131    }
132
133    /*
134     * remove a ConsistListListener object with this Consist
135     * Manager
136     * @param listener a Consist List Listener object.
137     */
138    @Override
139    public void removeConsistListListener(ConsistListListener l) {
140        changeListeners.remove(l);
141    }
142
143    /*
144     * Notify the registered Consist List Listener objects that the
145     * Consist List has changed.
146     */
147    @Override
148    public void notifyConsistListChanged() {
149        for (ConsistListListener l : changeListeners) {
150            l.notifyConsistListChanged();
151        }
152    }
153
154}