001package jmri.jmrit.logixng.implementation; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.Map; 006import java.util.HashMap; 007import java.util.ServiceLoader; 008 009import javax.annotation.Nonnull; 010 011import jmri.*; 012import jmri.jmrit.logixng.*; 013import jmri.util.*; 014 015/** 016 * Class providing the basic logic of the ActionManager interface. 017 * 018 * @author Dave Duchamp Copyright (C) 2007 019 * @author Daniel Bergqvist Copyright (C) 2018 020 */ 021public class DefaultAnalogActionManager extends AbstractBaseManager<MaleAnalogActionSocket> 022 implements AnalogActionManager { 023 024 private final Map<Category, List<Class<? extends Base>>> actionClassList = new HashMap<>(); 025 private MaleSocket _lastRegisteredBean; 026 027 028 public DefaultAnalogActionManager() { 029 InstanceManager.getDefault(LogixNG_Manager.class).registerManager(this); 030 031 for (AnalogActionFactory actionFactory : ServiceLoader.load(AnalogActionFactory.class)) { 032 actionFactory.init(); 033 } 034 035 for (Category category : Category.values()) { 036 actionClassList.put(category, new ArrayList<>()); 037 } 038 039 for (AnalogActionFactory actionFactory : ServiceLoader.load(AnalogActionFactory.class)) { 040 actionFactory.getClasses().forEach((entry) -> { 041// System.out.format("Add action: %s, %s%n", entry.getKey().name(), entry.getValue().getName()); 042 actionClassList.get(entry.getKey()).add(entry.getValue()); 043 }); 044 } 045 046 for (MaleAnalogActionSocketFactory maleSocketFactory : ServiceLoader.load(MaleAnalogActionSocketFactory.class)) { 047 _maleSocketFactories.add(maleSocketFactory); 048 } 049 } 050 051 /** {@inheritDoc} */ 052 @Override 053 public Class<? extends MaleSocket> getMaleSocketClass() { 054 return DefaultMaleAnalogActionSocket.class; 055 } 056 057 protected MaleAnalogActionSocket createMaleActionSocket(AnalogActionBean action) { 058 MaleAnalogActionSocket socket = new DefaultMaleAnalogActionSocket(this, action); 059 action.setParent(socket); 060 return socket; 061 } 062 063 /** {@inheritDoc} */ 064 @Override 065 public MaleSocket getLastRegisteredMaleSocket() { 066 return _lastRegisteredBean; 067 } 068 069 /** {@inheritDoc} */ 070 @Override 071 public MaleAnalogActionSocket registerBean(MaleAnalogActionSocket maleSocket) { 072 MaleAnalogActionSocket bean = super.registerBean(maleSocket); 073 _lastRegisteredBean = maleSocket; 074 return bean; 075 } 076 077 /** 078 * Remember a NamedBean Object created outside the manager. 079 * This method creates a MaleActionSocket for the action. 080 * 081 * @param action the bean 082 */ 083 @Override 084 public MaleAnalogActionSocket registerAction(@Nonnull AnalogActionBean action) 085 throws IllegalArgumentException { 086 087 if (action instanceof MaleAnalogActionSocket) { 088 throw new IllegalArgumentException("registerAction() cannot register a MaleAnalogActionSocket. Use the method register() instead."); 089 } 090 091 // Check if system name is valid 092 if (this.validSystemNameFormat(action.getSystemName()) != NameValidity.VALID) { 093 log.warn("SystemName {} is not in the correct format", action.getSystemName()); 094 throw new IllegalArgumentException(String.format("System name is invalid: %s", action.getSystemName())); 095 } 096 097 // Keep track of the last created auto system name 098 updateAutoNumber(action.getSystemName()); 099 100 MaleAnalogActionSocket maleSocket = createMaleActionSocket(action); 101 return registerBean(maleSocket); 102 } 103 104 @Override 105 public int getXMLOrder() { 106 return LOGIXNG_ANALOG_ACTIONS; 107 } 108 109 @Override 110 public String getBeanTypeHandled() { 111 return Bundle.getMessage("BeanNameAnalogAction"); 112 } 113 114 /** {@inheritDoc} */ 115 @Override 116 public void deleteAnalogAction(MaleAnalogActionSocket x) { 117 // delete the MaleAnalogActionSocket 118 deregister(x); 119 x.dispose(); 120 } 121 122 @Override 123 public char typeLetter() { 124 return 'Q'; 125 } 126 127 /*.* 128 * Test if parameter is a properly formatted system name. 129 * 130 * @param systemName the system name 131 * @return enum indicating current validity, which might be just as a prefix 132 *./ 133 @Override 134 public NameValidity validSystemNameFormat(String systemName) { 135 return LogixNG_Manager.validSystemNameFormat( 136 getSubSystemNamePrefix(), systemName); 137 } 138*/ 139 @Override 140 public FemaleAnalogActionSocket createFemaleSocket( 141 Base parent, FemaleSocketListener listener, String socketName) { 142 return new DefaultFemaleAnalogActionSocket(parent, listener, socketName); 143 } 144 145 @Override 146 public Map<Category, List<Class<? extends Base>>> getActionClasses() { 147 return actionClassList; 148 } 149 150 /** {@inheritDoc} */ 151 @Override 152 public String getBeanTypeHandled(boolean plural) { 153 return Bundle.getMessage(plural ? "BeanNameAnalogActions" : "BeanNameAnalogAction"); 154 } 155 156 static volatile DefaultAnalogActionManager _instance = null; 157 158 @InvokeOnGuiThread // this method is not thread safe 159 static public DefaultAnalogActionManager instance() { 160 if (!ThreadingUtil.isGUIThread()) { 161 LoggingUtil.warnOnce(log, "instance() called on wrong thread"); 162 } 163 164 if (_instance == null) { 165 _instance = new DefaultAnalogActionManager(); 166 } 167 return (_instance); 168 } 169 170 @Override 171 public Class<MaleAnalogActionSocket> getNamedBeanClass() { 172 return MaleAnalogActionSocket.class; 173 } 174 175 @Override 176 protected MaleAnalogActionSocket castBean(MaleSocket maleSocket) { 177 return (MaleAnalogActionSocket)maleSocket; 178 } 179 180 181 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultAnalogActionManager.class); 182 183}