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