001package jmri.managers; 002 003import java.beans.PropertyChangeEvent; 004import java.util.ArrayList; 005import java.util.List; 006 007import javax.annotation.CheckForNull; 008import javax.annotation.CheckReturnValue; 009import javax.annotation.Nonnull; 010 011import jmri.*; 012import jmri.jmrix.internal.InternalAnalogIOManager; 013import jmri.jmrix.internal.InternalSystemConnectionMemo; 014 015/** 016 * Implementation of a AnalogIOManager that can serve as a proxy for multiple 017 * system-specific implementations. 018 * 019 * @author Bob Jacobsen Copyright (C) 2010, 2018 020 * @author Dave Duchamp Copyright (C) 2004 021 * @author Daniel Bergqvist Copyright (C) 2020 022 */ 023public class ProxyAnalogIOManager extends AbstractProxyManager<AnalogIO> 024 implements AnalogIOManager { 025 026 private final InternalAnalogIOManager internalAnalogIOManager; 027 private boolean muteUpdates = false; 028 private final List<Class<? extends AnalogIO>> registerBeans = new ArrayList<>(); 029 private final List<Manager<? extends NamedBean>> registerBeanManagers = new ArrayList<>(); 030 031 public ProxyAnalogIOManager() { 032 internalAnalogIOManager = new InternalAnalogIOManager(InstanceManager.getDefault( 033 InternalSystemConnectionMemo.class)); 034 addManager(internalAnalogIOManager); 035 } 036 037 @Nonnull 038 public ProxyAnalogIOManager init() { 039 // Note that not all lights in LightManager are VariableLight. 040 addBeanType(Meter.class, InstanceManager.getDefault(MeterManager.class)); 041 addBeanType(VariableLight.class, InstanceManager.getDefault(LightManager.class)); 042 return this; 043 } 044 045 @Override 046 public int getXMLOrder() { 047 return jmri.Manager.ANALOGIOS; 048 } 049 050 @Override 051 protected AbstractManager<AnalogIO> makeInternalManager() { 052 return internalAnalogIOManager; 053 } 054 055 @Override 056 @Nonnull 057 public String getBeanTypeHandled(boolean plural) { 058 return Bundle.getMessage(plural ? "BeanNameAnalogIOs" : "BeanNameAnalogIO"); 059 } 060 061 /** 062 * {@inheritDoc} 063 */ 064 @Override 065 public Class<AnalogIO> getNamedBeanClass() { 066 return AnalogIO.class; 067 } 068 069 /* {@inheritDoc} */ 070 @Override 071 @CheckReturnValue 072 @CheckForNull 073 public AnalogIO getBySystemName(@Nonnull String systemName) { 074 AnalogIO analogIO = super.getBySystemName(systemName); 075 if (analogIO == null) { 076 analogIO = initInternal().getBySystemName(systemName); 077 } 078 return analogIO; 079 } 080 081 /** {@inheritDoc} */ 082 @Override 083 @CheckForNull 084 public AnalogIO getByUserName(@Nonnull String userName) { 085 AnalogIO analogIO = super.getByUserName(userName); 086 if (analogIO == null) { 087 analogIO = initInternal().getByUserName(userName); 088 } 089 return analogIO; 090 } 091 092 @Override 093 public void propertyChange(PropertyChangeEvent e) { 094 super.propertyChange(e); 095 096 // When we add or remove the Light to the internal AnalogIO manager, 097 // we get a propertyChange for that. 098 if (muteUpdates) return; 099 100 if ("beans".equals(e.getPropertyName())) { 101 102 for (Class<? extends AnalogIO> clazz : registerBeans) { 103 // A NamedBean is added 104 if ((e.getNewValue() != null) 105 && clazz.isAssignableFrom(e.getNewValue().getClass())) { 106 Manager<AnalogIO> internalManager = initInternal(); 107 muteUpdates = true; 108 internalManager.register((AnalogIO) e.getNewValue()); 109 muteUpdates = false; 110 } 111 112 // A NamedBean is removed 113 if ((e.getOldValue() != null) 114 && clazz.isAssignableFrom(e.getOldValue().getClass())) { 115 Manager<AnalogIO> internalManager = initInternal(); 116 muteUpdates = true; 117 internalManager.deregister((AnalogIO) e.getOldValue()); 118 muteUpdates = false; 119 } 120 } 121 } 122 } 123 124 /** {@inheritDoc} */ 125 @Override 126 public void dispose() { 127 super.dispose(); 128 for (Manager<? extends NamedBean> manager : registerBeanManagers) { 129 manager.removePropertyChangeListener("beans", this); 130 } 131 } 132 133 /** 134 * Add a type of NamedBean, for example VariableLight, that should be also registred in AnalogIOManager. 135 * @param clazz the NamedBean class that should be registered in this manager 136 * @param manager the manager that managers the NamedBeans of type clazz 137 */ 138 @Override 139 public void addBeanType(Class<? extends AnalogIO> clazz, Manager<? extends NamedBean> manager) { 140 registerBeans.add(clazz); 141 manager.addPropertyChangeListener("beans", this); 142 143 // Add all the existing beans to the manager 144 Manager<AnalogIO> internalManager = initInternal(); 145 muteUpdates = true; 146 for (NamedBean bean : manager.getNamedBeanSet()) { 147 internalManager.register((AnalogIO) bean); 148 } 149 muteUpdates = false; 150 } 151 152 /** 153 * Remove a type of NamedBean, for example VariableLight, from beeing registred in AnalogIOManager. 154 * @param clazz the NamedBean class that should be registered in this manager 155 * @param manager the manager that managers the NamedBeans of type clazz 156 */ 157 @Override 158 public void removeBeanType(Class<? extends AnalogIO> clazz, Manager<? extends NamedBean> manager) { 159 manager.removePropertyChangeListener("beans", this); 160 registerBeans.remove(clazz); 161 } 162 163// private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ProxyAnalogIOManager.class); 164 165}