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.*;
012
013/**
014 * Implementation of a MeterManager that can serve as a proxy for multiple
015 * system-specific implementations.
016 *
017 * @author  Bob Jacobsen      Copyright (C) 2010, 2018
018 * @author  Dave Duchamp      Copyright (C) 2004
019 * @author  Daniel Bergqvist  Copyright (C) 2020
020 */
021public class ProxyMeterManager extends AbstractProxyManager<Meter>
022        implements MeterManager {
023    
024    private boolean muteUpdates = false;
025    private final List<Class<? extends Meter>> registerBeans = new ArrayList<>();
026    private final List<Manager<? extends NamedBean>> registerBeanManagers = new ArrayList<>();
027
028    @Override
029    public int getXMLOrder() {
030        return jmri.Manager.METERS;
031    }
032
033    @Override
034    protected AbstractManager<Meter> makeInternalManager() {
035        return jmri.InstanceManager.getDefault(jmri.jmrix.internal.InternalSystemConnectionMemo.class).getMeterManager();
036    }
037
038    @Override
039    @Nonnull
040    public String getBeanTypeHandled(boolean plural) {
041        return Bundle.getMessage(plural ? "BeanNameMeters" : "BeanNameMeter");
042    }
043
044    /**
045     * {@inheritDoc}
046     */
047    @Override
048    public Class<Meter> getNamedBeanClass() {
049        return Meter.class;
050    }
051
052    /* {@inheritDoc} */
053    @Override
054    @CheckReturnValue
055    @CheckForNull
056    public Meter getBySystemName(@Nonnull String systemName) {
057        Meter meter = super.getBySystemName(systemName);
058        if (meter == null) {
059            meter = initInternal().getBySystemName(systemName);
060        }
061        return meter;
062    }
063
064    /** {@inheritDoc} */
065    @Override
066    @CheckForNull
067    public Meter getByUserName(@Nonnull String userName) {
068        Meter meter = super.getByUserName(userName);
069        if (meter == null) {
070            meter = initInternal().getByUserName(userName);
071        }
072        return meter;
073    }
074
075    /**
076     * Try to create a system manager.If this proxy manager is able to create
077     * a system manager, the concrete class must implement this method.
078     *
079     * @param memo the system connection memo for this connection
080     * @return the new manager or null if it's not possible to create the manager
081     */
082    @Override
083    protected Manager<Meter> createSystemManager(@Nonnull SystemConnectionMemo memo) {
084        MeterManager m = new jmri.managers.AbstractMeterManager(memo);
085        InstanceManager.setMeterManager(m);
086        return m;
087    }
088    
089    @Override
090    public void propertyChange(PropertyChangeEvent e) {
091        super.propertyChange(e);
092        
093        // When we add or remove the Light to the internal Meter manager,
094        // we get a propertyChange for that.
095        if (muteUpdates) return;
096        
097        if ("beans".equals(e.getPropertyName())) {
098            
099            for (Class<? extends Meter> clazz : registerBeans) {
100                // A NamedBean is added
101                if ((e.getNewValue() != null)
102                        && clazz.isAssignableFrom(e.getNewValue().getClass())) {
103                    Manager<Meter> internalManager = initInternal();
104                    muteUpdates = true;
105                    internalManager.register((Meter) e.getNewValue());
106                    muteUpdates = false;
107                }
108                
109                // A NamedBean is removed
110                if ((e.getOldValue() != null)
111                        && clazz.isAssignableFrom(e.getOldValue().getClass())) {
112                    Manager<Meter> internalManager = initInternal();
113                    muteUpdates = true;
114                    internalManager.deregister((Meter) e.getOldValue());
115                    muteUpdates = false;
116                }
117            }
118        }
119    }
120
121    /** {@inheritDoc} */
122    @Override
123    public void dispose() {
124        super.dispose();
125        for (Manager<? extends NamedBean> manager : registerBeanManagers) {
126            manager.removePropertyChangeListener("beans", this);
127        }
128    }
129
130//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ProxyMeterManager.class);
131
132}