001package jmri.jmrit.ussctc;
002
003import javax.annotation.Nonnull;
004import java.util.*;
005import jmri.*;
006
007/**
008 * Manages user-level logging information from Locks and Lock-like functions.
009 * Locking objects store their status as a string, which is kept for them until
010 * overwritten by a newer one.
011 * <p>
012 * This implementation stores one (if more than one) in a Memory for display.
013 *
014 * @author Bob Jacobsen Copyright (C) 2007, 2019
015 */
016public class LockLogger {
017
018    LockLogger(String name) {
019        logMemoryName = name;
020        memory = InstanceManager.getDefault(MemoryManager.class).provideMemory(logMemoryName);
021    }
022
023    /**
024     * Set the current status of some Lock
025     * @param logger The object providing status
026     * @param status The new status value, "" for "nothing of interest"
027     */
028    public void setStatus(@Nonnull Object logger, @Nonnull String status) {
029        log.debug("Object {} set \"{}\" was \"{}\"", logger.getClass(), status, statusMap.get(logger));
030        statusMap.put(logger, status);
031        // most recent always displayed if not null
032        if ( ! status.isEmpty()) {
033            log.trace("  writing status from call");
034            memory.setValue(status);
035            log(status);
036            return;
037        }
038        // see if anything else needs to be displayed
039        for (String value : statusMap.values()) {
040            if ( ! value.isEmpty() ) {
041                log.trace("   writing status from map: \"{}\"", value);
042                memory.setValue(value);
043                log(status);
044                return;
045            }
046        }
047        // should be "", but make sure
048        log.trace("   clearing status");
049        memory.setValue("");
050    }
051
052    public void clear() {
053        log.debug("LockLogger cleared from \"{}\"",
054                        memory.getValue()
055        );
056        statusMap.clear();
057        memory.setValue("");
058    }
059
060    /**
061     * Log a copy of the status. Intended to be overridden by specific LockLogger implementations.
062     * @param message The status message, all filled out
063     */
064    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value="SLF4J_FORMAT_SHOULD_BE_CONST",
065        justification="overridden by specific LockLogger implementations")
066    void log(String message) {
067        log.debug(message);
068    }
069
070    Map<Object, String> statusMap = new LinkedHashMap<>();
071
072    // static while we decide whether to access via scripts
073    final public String logMemoryName;
074    final public Memory memory;
075
076    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "SLF4J_LOGGER_SHOULD_BE_PRIVATE",
077    justification = "Findbugs got this one wrong.  The 'log' variable needs to be protected "+
078                    "because it's accessed in anonymous subclasses in the `Lock` class which override "+
079                    "the `log()` method")
080    protected final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LockLogger.class);
081}