001package jmri.jmrix.can.cbus; 002 003import java.util.Locale; 004import javax.annotation.*; 005import jmri.*; 006import jmri.jmrix.can.CanSystemConnectionMemo; 007import jmri.managers.AbstractLightManager; 008import org.slf4j.Logger; 009import org.slf4j.LoggerFactory; 010 011/** 012 * Implement LightManager for CAN CBUS systems. 013 * <p> 014 * System names are "ML+n;-m", where M is the user configurable system prefix, n 015 * and m are the events (signed for on/off, separated by ;). 016 * <p> 017 * Lights must be explicitly created, they are not polled. 018 * 019 * @author Matthew Harris Copyright (C) 2015 020 * @author Egbert Broerse Copyright (C) 2019 021 * @since 3.11.7 022 */ 023public class CbusLightManager extends AbstractLightManager { 024 025 /** 026 * Ctor using a given system connection memo 027 * @param memo System Connection 028 */ 029 public CbusLightManager(CanSystemConnectionMemo memo) { 030 super(memo); 031 } 032 033 /** 034 * {@inheritDoc} 035 */ 036 @Override 037 @Nonnull 038 public CanSystemConnectionMemo getMemo() { 039 return (CanSystemConnectionMemo) memo; 040 } 041 042 /** 043 * Internal method to invoke the factory, after all the logic for returning 044 * an existing method has been invoked. 045 * 046 * @return never null 047 */ 048 @Nonnull 049 @Override 050 protected Light createNewLight(@Nonnull String systemName, String userName) throws IllegalArgumentException { 051 String addr; 052 // first, check validity 053 try { 054 validateSystemNameFormat(systemName); 055 addr = systemName.substring(getSystemNamePrefix().length()); 056 } catch (IllegalArgumentException e) { 057 log.error("Unable to create CbusLight, {}", e.getMessage()); 058 throw e; 059 } 060 // validate (will add "+" to unsigned int) 061 String newAddress = CbusAddress.validateSysName(addr); 062 // OK, make 063 Light l = new CbusLight(getSystemPrefix(), newAddress, getMemo().getTrafficController()); 064 l.setUserName(userName); 065 return l; 066 } 067 068 /** 069 * {@inheritDoc} 070 */ 071 @Override 072 public boolean allowMultipleAdditions(@Nonnull String systemName) { 073 return true; 074 } 075 076 /** 077 * {@inheritDoc} 078 */ 079 @Override 080 @Nonnull 081 public String validateSystemNameFormat(@Nonnull String name, @Nonnull Locale locale) { 082 validateSystemNamePrefix(name, locale); 083 try { 084 CbusAddress.validateSysName(name.substring(getSystemNamePrefix().length())); 085 } catch (IllegalArgumentException ex) { 086 throw new jmri.NamedBean.BadSystemNameException(locale, "InvalidSystemNameCustom", ex.getMessage()); 087 } 088 return name; 089 } 090 091 /** 092 * {@inheritDoc} 093 */ 094 @Override 095 public NameValidity validSystemNameFormat(@Nonnull String systemName) { 096 String addr; 097 try { 098 addr = systemName.substring(getSystemPrefix().length() + 1); // get only the address part 099 CbusAddress.validateSysName(addr); 100 } catch (StringIndexOutOfBoundsException | IllegalArgumentException e) { 101 return NameValidity.INVALID; 102 } 103 return NameValidity.VALID; 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 @Override 110 public String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) throws jmri.JmriException { 111 try { 112 return prefix + typeLetter() + CbusAddress.validateSysName(curAddress); 113 } catch (IllegalArgumentException e) { 114 throw new jmri.JmriException(e.getMessage()); 115 } 116 } 117 118 /** 119 * {@inheritDoc} 120 */ 121 @Override 122 public boolean validSystemNameConfig(@Nonnull String systemName) { 123 return validSystemNameFormat(systemName) == NameValidity.VALID; 124 } 125 126 @Override 127 @Nonnull 128 @CheckReturnValue 129 public String getNextValidSystemName(@Nonnull NamedBean currentBean) throws JmriException { 130 if (!allowMultipleAdditions(currentBean.getSystemName())) throw new UnsupportedOperationException("Not supported"); 131 132 String currentName = currentBean.getSystemName(); 133 String suffix = Manager.getSystemSuffix(currentName); 134 String type = Manager.getTypeLetter(currentName); 135 String prefix = Manager.getSystemPrefix(currentName); 136 137 String nextName = CbusAddress.getIncrement(suffix); 138 139 if (nextName==null) { 140 throw new JmriException("No existing number found when incrementing " + currentName); 141 } 142 return prefix+type+nextName; 143 144 } 145 146 /** 147 * {@inheritDoc} 148 */ 149 @Override 150 public String getEntryToolTip() { 151 return Bundle.getMessage("AddCbusLightEntryToolTip"); 152 } 153 154 private static final Logger log = LoggerFactory.getLogger(CbusLightManager.class); 155 156}