001package jmri.implementation; 002 003import javax.annotation.CheckReturnValue; 004import jmri.JmriException; 005import jmri.NamedBean; 006import jmri.StringIO; 007 008import javax.annotation.Nonnull; 009 010/** 011 * Base implementation of the StringIO interface. 012 * 013 * @author Daniel Bergqvist Copyright (c) 2018 014 */ 015public abstract class AbstractStringIO extends AbstractNamedBean implements StringIO { 016 017 private String _commandedString = ""; 018 private String _knownString = ""; 019 020 /** 021 * Abstract constructor for new StringIO with system name 022 * 023 * @param systemName StringIO system name 024 */ 025 public AbstractStringIO(@Nonnull String systemName) { 026 super(systemName); 027 } 028 029 /** 030 * Abstract constructor for new StringIO with system name and user name 031 * 032 * @param systemName StringIO system name 033 * @param userName StringIO user name 034 */ 035 public AbstractStringIO(@Nonnull String systemName, String userName) { 036 super(systemName, userName); 037 } 038 039 /** 040 * Sends the string to the layout. 041 * The string [u]must not[/u] be longer than the value of getMaximumLength() 042 * unless that value is zero. Some microcomputers have little memory and 043 * it's very important that this method is never called with too long strings. 044 * <p> 045 * For systems that don't provide another form of feedback, this call is 046 * responsible for setting the known state to the new commanded state, and 047 * firing all listeners. 048 * 049 * @param value the desired string value 050 * @throws jmri.JmriException general error when setting the value fails 051 */ 052 abstract protected void sendStringToLayout(@Nonnull String value) throws JmriException; 053 054 /** 055 * Set the string of this StringIO. 056 * Called from the implementation class when the layout updates this StringIO. 057 * @param newValue new value to set 058 */ 059 protected void setString(@Nonnull String newValue) { 060 Object _old = this._knownString; 061 this._knownString = newValue; 062 firePropertyChange("KnownValue", _old, _knownString); // NOI18N 063 } 064 065 /** {@inheritDoc} */ 066 @Override 067 public void setCommandedStringValue(@Nonnull String value) throws JmriException { 068 var _old = _commandedString; 069 int maxLength = getMaximumLength(); 070 if ((maxLength > 0) && (value.length() > maxLength)) { 071 if (cutLongStrings()) { 072 value = value.substring(0, maxLength); 073 } else { 074 throw new JmriException("String too long"); 075 } 076 } 077 _commandedString = value; 078 sendStringToLayout(_commandedString); 079 firePropertyChange("CommandedValue", _old, _commandedString); // NOI18N 080 } 081 082 /** {@inheritDoc} */ 083 @Override 084 @Nonnull 085 public String getCommandedStringValue() { 086 return _commandedString; 087 } 088 089 /** {@inheritDoc} */ 090 @Override 091 public String getKnownStringValue() { 092 return _knownString; 093 } 094 095 /** 096 * Cut long strings instead of throwing an exception? 097 * For example, if the StringIO is a display, it could be desired to 098 * accept too long strings. 099 * On the other hand, if the StringIO is used to send a command, a too 100 * long string is an error. 101 * 102 * @return true if long strings should be cut 103 */ 104 abstract protected boolean cutLongStrings(); 105 106 /** {@inheritDoc} */ 107 @Override 108 public int getState() { 109 // A StringIO doesn't have a state 110 return NamedBean.UNKNOWN; 111 } 112 113 /** {@inheritDoc} */ 114 @Override 115 public void setState(int newState) { 116 // A StringIO doesn't have an integer state 117 } 118 119 /** {@inheritDoc} */ 120 @Override 121 @Nonnull 122 public String getBeanType() { 123 return Bundle.getMessage("BeanNameStringIO"); 124 } 125 126 /** 127 * {@inheritDoc} 128 * 129 * Do a string comparison. 130 */ 131 @CheckReturnValue 132 @Override 133 public int compareSystemNameSuffix(@Nonnull String suffix1, @Nonnull String suffix2, @Nonnull NamedBean n) { 134 return suffix1.compareTo(suffix2); 135 } 136 137 // private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractStringIO.class); 138 139}