001package jmri.jmrit.logixng.expressions; 002 003import java.util.Locale; 004import java.util.Map; 005 006import jmri.InstanceManager; 007import jmri.JmriException; 008import jmri.jmrit.logixng.Base; 009import jmri.jmrit.logixng.Category; 010import jmri.jmrit.logixng.FemaleSocket; 011import jmri.jmrit.logixng.FemaleSocketListener; 012import jmri.jmrit.logixng.DigitalExpressionManager; 013import jmri.jmrit.logixng.FemaleDigitalExpressionSocket; 014import jmri.jmrit.logixng.MaleSocket; 015import jmri.jmrit.logixng.SocketAlreadyConnectedException; 016 017/** 018 * An Expression that negates the result of its child expression. 019 * 020 * This expression returns False if the child returns True. It returns True 021 * if the child returns False. It returns False if no child is connected. 022 * 023 * @author Daniel Bergqvist Copyright 2021 024 */ 025public class Not extends AbstractDigitalExpression implements FemaleSocketListener { 026 027 private String _socketSystemName; 028 private final FemaleDigitalExpressionSocket _socket; 029 030 public Not(String sys, String user) 031 throws BadUserNameException, BadSystemNameException { 032 033 super(sys, user); 034 035 _socket = InstanceManager.getDefault(DigitalExpressionManager.class) 036 .createFemaleSocket(this, this, Bundle.getMessage("Not_SocketName")); 037 } 038 039 @Override 040 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException { 041 DigitalExpressionManager manager = InstanceManager.getDefault(DigitalExpressionManager.class); 042 String sysName = systemNames.get(getSystemName()); 043 String userName = userNames.get(getSystemName()); 044 if (sysName == null) sysName = manager.getAutoSystemName(); 045 Not copy = new Not(sysName, userName); 046 copy.setComment(getComment()); 047 return manager.registerExpression(copy).deepCopyChildren(this, systemNames, userNames); 048 } 049 050 /** {@inheritDoc} */ 051 @Override 052 public Category getCategory() { 053 return Category.COMMON; 054 } 055 056 /** {@inheritDoc} */ 057 @Override 058 public boolean evaluate() throws JmriException { 059 return !_socket.evaluate(); 060 } 061 062 @Override 063 public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException { 064 switch (index) { 065 case 0: 066 return _socket; 067 068 default: 069 throw new IllegalArgumentException( 070 String.format("index has invalid value: %d", index)); 071 } 072 } 073 074 @Override 075 public int getChildCount() { 076 return 1; 077 } 078 079 @Override 080 public void connected(FemaleSocket socket) { 081 if (socket == _socket) { 082 _socketSystemName = socket.getConnectedSocket().getSystemName(); 083 } else { 084 throw new IllegalArgumentException("unkown socket"); 085 } 086 } 087 088 @Override 089 public void disconnected(FemaleSocket socket) { 090 if (socket == _socket) { 091 _socketSystemName = null; 092 } else { 093 throw new IllegalArgumentException("unkown socket"); 094 } 095 } 096 097 @Override 098 public String getShortDescription(Locale locale) { 099 return Bundle.getMessage(locale, "Not_Short"); 100 } 101 102 @Override 103 public String getLongDescription(Locale locale) { 104 return Bundle.getMessage(locale, "Not_Long"); 105 } 106 107 public String getSocketSystemName() { 108 return _socketSystemName; 109 } 110 111 public void setSocketSystemName(String systemName) { 112 _socketSystemName = systemName; 113 } 114 115 /** {@inheritDoc} */ 116 @Override 117 public void setup() { 118 try { 119 if ( !_socket.isConnected() 120 || !_socket.getConnectedSocket().getSystemName() 121 .equals(_socketSystemName)) { 122 123 String socketSystemName = _socketSystemName; 124 _socket.disconnect(); 125 if (socketSystemName != null) { 126 MaleSocket maleSocket = 127 InstanceManager.getDefault(DigitalExpressionManager.class) 128 .getBySystemName(socketSystemName); 129 _socket.disconnect(); 130 if (maleSocket != null) { 131 _socket.connect(maleSocket); 132 maleSocket.setup(); 133 } else { 134 log.error("cannot load digital expression {}", socketSystemName); 135 } 136 } 137 } else { 138 _socket.getConnectedSocket().setup(); 139 } 140 } catch (SocketAlreadyConnectedException ex) { 141 // This shouldn't happen and is a runtime error if it does. 142 throw new RuntimeException("socket is already connected"); 143 } 144 } 145 146 /** {@inheritDoc} */ 147 @Override 148 public void registerListenersForThisClass() { 149 // Do nothing 150 } 151 152 /** {@inheritDoc} */ 153 @Override 154 public void unregisterListenersForThisClass() { 155 // Do nothing 156 } 157 158 /** {@inheritDoc} */ 159 @Override 160 public void disposeMe() { 161 } 162 163 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Not.class); 164 165}