001package jmri.server.json.throttle; 002 003import com.fasterxml.jackson.databind.ObjectMapper; 004import java.util.ArrayList; 005import java.util.Collection; 006import java.util.HashMap; 007import java.util.List; 008import jmri.DccLocoAddress; 009import jmri.InstanceManager; 010import jmri.InstanceManagerAutoDefault; 011import jmri.ThrottleListener; 012import jmri.ThrottleManager; 013 014/** 015 * Manager for {@link jmri.server.json.throttle.JsonThrottle} objects. A manager 016 * is needed since multiple JsonThrottle objects may be controlling the same 017 * {@link jmri.DccLocoAddress}. 018 * 019 * @author Randall Wood Copyright 2016, 2018 020 */ 021public class JsonThrottleManager implements InstanceManagerAutoDefault { 022 023 private final HashMap<DccLocoAddress, JsonThrottle> throttles = new HashMap<>(); 024 private final HashMap<JsonThrottle, ArrayList<JsonThrottleSocketService>> services = new HashMap<>(); 025 private final ObjectMapper mapper = new ObjectMapper(); 026 027 public JsonThrottleManager() { 028 // do nothing 029 } 030 031 // Synchronized throughout: notifyThrottleFound() is now deferred to the 032 // EDT (see AbstractThrottleManager), so that deferred callback and a 033 // thread handling a fresh JSON request can touch these maps at the 034 // same time. getThrottles() returns a copy since callers iterate it. 035 public synchronized Collection<JsonThrottle> getThrottles() { 036 return new ArrayList<>(this.throttles.values()); 037 } 038 039 public synchronized void put(DccLocoAddress address, JsonThrottle throttle) { 040 this.throttles.put(address, throttle); 041 } 042 043 public synchronized void put(JsonThrottle throttle, JsonThrottleSocketService service) { 044 this.services.computeIfAbsent(throttle, v -> new ArrayList<>()).add(service); 045 } 046 047 public synchronized boolean containsKey(DccLocoAddress address) { 048 return this.throttles.containsKey(address); 049 } 050 051 public synchronized JsonThrottle get(DccLocoAddress address) { 052 return this.throttles.get(address); 053 } 054 055 public synchronized void remove(DccLocoAddress address) { 056 this.throttles.remove(address); 057 } 058 059 public synchronized List<JsonThrottleSocketService> getServers(JsonThrottle throttle) { 060 return this.services.computeIfAbsent(throttle, v -> new ArrayList<>()); 061 } 062 063 public synchronized void remove(JsonThrottle throttle, JsonThrottleSocketService server) { 064 this.getServers(throttle).remove(server); 065 } 066 067 public ObjectMapper getObjectMapper() { 068 return this.mapper; 069 } 070 071 public boolean canBeLongAddress(int asInt) { 072 return InstanceManager.getDefault(ThrottleManager.class).canBeLongAddress(asInt); 073 } 074 075 public boolean canBeShortAddress(int asInt) { 076 return InstanceManager.getDefault(ThrottleManager.class).canBeShortAddress(asInt); 077 } 078 079 public boolean requestThrottle(DccLocoAddress address, ThrottleListener listener) { 080 return InstanceManager.getDefault(ThrottleManager.class).requestThrottle(address, listener, false); 081 } 082 083 public boolean requestThrottle(jmri.BasicRosterEntry rosterEntry, ThrottleListener listener) { 084 return InstanceManager.getDefault(ThrottleManager.class).requestThrottle(rosterEntry, listener, false); 085 } 086 087 // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(JsonThrottleManager.class); 088}