001package jmri.managers; 002 003import java.util.ArrayList; 004import java.util.Set; 005import jmri.AddressedProgrammer; 006import jmri.AddressedProgrammerManager; 007import jmri.GlobalProgrammerManager; 008import jmri.InstanceInitializer; 009import jmri.InstanceManager; 010import jmri.Programmer; 011import jmri.ProgrammingMode; 012import jmri.beans.PropertyChangeSupport; 013import jmri.implementation.AbstractInstanceInitializer; 014import org.openide.util.lookup.ServiceProvider; 015import org.slf4j.Logger; 016import org.slf4j.LoggerFactory; 017 018/** 019 * Defers global programmer operations to the default global Programmer, and 020 * addressed programmer operations to the default AddressedProgrammer. 021 * <p> 022 * The underlying Programmer is looked up for each access to ensure that it is 023 * current. 024 * 025 * @see jmri.GlobalProgrammerManager 026 * @see jmri.AddressedProgrammerManager 027 * @author Bob Jacobsen Copyright (C) 2014 028 */ 029public class DeferringProgrammerManager extends PropertyChangeSupport implements AddressedProgrammerManager, GlobalProgrammerManager { 030 031 public DeferringProgrammerManager() { 032 } 033 034 String userName = "<Default>"; 035 036 /** 037 * Provides the human-readable representation for including 038 * ProgrammerManagers directly in user interface components, so it should 039 * return a user-provided name for this particular one. 040 */ 041 @Override 042 public String getUserName() { 043 return userName; 044 } 045 046 /** 047 * Provides the human-readable representation for including 048 * ProgrammerManagers directly in user interface components, so it should 049 * return a user-provided name for this particular one. 050 */ 051 @Override 052 public String toString() { 053 return getUserName(); 054 } 055 056 @Override 057 public Programmer getGlobalProgrammer() { 058 GlobalProgrammerManager gp = InstanceManager.getNullableDefault(GlobalProgrammerManager.class); 059 if (gp == null || this.equals(gp)) { 060 log.debug("no defaultGlobal ProgrammerManager, getGlobalProgrammer returns null"); 061 return null; 062 } 063 Programmer p = gp.getGlobalProgrammer(); 064 log.debug("getGlobalProgrammer returns default service-mode programmer of type {} from {}", 065 (p != null ? p.getClass() : "(null)"), gp.getClass()); 066 return p; 067 } 068 069 @Override 070 public Programmer reserveGlobalProgrammer() { 071 GlobalProgrammerManager gp = InstanceManager.getNullableDefault(GlobalProgrammerManager.class); 072 if (gp == null || this.equals(gp)) { 073 return null; 074 } 075 return gp.reserveGlobalProgrammer(); 076 } 077 078 @Override 079 public void releaseGlobalProgrammer(Programmer p) { 080 GlobalProgrammerManager gp = InstanceManager.getNullableDefault(GlobalProgrammerManager.class); 081 if (gp == null || this.equals(gp)) { 082 return; 083 } 084 gp.releaseGlobalProgrammer(p); 085 } 086 087 /** 088 * Allow for implementations that do not support Service mode programming 089 * 090 * @return false if there's no chance of getting one 091 */ 092 @Override 093 public boolean isGlobalProgrammerAvailable() { 094 GlobalProgrammerManager gp = InstanceManager.getNullableDefault(GlobalProgrammerManager.class); 095 if (gp == null || this.equals(gp)) { 096 return false; 097 } 098 return InstanceManager.getDefault(GlobalProgrammerManager.class).isGlobalProgrammerAvailable(); 099 } 100 101 @Override 102 public AddressedProgrammer getAddressedProgrammer(boolean pLongAddress, int pAddress) { 103 AddressedProgrammerManager ap = InstanceManager.getNullableDefault(AddressedProgrammerManager.class); 104 if (ap == null || this.equals(ap)) { 105 return null; 106 } 107 return ap.getAddressedProgrammer(pLongAddress, pAddress); 108 } 109 110 @Override 111 public AddressedProgrammer reserveAddressedProgrammer(boolean pLongAddress, int pAddress) { 112 AddressedProgrammerManager ap = InstanceManager.getNullableDefault(AddressedProgrammerManager.class); 113 if (ap == null || this.equals(ap)) { 114 return null; 115 } 116 return ap.reserveAddressedProgrammer(pLongAddress, pAddress); 117 } 118 119 @Override 120 public void releaseAddressedProgrammer(AddressedProgrammer p) { 121 AddressedProgrammerManager ap = InstanceManager.getNullableDefault(AddressedProgrammerManager.class); 122 if (ap == null || this.equals(ap)) { 123 return; 124 } 125 ap.releaseAddressedProgrammer(p); 126 } 127 128 /** 129 * Default programmer does not provide Ops Mode 130 * 131 * @return false if there's no chance of getting one 132 */ 133 @Override 134 public boolean isAddressedModePossible() { 135 AddressedProgrammerManager ap = InstanceManager.getNullableDefault(AddressedProgrammerManager.class); 136 if (ap == null || this.equals(ap)) { 137 return false; 138 } 139 return ap.isAddressedModePossible(); 140 } 141 142 /** 143 * Default programmer doesn't depend on address 144 * 145 * @return false if there's no chance of getting one 146 */ 147 @Override 148 public boolean isAddressedModePossible(jmri.LocoAddress l) { 149 return isAddressedModePossible(); 150 } 151 152 @Override 153 public java.util.List<ProgrammingMode> getDefaultModes() { 154 AddressedProgrammerManager ap = InstanceManager.getNullableDefault(AddressedProgrammerManager.class); 155 if (ap == null || this.equals(ap)) { 156 return new ArrayList<>(); 157 } 158 return InstanceManager.getDefault(AddressedProgrammerManager.class).getDefaultModes(); 159 } 160 161 @ServiceProvider(service=InstanceInitializer.class) 162 public static final class Initializer extends AbstractInstanceInitializer { 163 164 @Override 165 public <T> Object getDefault(Class<T> type) { 166 if (type == AddressedProgrammerManager.class) { 167 return new DeferringProgrammerManager(); 168 } 169 if (type == GlobalProgrammerManager.class) { 170 return new DeferringProgrammerManager(); 171 } 172 return super.getDefault(type); 173 } 174 175 @Override 176 public Set<Class<?>> getInitalizes() { 177 Set<Class<?>> set = super.getInitalizes(); 178 set.add(AddressedProgrammerManager.class); 179 set.add(GlobalProgrammerManager.class); 180 return set; 181 } 182 183 } 184 private final static Logger log = LoggerFactory.getLogger(DeferringProgrammerManager.class); 185}