001package jmri.jmrix.marklin; 002 003import javax.annotation.Nonnull; 004import jmri.JmriException; 005import jmri.Turnout; 006 007/** 008 * Implement turnout manager for Marklin systems. 009 * <p> 010 * System names use an optional protocol prefix followed by a 1-based address: 011 * <ul> 012 * <li>{@code MTDCC45} DCC accessory address 45</li> 013 * <li>{@code MTMM123} MM/MM2 accessory address 123</li> 014 * <li>{@code MTCAN200} raw CAN wire address 200 (vendor/club range)</li> 015 * <li>{@code MT45} legacy unprefixed, treated as DCC</li> 016 * </ul> 017 * <p> 018 * Based on work by Bob Jacobsen 019 * 020 * @author Kevin Dickerson Copyright (C) 2012 021 * @author Ralf Lang 022 */ 023public class MarklinTurnoutManager extends jmri.managers.AbstractTurnoutManager { 024 025 /** Regex for the address portion after stripping system-prefix + type letter. */ 026 private static final java.util.regex.Pattern ADDRESS_PATTERN = 027 java.util.regex.Pattern.compile("^(MM|DCC|CAN)?(\\d+)$"); 028 029 public MarklinTurnoutManager(MarklinSystemConnectionMemo memo) { 030 super(memo); 031 tc = memo.getTrafficController(); 032 } 033 034 private final MarklinTrafficController tc; 035 036 /** {@inheritDoc} */ 037 @Override 038 @Nonnull 039 public MarklinSystemConnectionMemo getMemo() { 040 return (MarklinSystemConnectionMemo) memo; 041 } 042 043 /** 044 * {@inheritDoc} 045 * <p> 046 * Accepts {@code MM123}, {@code DCC45}, {@code CAN200} or plain {@code 123} 047 * Unprefixed defaults to DCC for BC reasons. 048 * The prefix and number are passed through verbatim. 049 * The full system name becomes e.g. {@code MTDCC123}. 050 */ 051 @Override 052 @Nonnull 053 public String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) throws JmriException { 054 if (!ADDRESS_PATTERN.matcher(curAddress).matches()) { 055 throw new JmriException("Invalid Marklin turnout address '" + curAddress 056 + "'. Use MM<n>, DCC<n>, CAN<n>, or plain <n> (defaults to DCC)."); 057 } 058 return prefix + typeLetter() + curAddress; 059 } 060 061 /** {@inheritDoc} */ 062 @Override 063 public jmri.Manager.NameValidity validSystemNameFormat(@Nonnull String systemName) { 064 String addr = systemName.substring(getSystemPrefix().length() + 1); // strip e.g. "MT" 065 return ADDRESS_PATTERN.matcher(addr).matches() 066 ? jmri.Manager.NameValidity.VALID : jmri.Manager.NameValidity.INVALID; 067 } 068 069 /** {@inheritDoc} */ 070 @Override 071 @Nonnull 072 public String validateSystemNameFormat(@Nonnull String systemName, @Nonnull java.util.Locale locale) 073 throws jmri.NamedBean.BadSystemNameException { 074 systemName = validateSystemNamePrefix(systemName, locale); 075 if (validSystemNameFormat(systemName) != jmri.Manager.NameValidity.VALID) { 076 throw new jmri.NamedBean.BadSystemNameException(locale, 077 "InvalidSystemNameNotInteger", systemName, getSystemNamePrefix()); 078 } 079 return systemName; 080 } 081 082 /** {@inheritDoc} */ 083 @Override 084 @Nonnull 085 protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException { 086 Turnout t = new MarklinTurnout(systemName, getSystemPrefix(), tc); 087 t.setUserName(userName); 088 return t; 089 } 090 091 /** {@inheritDoc} */ 092 @Override 093 public String getEntryToolTip() { 094 return Bundle.getMessage("TurnoutEntryToolTip"); 095 } 096 097 /** {@inheritDoc} */ 098 @Override 099 public boolean allowMultipleAdditions(@Nonnull String systemName) { 100 return true; 101 } 102 103}