001package jmri.managers; 002 003import java.util.ArrayList; 004 005import javax.annotation.CheckForNull; 006import javax.annotation.Nonnull; 007 008import jmri.Block; 009import jmri.InstanceManager; 010import jmri.Manager; 011import jmri.NamedBean; 012import jmri.Section; 013import jmri.SectionManager; 014import jmri.Transit; 015 016/** 017 * Implementation of a Transit Manager 018 * <p> 019 * This doesn't need an interface, since Transits are globaly implemented, 020 * instead of being system-specific. 021 * <p> 022 * Note that Transit system names must begin with system prefix and type character, 023 * usually IZ, and be followed by a string, usually, but not always, a number. This 024 * is enforced when a Transit is created. 025 * <br> 026 * <hr> 027 * This file is part of JMRI. 028 * <p> 029 * JMRI is free software; you can redistribute it and/or modify it under the 030 * terms of version 2 of the GNU General Public License as published by the Free 031 * Software Foundation. See the "COPYING" file for a copy of this license. 032 * <p> 033 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 034 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 035 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 036 * 037 * @author Dave Duchamp Copyright (C) 2008, 2011 038 */ 039public class DefaultTransitManager extends AbstractManager<Transit> implements jmri.TransitManager { 040 041 public DefaultTransitManager() { 042 super(); 043 addVetoListener(); 044 } 045 046 final void addVetoListener(){ 047 InstanceManager.getDefault(SectionManager.class).addVetoableChangeListener(this); 048 } 049 050 @Override 051 public int getXMLOrder() { 052 return Manager.TRANSITS; 053 } 054 055 @Override 056 public char typeLetter() { 057 return 'Z'; 058 } 059 060 /** 061 * Create a new Transit if the Transit does not exist. 062 * This is NOT a provide method. 063 * 064 * @param systemName the desired system name 065 * @param userName the desired user name 066 * @return a new Transit 067 * @throws NamedBean.BadNameException if a Transit with the same systemName or 068 * userName already exists, or if there is trouble creating a new 069 * Transit. 070 */ 071 @Override 072 @Nonnull 073 public Transit createNewTransit(@CheckForNull String systemName, String userName) throws NamedBean.BadNameException { 074 // check system name 075 if ((systemName == null) || (systemName.isEmpty())) { 076 throw new NamedBean.BadSystemNameException("Transit System Name cannot be empty or null.", // NOI18N 077 Bundle.getMessage("InvalidBeanSystemNameEmpty",getBeanTypeHandled(false))); 078 } 079 String sysName = systemName; 080 if (!sysName.startsWith(getSystemNamePrefix())) { 081 sysName = makeSystemName(sysName); 082 } 083 // Check that Transit does not already exist 084 Transit z; 085 if (userName != null && !userName.isEmpty()) { 086 z = getByUserName(userName); 087 if (z != null) { 088 throw new NamedBean.BadUserNameException("Transit UserName \""+userName+"\" Already Exists.", // NOI18N 089 Bundle.getMessage("InvalidUserNameAlreadyExists",getBeanTypeHandled(false),sysName)); 090 } 091 } 092 z = getBySystemName(sysName); 093 if (z != null) { 094 throw new NamedBean.DuplicateSystemNameException("Transit SytemName \""+sysName+"\" Already Exists.", // NOI18N 095 Bundle.getMessage("InvalidSytemNameAlreadyExists",getBeanTypeHandled(false),sysName)); 096 } 097 // Transit does not exist, create a new Transit 098 z = new jmri.implementation.DefaultTransit(sysName, userName); 099 // save in the maps 100 register(z); 101 102 // Keep track of the last created auto system name 103 updateAutoNumber(systemName); 104 105 return z; 106 } 107 108 /** 109 * For use with User GUI, to allow the auto generation of systemNames, where 110 * the user can optionally supply a username. 111 * <p> 112 * Note: Since system names should be kept short for use in Dispatcher, 113 * automatically generated system names are in the form {@code IZnn}, where 114 * {@code nn} is the first available number. 115 * 116 * @param userName the desired user name 117 * @return a new Transit 118 * @throws NamedBean.BadNameException if userName is already associated with 119 * another Transit 120 */ 121 @Override 122 @Nonnull 123 public Transit createNewTransit(String userName) throws NamedBean.BadNameException { 124 return createNewTransit(getAutoSystemName(), userName); 125 } 126 127 /** 128 * Get an existing Transit. 129 * First looks up assuming that name is a User 130 * Name. If this fails looks up assuming that name is a System Name. 131 * If both fail, returns null. 132 * 133 * @param name User name or system name to match 134 * @return null if no match found 135 */ 136 @Override 137 @CheckForNull 138 public Transit getTransit(String name) { 139 Transit z = getByUserName(name); 140 return (z != null ? z : getBySystemName(name)); 141 } 142 143 /** 144 * Remove an existing Transit. 145 * 146 * @param z the transit to remove 147 */ 148 @Override 149 public void deleteTransit(Transit z) { 150 // delete the Transit 151 deregister(z); 152 z.dispose(); 153 } 154 155 /** 156 * Get a list of Transits which use a specified Section. 157 * 158 * @param s the section to check Transits against 159 * @return a list, possibly empty, of Transits using section s. 160 */ 161 @Override 162 @Nonnull 163 public ArrayList<Transit> getListUsingSection(Section s) { 164 ArrayList<Transit> list = new ArrayList<>(); 165 for (Transit tTransit : getNamedBeanSet()) { 166 if (tTransit.containsSection(s)) { 167 // this Transit uses the specified Section 168 list.add(tTransit); 169 } 170 } 171 return list; 172 } 173 174 @Override 175 @Nonnull 176 public ArrayList<Transit> getListUsingBlock(Block b) { 177 ArrayList<Transit> list = new ArrayList<>(); 178 for (Transit tTransit : getNamedBeanSet()) { 179 if (tTransit.containsBlock(b)) { 180 // this Transit uses the specified Section 181 list.add(tTransit); 182 } 183 } 184 return list; 185 } 186 187 @Override 188 @Nonnull 189 public ArrayList<Transit> getListEntryBlock(Block b) { 190 ArrayList<Transit> list = new ArrayList<>(); 191 for (Transit tTransit : getNamedBeanSet()) { 192 ArrayList<Block> entryBlock = tTransit.getEntryBlocksList(); 193 if (entryBlock.contains(b)) { 194 // this Transit uses the specified Section 195 list.add(tTransit); 196 } 197 } 198 return list; 199 } 200 201 @Override 202 @Nonnull 203 public String getBeanTypeHandled(boolean plural) { 204 return Bundle.getMessage(plural ? "BeanNameTransits" : "BeanNameTransit"); 205 } 206 207 /** 208 * {@inheritDoc} 209 */ 210 @Override 211 public Class<Transit> getNamedBeanClass() { 212 return Transit.class; 213 } 214 215 @Override 216 public void dispose() { 217 InstanceManager.getDefault(SectionManager.class).removeVetoableChangeListener(this); 218 super.dispose(); 219 } 220 221 // private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultTransitManager.class); 222 223}