001package jmri.jmrix.maple; 002 003import java.util.Locale; 004import javax.annotation.Nonnull; 005import jmri.Turnout; 006import jmri.managers.AbstractTurnoutManager; 007 008/** 009 * Implement turnout manager for serial systems 010 * <p> 011 * System names are "KTnnn", where K is the user configurable system prefix, 012 * nnn is the turnout number without padding. 013 * 014 * @author Bob Jacobsen Copyright (C) 2003, 2008 015 */ 016public class SerialTurnoutManager extends AbstractTurnoutManager { 017 018 public SerialTurnoutManager(MapleSystemConnectionMemo memo) { 019 super(memo); 020 } 021 022 /** 023 * {@inheritDoc} 024 */ 025 @Override 026 @Nonnull 027 public MapleSystemConnectionMemo getMemo() { 028 return (MapleSystemConnectionMemo) memo; 029 } 030 031 /** 032 * {@inheritDoc} 033 */ 034 @Nonnull 035 @Override 036 protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException { 037 // validate the system name, and normalize it 038 String sName = SerialAddress.normalizeSystemName(systemName, getSystemPrefix()); 039 if (sName.isEmpty()) { 040 // system name is not valid 041 throw new IllegalArgumentException("Cannot create System Name from " + systemName); 042 } 043 // does this turnout already exist 044 Turnout t = getBySystemName(sName); 045 if (t != null) { 046 return t; 047 } 048 049 // check if the addressed output bit is available 050 int bitNum = SerialAddress.getBitFromSystemName(sName, getSystemPrefix()); 051 if (bitNum == 0) { 052 throw new IllegalArgumentException("Cannot get Bit from System Name " + systemName + " " + sName); 053 } 054 String conflict = SerialAddress.isOutputBitFree(bitNum, getSystemPrefix()); 055 if ((!conflict.isEmpty()) && (!conflict.equals(sName))) { 056 log.error("{} assignment conflict with {}.", sName, conflict); 057 throw new IllegalArgumentException("The output bit " + bitNum + ", is currently assigned to " + conflict + "."); 058 } 059 060 // create the turnout 061 t = new SerialTurnout(sName, userName, getMemo()); 062 063 // does system name correspond to configured hardware 064 if (!SerialAddress.validSystemNameConfig(sName, 'T', getMemo())) { 065 // system name does not correspond to configured hardware 066 log.warn("Turnout '{}' refers to an unconfigured output bit.", sName); 067 jmri.util.swing.JmriJOptionPane.showMessageDialog(null, "WARNING - The Turnout just added, " 068 + sName + ", refers to an unconfigured output bit.", "Configuration Warning", 069 jmri.util.swing.JmriJOptionPane.INFORMATION_MESSAGE); 070 } 071 return t; 072 } 073 074 @Override 075 public boolean allowMultipleAdditions(@Nonnull String systemName) { 076 return true; 077 } 078 079 /** 080 * {@inheritDoc} 081 */ 082 @Override 083 @Nonnull 084 public String validateSystemNameFormat(@Nonnull String name, @Nonnull Locale locale) { 085 return SerialAddress.validateSystemNameFormat(name, this, locale); 086 } 087 088 /** 089 * {@inheritDoc} 090 */ 091 @Override 092 public NameValidity validSystemNameFormat(@Nonnull String systemName) { 093 return (SerialAddress.validSystemNameFormat(systemName, typeLetter(), getSystemPrefix())); 094 } 095 096 /** 097 * {@inheritDoc} 098 */ 099 @Override 100 public String getEntryToolTip() { 101 return Bundle.getMessage("AddOutputEntryToolTip"); 102 } 103 104 /** 105 * Get from the user, the number of addressed bits used to control a 106 * turnout. Normally this is 1, and the default routine returns 1 107 * automatically. Turnout Managers for systems that can handle multiple 108 * control bits should override this method with one which asks the user to 109 * specify the number of control bits. If the user specifies more than one 110 * control bit, this method should check if the additional bits are 111 * available (not assigned to another object). If the bits are not 112 * available, this method should return 0 for number of control bits, after 113 * informing the user of the problem. This function is called whenever a new 114 * turnout is defined in the Turnout table. It can also be used to set up 115 * other turnout control options, such as pulsed control of turnout 116 * machines. 117 */ 118// Code below to do with having a pulsed turnout type is commented out for current Maple version 119// /** 120// * Get from the user, the type of output to be used bits to control a turnout. 121// * Normally this is 0 for 'steady state' control, and the default routine 122// * returns 0 automatically. 123// * Turnout Managers for systems that can handle pulsed control as well as 124// * steady state control should override this method with one which asks 125// * the user to specify the type of control to be used. The routine should 126// * return 0 for 'steady state' control, or n for 'pulsed' control, where n 127// * specifies the duration of the pulse (normally in seconds). 128// */ 129// public int askControlType(String systemName) { 130// // ask if user wants 'steady state' output (stall motors, e.g., Tortoises) or 131// // 'pulsed' output (some turnout controllers). 132// int iType = selectOutputType(); 133// if (iType == javax.swing.JOptionPane.CLOSED_OPTION) { 134// /* user cancelled without selecting an output type */ 135// iType = 0; 136// log.warn("User cancelled without selecting output type. Defaulting to 'steady state'."); 137// } 138// // Note: If the user selects 'pulsed', this routine defaults to 1 second. 139// return (iType); 140// } 141// /** 142// * Public method to allow user to specify one or two output bits for turnout control 143// * Note: This method returns 1 or 2 if the user selected, or 0 if the user cancelled 144// * without selecting. 145// */ 146// public int selectNumberOfControlBits() { 147// int iNum = 0; 148// iNum = javax.swing.JOptionPane.showOptionDialog(null, 149// "How many output bits should be used to control this turnout?", 150// "Turnout Question",javax.swing.JOptionPane.DEFAULT_OPTION, 151// javax.swing.JOptionPane.QUESTION_MESSAGE, 152// null, new String[] {"Use 1 bit", "Use 2 bits"}, "Use 1 bit"); 153// return iNum; 154// } 155// /** 156// * Public method to allow user to specify pulsed or steady state for two output bits 157// * for turnout control 158// * Note: This method returns 1 for steady state or 2 for pulsed if the user selected, 159// * or 0 if the user cancelled without selecting. 160// */ 161// public int selectOutputType() { 162// int iType = 0; 163// iType = javax.swing.JOptionPane.showOptionDialog(null, 164// "Should the output bit(s) be 'steady state' or 'pulsed'?", 165// "Output Bits Question",javax.swing.JOptionPane.DEFAULT_OPTION, 166// javax.swing.JOptionPane.QUESTION_MESSAGE, 167// null, new String[] {"Steady State Output", "Pulsed Output"}, "Steady State Output"); 168// return iType; 169// } 170// /** 171// * Public method to notify user when the second bit of a proposed two output bit turnout 172// * has a conflict with another assigned bit 173// */ 174// public void notifySecondBitConflict(String conflict,int bitNum) { 175// javax.swing.JOptionPane.showMessageDialog(null,"The second output bit, "+bitNum+ 176// ", is currently assigned to "+conflict+". Turnout cannot be created as "+ 177// "you specified.", "Assignment Conflict", 178// javax.swing.JOptionPane.INFORMATION_MESSAGE,null); 179// } 180 181 182 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SerialTurnoutManager.class); 183 184}