001package jmri.implementation; 002 003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 004import java.util.List; 005import jmri.AddressedProgrammer; 006import jmri.Programmer; 007import org.jdom2.Element; 008import org.slf4j.Logger; 009import org.slf4j.LoggerFactory; 010 011/** 012 * Utility to load a specific ProgrammerFacade from an XML element. 013 * 014 * @author Bob Jacobsen Copyright (C) 2013 015 */ 016public class ProgrammerFacadeSelector { 017 018 /** 019 * Add facades specified in an XML decoder definition element to the front 020 * of a programmer. 021 * 022 * @param element Contains "capability" elements that define the Facades 023 * @param programmer Programmer implementation to decorate 024 * @param allowCache Passed to facades that optionally cache 025 * @param baseProg The original underlying programmer, less any facades 026 * @return the programmer with added facades 027 */ 028 @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST", 029 justification = "cast is checked by conditional surrounding the code block") // NOI18N 030 public static Programmer loadFacadeElements( 031 Element element, Programmer programmer, boolean allowCache, Programmer baseProg) { 032 // iterate over any facades and add them 033 List<Element> facades = element.getChildren("capability"); 034 if (log.isDebugEnabled()) { 035 log.debug("Found {} capability elements", facades.size()); 036 } 037 for (Element facade : facades) { 038 String fname = facade.getChild("name").getText(); 039 if (log.isDebugEnabled()) { 040 log.debug("Process capability facade: {}", fname); 041 } 042 043 List<Element> parameters = facade.getChildren("parameter"); 044 if (log.isDebugEnabled()) { 045 log.debug("Found {} capability parameters", facades.size()); 046 } 047 for (Element parameter : parameters) { 048 String pname = parameter.getAttributeValue("name"); 049 String pval = parameter.getText(); 050 log.debug("Found parameter name=\"{}\", value=\"{}\" ", pname, pval); 051 } 052 053 switch (fname) { 054 case "High Access via Double Index": { 055 String top = parameters.get(0).getText(); 056 String addrCVhigh = parameters.get(1).getText(); 057 String addrCVlow = parameters.get(2).getText(); 058 String valueCV = parameters.get(3).getText(); 059 String modulo = parameters.get(4).getText(); 060 jmri.implementation.AddressedHighCvProgrammerFacade pf 061 = new jmri.implementation.AddressedHighCvProgrammerFacade(programmer, top, addrCVhigh, addrCVlow, valueCV, modulo); 062 log.debug("new programmer '{}' {}", fname, pf); 063 programmer = pf; // to go around and see if there are more 064 break; 065 } 066 case "High Access via Partial Index": { 067 String top = parameters.get(0).getText(); 068 String addrCV = parameters.get(1).getText(); 069 String factor = parameters.get(2).getText(); 070 String modulo = parameters.get(3).getText(); 071 jmri.implementation.OffsetHighCvProgrammerFacade pf 072 = new jmri.implementation.OffsetHighCvProgrammerFacade(programmer, top, addrCV, factor, modulo); 073 log.debug("new programmer '{}' {}", fname, pf); 074 programmer = pf; // to go around and see if there are more 075 break; 076 } 077 case "High Access via Partial Index with Reset": { 078 String top = parameters.get(0).getText(); 079 String addrCV = parameters.get(1).getText(); 080 String factor = parameters.get(2).getText(); 081 String modulo = parameters.get(3).getText(); 082 String indicator = parameters.get(4).getText(); 083 jmri.implementation.ResettingOffsetHighCvProgrammerFacade pf 084 = new jmri.implementation.ResettingOffsetHighCvProgrammerFacade(programmer, top, addrCV, factor, modulo, indicator); 085 log.debug("new programmer '{}' {}", fname, pf); 086 programmer = pf; // to go around and see if there are more 087 break; 088 } 089 case "Indexed CV access": { 090 String PI = parameters.get(0).getText(); 091 String SI = (parameters.size() > 1) ? parameters.get(1).getText() : null; 092 boolean cvFirst = (parameters.size() > 2) ? (!parameters.get(2).getText().equals("false")) : true; 093 boolean skipDupIndexWrite = (parameters.size() > 3) ? (parameters.get(3).getText().equals("false") ? false : allowCache) : allowCache; // if not present, use default 094 jmri.implementation.MultiIndexProgrammerFacade pf 095 = new jmri.implementation.MultiIndexProgrammerFacade(programmer, PI, SI, cvFirst, skipDupIndexWrite); 096 log.debug("new programmer '{}' {}", fname, pf); 097 programmer = pf; // to go around and see if there are more 098 break; 099 } 100 case "TCS 4 CV access": { 101 jmri.implementation.TwoIndexTcsProgrammerFacade pf 102 = new jmri.implementation.TwoIndexTcsProgrammerFacade(programmer); 103 log.debug("new programmer '{}' {}", fname, pf); 104 programmer = pf; // to go around and see if there are more 105 break; 106 } 107 case "Ops Mode Accessory Programming": 108 if (AddressedProgrammer.class.isAssignableFrom(baseProg.getClass())) { // create if relevant to current mode, otherwise silently ignore 109 String addrType = "decoder"; 110 int delay = 500; 111 for (Element x : parameters) { 112 switch (x.getAttributeValue("name")) { 113 case "Address Type": 114 addrType = x.getText(); 115 break; 116 case "Delay": 117 delay = Integer.parseInt(x.getText()); 118 break; 119 default: 120 log.error("Unknown parameter \"{}\" for \"{}\"", fname, x.getText()); 121 break; 122 } 123 } 124 log.debug("\"{}\": addrType=\"{}\", delay=\"{}\", baseProg=\"{}\"", fname, addrType, delay, baseProg); 125 126 jmri.implementation.AccessoryOpsModeProgrammerFacade pf 127 = new jmri.implementation.AccessoryOpsModeProgrammerFacade(programmer, addrType, delay, (AddressedProgrammer) baseProg); 128 log.debug("new programmer '{}' {}", fname, pf); 129 programmer = pf; // to go around and see if there are more 130 } 131 break; 132 case "Ops Mode Delayed Programming": 133 if (AddressedProgrammer.class.isAssignableFrom(baseProg.getClass())) { // create if relevant to current mode, otherwise silently ignore 134 int delay = 500; 135 for (Element x : parameters) { 136 switch (x.getAttributeValue("name")) { 137 case "Delay": 138 delay = Integer.parseInt(x.getText()); 139 break; 140 default: 141 log.error("Unknown parameter \"{}\" for \"{}\"", fname, x.getText()); 142 break; 143 } 144 } 145 log.debug("\"{}\": delay=\"{}\"", fname, delay); 146 jmri.implementation.OpsModeDelayedProgrammerFacade pf 147 = new jmri.implementation.OpsModeDelayedProgrammerFacade(programmer, delay); 148 log.debug("new programmer '{}' {}", fname, pf); 149 programmer = pf; // to go around and see if there are more 150 } 151 break; 152 default: 153 log.error("Cannot create programmer capability named: \"{}\"", fname); 154 break; 155 } 156 } 157 158 return programmer; 159 } 160 161 private final static Logger log = LoggerFactory.getLogger(ProgrammerFacadeSelector.class); 162}