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