001package jmri.managers; 002 003import java.util.List; 004import javax.annotation.Nonnull; 005import javax.annotation.CheckForNull; 006import jmri.AddressedProgrammer; 007import jmri.AddressedProgrammerManager; 008import jmri.GlobalProgrammerManager; 009import jmri.Programmer; 010import jmri.ProgrammingMode; 011import jmri.beans.PropertyChangeSupport; 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014 015/** 016 * Provides a very basic implementation of a programmer manager by providing a 017 * union of the AddressedProgrammerManager and GlobalProgrammerManager 018 * interfaces. 019 * <p> 020 * This implementation requires a service-mode Programmer at construction time 021 * and returns that Programmer for all global programming mode requests. This 022 * implementation of AddressedProgrammerManager always returns null for Op Mode, 023 * or addressed programmer requests, indicating there is no programmer of that 024 * type. 025 * 026 * @see jmri.AddressedProgrammerManager 027 * @see jmri.GlobalProgrammerManager 028 * @author Bob Jacobsen Copyright (C) 2001, 2015, 2016 029 */ 030public class DefaultProgrammerManager extends PropertyChangeSupport implements AddressedProgrammerManager, GlobalProgrammerManager { 031 032 // For the record, these were the original numerical definitions: 033 // public static final ProgrammingMode NONE = new ProgrammingMode("NONE", 0); 034 // public static final ProgrammingMode REGISTERMODE = new ProgrammingMode("REGISTERMODE", 11); 035 // public static final ProgrammingMode PAGEMODE = new ProgrammingMode("PAGEMODE", 21); 036 // public static final ProgrammingMode DIRECTBITMODE = new ProgrammingMode("DIRECTBITMODE", 31); 037 // public static final ProgrammingMode DIRECTBYTEMODE = new ProgrammingMode("DIRECTBYTEMODE", 32); 038 // public static final ProgrammingMode ADDRESSMODE = new ProgrammingMode("ADDRESSMODE", 41); 039 // public static final ProgrammingMode OPSBYTEMODE = new ProgrammingMode("OPSBYTEMODE", 101); 040 // public static final ProgrammingMode OPSBITMODE = new ProgrammingMode("OPSBITMODE", 102); 041 // public static final ProgrammingMode OPSACCBYTEMODE = new ProgrammingMode("OPSACCBYTEMODE", 111); 042 // public static final ProgrammingMode OPSACCBITMODE = new ProgrammingMode("OPSACCBITMODE", 112); 043 // public static final ProgrammingMode OPSACCEXTBYTEMODE = new ProgrammingMode("OPSACCEXTBYTEMODE", 121); 044 // public static final ProgrammingMode OPSACCEXTBITMODE = new ProgrammingMode("OPSACCEXTBITMODE", 122); 045 private Programmer programmer; 046 047 /** 048 * Constructor when no global programmer is available. 049 */ 050 public DefaultProgrammerManager() { 051 this(null); // indicates not present 052 } 053 054 /** 055 * Constructor with a programmer. 056 * 057 * @param programmer the programmer to use; if null, acts as if no 058 * programmer is available 059 */ 060 public DefaultProgrammerManager(@CheckForNull Programmer programmer) { 061 this.programmer = programmer; 062 } 063 064 /** 065 * Constructor with a programmer and associated connection. 066 * 067 * @param programmer the programmer to use; if null, acts as if no 068 * programmer is available 069 * @param memo the associated connection 070 */ 071 public DefaultProgrammerManager(@CheckForNull Programmer programmer, @Nonnull jmri.SystemConnectionMemo memo) { 072 this(programmer); 073 this.userName = memo.getUserName(); 074 } 075 076 private String userName = "<Default>"; 077 078 /** 079 * Provides the human-readable representation for including 080 * ProgrammerManagers directly in user interface components, so it should 081 * return a user-provided name for this particular one. 082 */ 083 @Override 084 public String getUserName() { 085 return userName; 086 } 087 088 /** 089 * Provides the human-readable representation for including 090 * ProgrammerManagers directly in user interface components, so it should 091 * return a user-provided name for this particular one. 092 */ 093 @Override 094 public String toString() { 095 return getUserName(); 096 } 097 098 @Override 099 public final Programmer getGlobalProgrammer() { 100 return getConcreteGlobalProgrammer(); 101 } 102 103 /** 104 * Gain access to the Global Mode Programmer without reservation. 105 * 106 * @return null only if there isn't a Global Mode Programmer available via 107 * this Manager. 108 */ 109 @CheckForNull 110 protected Programmer getConcreteGlobalProgrammer() { 111 log.debug("return default service-mode programmer of type {}", (programmer != null ? programmer.getClass() : "(null)")); 112 return programmer; 113 } 114 115 @Override 116 public final AddressedProgrammer getAddressedProgrammer(boolean pLongAddress, int pAddress) { 117 return getConcreteAddressedProgrammer(pLongAddress, pAddress); 118 } 119 120 /** 121 * Gain access to a Addressed Mode Programmer without reservation. 122 * 123 * @param pLongAddress true if this is a long (14 bit) address, else false 124 * @param pAddress specific decoder address to use 125 * @return null only if there isn't an Ops Mode Programmer in the system 126 */ 127 @CheckForNull 128 protected AddressedProgrammer getConcreteAddressedProgrammer(boolean pLongAddress, int pAddress) { 129 return null; 130 } 131 132 @Override 133 public final Programmer reserveGlobalProgrammer() { 134 return reserveConcreteGlobalProgrammer(); 135 } 136 137 /** 138 * Gain access to the Global Mode Programmer, in the process reserving it 139 * for yourself. 140 * 141 * @return null if the existing Global Mode programmer is in use 142 */ 143 protected Programmer reserveConcreteGlobalProgrammer() { 144 return programmer; 145 } 146 147 @Override 148 public void releaseGlobalProgrammer(@Nonnull Programmer p) { 149 } 150 151 @Override 152 public final AddressedProgrammer reserveAddressedProgrammer(boolean pLongAddress, int pAddress) { 153 return reserveConcreteAddressedProgrammer(pLongAddress, pAddress); 154 } 155 156 /** 157 * Gain access to a (the) Addressed Mode Programmer, in the process 158 * reserving it for yourself. 159 * 160 * @param pLongAddress true if this is a long (14 bit) address, else false 161 * @param pAddress Specific decoder address to use 162 * @return null if the address is in use by a reserved programmer 163 */ 164 @CheckForNull 165 protected AddressedProgrammer reserveConcreteAddressedProgrammer(boolean pLongAddress, int pAddress) { 166 return null; 167 } 168 169 @Override 170 public void releaseAddressedProgrammer(@Nonnull AddressedProgrammer p) { 171 } 172 173 /** 174 * {@inheritDoc} 175 * 176 * @return always false in this implementation 177 */ 178 @Override 179 public boolean isAddressedModePossible() { 180 return false; 181 } 182 183 /** 184 * {@inheritDoc} 185 * 186 * @return always false in this implementation 187 */ 188 @Override 189 public boolean isAddressedModePossible(@Nonnull jmri.LocoAddress l) { 190 return isAddressedModePossible(); 191 } 192 193 /** 194 * {@inheritDoc} 195 * 196 * @return always false in this implementation 197 */ 198 @Override 199 public boolean isGlobalProgrammerAvailable() { 200 return true; 201 } 202 203 /** 204 * {@inheritDoc} 205 * 206 * @return a default list of programming modes that most 207 * {@link jmri.AddressedProgrammer}s make available 208 */ 209 @Override 210 public List<ProgrammingMode> getDefaultModes() { 211 List<ProgrammingMode> retval = new java.util.ArrayList<>(); 212 retval.add(ProgrammingMode.OPSBYTEMODE); 213 return retval; 214 } 215 216 public void dispose() { 217 if (programmer != null) { 218 programmer.dispose(); 219 } 220 } 221 222 private final static Logger log = LoggerFactory.getLogger(DefaultProgrammerManager.class); 223}