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 * 045 * @param value the desired string value 046 * @throws jmri.JmriException general error when setting the value fails 047 */ 048 abstract protected void sendStringToLayout(@Nonnull String value) throws JmriException; 049 050 /** 051 * Set the string of this StringIO. 052 * Called from the implementation class when the layout updates this StringIO. 053 * @param newValue new value to set 054 */ 055 protected void setString(@Nonnull String newValue) { 056 Object _old = this._knownString; 057 this._knownString = newValue; 058 firePropertyChange(PROPERTY_STATE, _old, _knownString); // NOI18N 059 } 060 061 /** {@inheritDoc} */ 062 @Override 063 public void setCommandedStringValue(@Nonnull String value) throws JmriException { 064 int maxLength = getMaximumLength(); 065 if ((maxLength > 0) && (value.length() > maxLength)) { 066 if (cutLongStrings()) { 067 value = value.substring(0, maxLength); 068 } else { 069 throw new JmriException("String too long"); 070 } 071 } 072 _commandedString = value; 073 sendStringToLayout(_commandedString); 074 } 075 076 /** {@inheritDoc} */ 077 @Override 078 @Nonnull 079 public String getCommandedStringValue() { 080 return _commandedString; 081 } 082 083 /** {@inheritDoc} */ 084 @Override 085 public String getKnownStringValue() { 086 return _knownString; 087 } 088 089 /** 090 * Cut long strings instead of throwing an exception? 091 * For example, if the StringIO is a display, it could be desired to 092 * accept too long strings. 093 * On the other hand, if the StringIO is used to send a command, a too 094 * long string is an error. 095 * 096 * @return true if long strings should be cut 097 */ 098 abstract protected boolean cutLongStrings(); 099 100 /** {@inheritDoc} */ 101 @Override 102 public int getState() { 103 // A StringIO doesn't have a state 104 return NamedBean.UNKNOWN; 105 } 106 107 /** {@inheritDoc} */ 108 @Override 109 public void setState(int newState) { 110 // A StringIO doesn't have a state 111 } 112 113 /** {@inheritDoc} */ 114 @Override 115 @Nonnull 116 public String getBeanType() { 117 return Bundle.getMessage("BeanNameStringIO"); 118 } 119 120 /** 121 * {@inheritDoc} 122 * 123 * Do a string comparison. 124 */ 125 @CheckReturnValue 126 @Override 127 public int compareSystemNameSuffix(@Nonnull String suffix1, @Nonnull String suffix2, @Nonnull NamedBean n) { 128 return suffix1.compareTo(suffix2); 129 } 130 131}