0,0 → 1,363 |
package dongfang.mkt.configuration; |
|
import java.io.File; |
import java.io.IOException; |
import java.util.ArrayList; |
import java.util.HashMap; |
import java.util.List; |
import java.util.Map; |
|
import javax.xml.parsers.DocumentBuilder; |
import javax.xml.parsers.DocumentBuilderFactory; |
import javax.xml.parsers.ParserConfigurationException; |
import javax.xml.xpath.XPath; |
import javax.xml.xpath.XPathConstants; |
import javax.xml.xpath.XPathExpressionException; |
import javax.xml.xpath.XPathFactory; |
|
import org.w3c.dom.Document; |
import org.w3c.dom.Element; |
import org.w3c.dom.NodeList; |
import org.xml.sax.SAXException; |
|
public class ConfigSet { |
public static final int NUMBER_OF_VARIABLES = 8; |
String name; |
int eepromVersion; |
|
List<Section> declaredSections = new ArrayList<Section>(); |
List<ConfigEntry> entries = new ArrayList<ConfigEntry>(); |
|
public static class Section { |
String name, title; |
List<ConfigEntry> entries = new ArrayList<ConfigEntry>(); |
|
public Section(String name, String title) { |
this.name = name; |
this.title = title; |
} |
|
public void addConfigEntry(ConfigEntry e) { |
this.entries.add(e); |
} |
|
public List<ConfigEntry> getEntries() { |
return entries; |
} |
|
public String getName() { return name; } |
public String getTitle() { return title; } |
} |
|
public static abstract class ConfigEntry { |
String name; |
|
ConfigEntry(String name) { |
this.name = name; |
} |
|
abstract int getByteCount(); |
|
abstract String toStringWithValues(); |
|
abstract void toXML(StringBuilder result); |
|
abstract int setValue(int[] data, int offset); |
|
public String getName() { |
return name; |
} |
|
public String getSection() { |
return name; |
} |
} |
|
public static class ByteEntry extends ConfigEntry { |
ByteEntry(String name, boolean isDynamic) { |
super(name); |
this.isDynamic = isDynamic; |
} |
|
boolean isDynamic; |
int value; |
|
int getByteCount() { |
return 1; |
} |
|
int getValue() { |
return value; |
} |
|
int setValue(int[] data, int offset) { |
this.value = data[offset]; |
return getByteCount(); |
} |
|
String toStringWithValues() { |
return name + ":\t" + value; |
} |
|
void toXML(StringBuilder result) { |
String s_value; |
int numberOfHighestVariable = 255; |
int numberOfLowestVariable = numberOfHighestVariable |
- NUMBER_OF_VARIABLES; |
if (isDynamic && value >= numberOfLowestVariable) { |
s_value = "var" + (value - numberOfLowestVariable); |
} else |
s_value = Integer.toString(value); |
result.append(" <parameter name=\"" + name + "\" value=\"" |
+ s_value + "\"/>\n"); |
} |
} |
|
public static class BitSetEntry extends ConfigEntry { |
BitSetEntry(String name, String[] bitNames) { |
super(name); |
this.bitNames = bitNames; |
} |
|
int value; |
String[] bitNames; |
|
int getByteCount() { |
return 1; |
} |
|
int getValue() { |
return value; |
} |
|
int setValue(int[] data, int offset) { |
value = data[offset]; |
return getByteCount(); |
} |
|
String toStringWithValues() { |
StringBuilder result = new StringBuilder(name + "\t["); |
for (int i = 0; i < Math.min(bitNames.length, 8); i++) { |
if (i != 0) |
result.append(", "); |
result.append(bitNames[i] + ":" |
+ ((value & (1 << i)) != 0 ? "1" : "0")); |
} |
return result.toString(); |
} |
|
void toXML(StringBuilder result) { |
result.append(" <parameter name=\"" + name + "\">\n"); |
for (int i = 0; i < Math.min(bitNames.length, 8); i++) { |
result.append(" <bit name=\"" + bitNames[i] + "\" value=\"" |
+ ((value & (1 << i)) != 0 ? "1" : "0") + "\"/>\n"); |
} |
result.append(" </parameter>\n"); |
} |
} |
|
public static class ArrayEntry extends ConfigEntry { |
int length; |
boolean isDynamic; |
int[] values; |
|
ArrayEntry(String name, boolean isDynamic, int length) { |
super(name); |
this.isDynamic = isDynamic; |
this.length = length; |
} |
|
int[] getValue() { |
return values; |
} |
|
int setValue(int[] data, int offset) { |
values = new int[length]; |
System.arraycopy(data, offset, values, 0, length); |
return length; |
} |
|
int getByteCount() { |
return length; |
} |
|
String toStringWithValues() { |
StringBuilder result = new StringBuilder(name + ":\t{"); |
for (int i = 0; i < length; i++) { |
if (i != 0) |
result.append(","); |
result.append(values[i]); |
} |
result.append("}"); |
return result.toString(); |
} |
|
void toXML(StringBuilder result) { |
result.append(" <list name=\"" + name + "\">\n"); |
for (int i = 0; i < length; i++) { |
result.append(" <entry value=\"" + values[i] + "\"/>\n"); |
} |
result.append(" </list>\n"); |
} |
} |
|
public List<ConfigEntry> getEntries() { |
return entries; |
} |
|
public List<Section> getDeclaredSections() { |
return declaredSections; |
} |
|
public void setData(int[] data) { |
int offset = 0; |
for (ConfigEntry entry : entries) { |
offset += entry.setValue(data, offset); |
} |
StringBuilder sbname = new StringBuilder(); |
for (int i = 0; i < 12; i++) { |
if (data[offset] == 0) |
break; |
sbname.append((char) data[offset++]); |
} |
name = sbname.toString(); |
} |
|
public int getByteCount() { |
int result = 0; |
for (ConfigEntry e : entries) { |
result += e.getByteCount(); |
} |
return result; |
} |
|
public String toStringWithValues() { |
StringBuilder result = new StringBuilder(); |
result.append(name + "\n"); |
for (ConfigEntry entry : entries) { |
result.append(entry.toStringWithValues() + "\n"); |
} |
return result.toString(); |
} |
|
public String toXML() { |
StringBuilder result = new StringBuilder(); |
result.append("<parameterset eepromVersion=\"" + eepromVersion |
+ "\" length=\"" + getByteCount() + "\">\n"); |
for (int i = 0; i < entries.size(); i++) { |
ConfigEntry entry = entries.get(i); |
entry.toXML(result); |
} |
result.append("</parameterset>\n"); |
return result.toString(); |
} |
|
public ConfigSet(int eepromVersion) { |
super(); |
this.eepromVersion = eepromVersion; |
} |
|
// This parses only for the purpose of naming and typing parameter sets! |
// It does not parse the section and default information, which could be |
// useful for GUIs etc. |
public static ConfigSet parseXMLConfigSet(int version) throws IOException { |
String fileName = "v" + version + ".xml"; |
File f = new File(fileName); |
DocumentBuilderFactory saxfac = DocumentBuilderFactory.newInstance(); |
saxfac.setValidating(false); |
try { |
DocumentBuilder bldr = saxfac.newDocumentBuilder(); |
Document doc = bldr.parse(f); |
XPath xpath = XPathFactory.newInstance().newXPath(); |
|
String s_eepromVersion = xpath.evaluate( |
"/parameterconfig/@eepromVersion", doc); |
int eepromVersion = Integer.parseInt(s_eepromVersion); |
|
if (eepromVersion != version) { |
throw new IOException( |
"Version mismatch between file name (" |
+ fileName |
+ ") and the version in the parameterconfig/@eepromVersion attribute(" |
+ s_eepromVersion + ")"); |
} |
|
ConfigSet result = new ConfigSet(eepromVersion); |
|
NodeList sectionNodes = (NodeList) xpath.evaluate( |
"/section", doc, XPathConstants.NODESET); |
|
for (int i = 0; i < sectionNodes.getLength(); i++) { |
Element e = (Element) sectionNodes.item(i); |
Section section = new Section(e.getAttribute("name"), e.getAttribute("title")); |
result.declaredSections.add(section); |
} |
|
NodeList parameterNodes = (NodeList) xpath.evaluate( |
"/parameterconfig/parameter", doc, XPathConstants.NODESET); |
|
Section rest = new Section("others", "Entries without a declared section"); |
for (int i = 0; i < parameterNodes.getLength(); i++) { |
Element e = (Element) parameterNodes.item(i); |
|
Map<String, Section> sectionMap = new HashMap<String, Section>(); |
ConfigEntry entry; |
|
if (!e.hasAttribute("name")) { |
throw new IOException("A parameter element (the " + i |
+ "th) had no name attribute!"); |
} |
String s_name = e.getAttribute("name"); |
String s_section = e.getAttribute("section"); |
|
String s_type; |
|
if (e.hasAttribute("type")) { |
s_type = e.getAttribute("type"); |
} else { |
s_type = "static"; |
} |
|
if ("static".equals(s_type)) { |
entry = new ConfigSet.ByteEntry(s_name, false); |
} else if ("dynamic".equals(s_type)) { |
entry = new ConfigSet.ByteEntry(s_name, true); |
} else if ("bitset".equals(s_type)) { |
NodeList bitNodes = (NodeList) xpath.evaluate("bit", e, |
XPathConstants.NODESET); |
String[] bitNames = new String[8]; |
for (int j = 0; j < 8; j++) { |
Element bitNode = (Element) bitNodes.item(j); |
if (bitNode != null) { |
bitNames[j] = bitNode.getAttribute("name"); |
} else { |
bitNames[j] = "Unused"; |
} |
} |
entry = new ConfigSet.BitSetEntry(s_name, |
bitNames); |
} else { |
throw new IOException("Unknown parameter type: " + s_type); |
} |
|
result.entries.add(entry); |
Section section = sectionMap.get(s_section); |
if (section==null) section = rest; |
section.addConfigEntry(entry); |
} |
if (!rest.getEntries().isEmpty()) { |
result.declaredSections.add(rest); |
} |
result.name = "" + version; |
return result; |
} catch (IOException ex) { |
throw ex; |
} catch (XPathExpressionException ex) { |
throw new IOException(ex); |
} catch (SAXException ex) { |
throw new IOException(ex); |
} catch (ParserConfigurationException ex) { |
throw new IOException(ex); |
} |
} |
} |