Subversion Repositories Projects

Rev

Rev 1532 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1532 - 1
package dongfang.mkt.configuration;
2
 
3
import java.io.File;
4
import java.io.IOException;
5
import java.util.ArrayList;
6
import java.util.List;
7
 
8
import javax.xml.parsers.DocumentBuilder;
9
import javax.xml.parsers.DocumentBuilderFactory;
10
import javax.xml.parsers.ParserConfigurationException;
11
import javax.xml.xpath.XPath;
12
import javax.xml.xpath.XPathConstants;
13
import javax.xml.xpath.XPathExpressionException;
14
import javax.xml.xpath.XPathFactory;
15
 
16
import org.w3c.dom.Document;
17
import org.w3c.dom.Element;
18
import org.w3c.dom.NodeList;
19
import org.xml.sax.SAXException;
20
 
21
public class ConfigSet {
22
        public static final int NUMBER_OF_VARIABLES = 8;
23
        String name;
24
        int eepromVersion;
25
 
26
        List<Section> declaredSections = new ArrayList<Section>();
27
        List<ConfigEntry> entries = new ArrayList<ConfigEntry>();
28
 
29
        public static class Section {
30
                String name, title;
31
                List<ConfigEntry> entries = new ArrayList<ConfigEntry>();
32
 
33
                public Section(String name, String title) {
34
                        this.name = name;
35
                        this.title = title;
36
                }
37
 
38
                public void addConfigEntry(ConfigEntry e) {
39
                        this.entries.add(e);
40
                }
41
 
42
                public List<ConfigEntry> getEntries() {
43
                        return entries;
44
                }
45
 
46
                public String getName() { return name; }
47
                public String getTitle() { return title; }
48
        }
49
 
50
        public static abstract class ConfigEntry {
51
                String name;
52
 
53
                ConfigEntry(String name) {
54
                        this.name = name;
55
                }
56
 
57
                abstract int getByteCount();
58
 
59
                abstract String toStringWithValues();
60
 
61
                abstract void toXML(StringBuilder result);
62
 
63
                abstract int setValue(int[] data, int offset);
64
 
65
                public String getName() {
66
                        return name;
67
                }
68
 
69
                public String getSection() {
70
                        return name;
71
                }
72
        }
73
 
74
        public static class ByteEntry extends ConfigEntry {
75
                ByteEntry(String name, boolean isDynamic) {
76
                        super(name);
77
                        this.isDynamic = isDynamic;
78
                }
79
 
80
                boolean isDynamic;
81
                int value;
82
 
83
                int getByteCount() {
84
                        return 1;
85
                }
86
 
87
                int getValue() {
88
                        return value;
89
                }
90
 
91
                int setValue(int[] data, int offset) {
92
                        this.value = data[offset];
93
                        return getByteCount();
94
                }
95
 
96
                String toStringWithValues() {
97
                        return name + ":\t" + value;
98
                }
99
 
100
                void toXML(StringBuilder result) {
101
                        String s_value;
102
                        int numberOfHighestVariable = 255;
103
                        int numberOfLowestVariable = numberOfHighestVariable
104
                                        - NUMBER_OF_VARIABLES;
105
                        if (isDynamic && value >= numberOfLowestVariable) {
106
                                s_value = "var" + (value - numberOfLowestVariable);
107
                        } else
108
                                s_value = Integer.toString(value);
109
                        result.append("  <parameter name=\"" + name + "\" value=\""
110
                                        + s_value + "\"/>\n");
111
                }
112
        }
113
 
114
        public static class BitSetEntry extends ConfigEntry {
115
                BitSetEntry(String name, String[] bitNames) {
116
                        super(name);
117
                        this.bitNames = bitNames;
118
                }
119
 
120
                int value;
121
                String[] bitNames;
122
 
123
                int getByteCount() {
124
                        return 1;
125
                }
126
 
127
                int getValue() {
128
                        return value;
129
                }
130
 
131
                int setValue(int[] data, int offset) {
132
                        value = data[offset];
133
                        return getByteCount();
134
                }
135
 
136
                String toStringWithValues() {
137
                        StringBuilder result = new StringBuilder(name + "\t[");
138
                        for (int i = 0; i < Math.min(bitNames.length, 8); i++) {
139
                                if (i != 0)
140
                                        result.append(", ");
141
                                result.append(bitNames[i] + ":"
142
                                                + ((value & (1 << i)) != 0 ? "1" : "0"));
143
                        }
144
                        return result.toString();
145
                }
146
 
147
                void toXML(StringBuilder result) {
148
                        result.append("  <parameter name=\"" + name + "\">\n");
149
                        for (int i = 0; i < Math.min(bitNames.length, 8); i++) {
150
                                result.append("    <bit name=\"" + bitNames[i] + "\" value=\""
151
                                                + ((value & (1 << i)) != 0 ? "1" : "0") + "\"/>\n");
152
                        }
153
                        result.append("  </parameter>\n");
154
                }
155
        }
156
 
157
        public static class ArrayEntry extends ConfigEntry {
158
                int length;
159
                boolean isDynamic;
160
                int[] values;
161
 
162
                ArrayEntry(String name, boolean isDynamic, int length) {
163
                        super(name);
164
                        this.isDynamic = isDynamic;
165
                        this.length = length;
166
                }
167
 
168
                int[] getValue() {
169
                        return values;
170
                }
171
 
172
                int setValue(int[] data, int offset) {
173
                        values = new int[length];
174
                        System.arraycopy(data, offset, values, 0, length);
175
                        return length;
176
                }
177
 
178
                int getByteCount() {
179
                        return length;
180
                }
181
 
182
                String toStringWithValues() {
183
                        StringBuilder result = new StringBuilder(name + ":\t{");
184
                        for (int i = 0; i < length; i++) {
185
                                if (i != 0)
186
                                        result.append(",");
187
                                result.append(values[i]);
188
                        }
189
                        result.append("}");
190
                        return result.toString();
191
                }
192
 
193
                void toXML(StringBuilder result) {
194
                        result.append("  <list name=\"" + name + "\">\n");
195
                        for (int i = 0; i < length; i++) {
196
                                result.append("    <entry value=\"" + values[i] + "\"/>\n");
197
                        }
198
                        result.append("  </list>\n");
199
                }
200
        }
201
 
202
        public List<ConfigEntry> getEntries() {
203
                return entries;
204
        }
205
 
206
        public List<Section> getDeclaredSections() {
207
                return declaredSections;
208
        }
209
 
210
        public void setData(int[] data) {
211
                int offset = 0;
212
                for (ConfigEntry entry : entries) {
213
                        offset += entry.setValue(data, offset);
214
                }
215
                StringBuilder sbname = new StringBuilder();
216
                for (int i = 0; i < 12; i++) {
217
                        if (data[offset] == 0)
218
                                break;
219
                        sbname.append((char) data[offset++]);
220
                }
221
                name = sbname.toString();
222
        }
223
 
224
        public int getByteCount() {
225
                int result = 0;
226
                for (ConfigEntry e : entries) {
227
                        result += e.getByteCount();
228
                }
229
                return result;
230
        }
231
 
232
        public String toStringWithValues() {
233
                StringBuilder result = new StringBuilder();
234
                result.append(name + "\n");
235
                for (ConfigEntry entry : entries) {
236
                        result.append(entry.toStringWithValues() + "\n");
237
                }
238
                return result.toString();
239
        }
240
 
241
        public String toXML() {
242
                StringBuilder result = new StringBuilder();
243
                result.append("<parameterset eepromVersion=\"" + eepromVersion
244
                                + "\" length=\"" + getByteCount() + "\">\n");
245
                for (int i = 0; i < entries.size(); i++) {
246
                        ConfigEntry entry = entries.get(i);
247
                        entry.toXML(result);
248
                }
249
                result.append("</parameterset>\n");
250
                return result.toString();
251
        }
252
 
253
        public ConfigSet(int eepromVersion) {
254
                super();
255
                this.eepromVersion = eepromVersion;
256
        }
257
 
258
        // This parses only for the purpose of naming and typing parameter sets!
259
        // It does not parse the section and default information, which could be
260
        // useful for GUIs etc.
261
        public static ConfigSet parseXMLConfigSet(int version) throws IOException {
1559 - 262
                String fileName = "configsets/templates/v" + version + ".xml";
1532 - 263
                File f = new File(fileName);
264
                DocumentBuilderFactory saxfac = DocumentBuilderFactory.newInstance();
265
                saxfac.setValidating(false);
266
                try {
267
                        DocumentBuilder bldr = saxfac.newDocumentBuilder();
268
                        Document doc = bldr.parse(f);
269
                        XPath xpath = XPathFactory.newInstance().newXPath();
270
 
271
                        String s_eepromVersion = xpath.evaluate(
1559 - 272
                                        "/parametertemplate/@eepromVersion", doc);
1532 - 273
                        int eepromVersion = Integer.parseInt(s_eepromVersion);
274
 
275
                        if (eepromVersion != version) {
276
                                throw new IOException(
277
                                                "Version mismatch between file name ("
278
                                                                + fileName
1559 - 279
                                                                + ") and the version in the parametertemplate/@eepromVersion attribute("
1532 - 280
                                                                + s_eepromVersion + ")");
281
                        }
282
 
283
                        ConfigSet result = new ConfigSet(eepromVersion);
284
 
285
                        NodeList sectionNodes = (NodeList) xpath.evaluate(
1559 - 286
                                        "/parametertemplate/section", doc, XPathConstants.NODESET);
1532 - 287
 
288
                        for (int i = 0; i < sectionNodes.getLength(); i++) {
1559 - 289
                                Element sectionNode = (Element) sectionNodes.item(i);
290
                                Section section = new Section(sectionNode.getAttribute("name"), sectionNode.getAttribute("title"));
1532 - 291
                                result.declaredSections.add(section);
292
 
293
                        NodeList parameterNodes = (NodeList) xpath.evaluate(
1559 - 294
                                        "parameter", sectionNode, XPathConstants.NODESET);
1532 - 295
 
1559 - 296
                        for (int j=0; j<parameterNodes.getLength(); j++) {
297
                                Element parameterNode = (Element) parameterNodes.item(j);
1532 - 298
 
299
                                ConfigEntry entry;
300
 
1559 - 301
                                if (!sectionNode.hasAttribute("name")) {
302
                                        throw new IOException("A parameter element (the " + j
303
                                                        + "th in section "+sectionNode.getAttribute("name")+") had no name attribute!");
1532 - 304
                                }
305
 
1559 - 306
                                String s_name = parameterNode.getAttribute("name");
1532 - 307
                                String s_type;
308
 
1559 - 309
                                if (parameterNode.hasAttribute("type")) {
310
                                        s_type = parameterNode.getAttribute("type");
1532 - 311
                                } else {
312
                                        s_type = "static";
313
                                }
314
 
315
                                if ("static".equals(s_type)) {
316
                                        entry = new ConfigSet.ByteEntry(s_name, false);
317
                                } else if ("dynamic".equals(s_type)) {
318
                                        entry = new ConfigSet.ByteEntry(s_name, true);
319
                                } else if ("bitset".equals(s_type)) {
1559 - 320
                                        NodeList bitNodes = (NodeList) xpath.evaluate("bit", parameterNode, XPathConstants.NODESET);
1532 - 321
                                        String[] bitNames = new String[8];
1559 - 322
                                        for (int k=0; k<8; k++) {
323
                                                Element bitNode = (Element) bitNodes.item(k);
1532 - 324
                                                if (bitNode != null) {
1559 - 325
                                                        bitNames[k] = bitNode.getAttribute("name");
1532 - 326
                                                } else {
1559 - 327
                                                        bitNames[k] = "Unused";
1532 - 328
                                                }
329
                                        }
1559 - 330
                                        entry = new ConfigSet.BitSetEntry(s_name, bitNames);
1532 - 331
                                } else {
332
                                        throw new IOException("Unknown parameter type: " + s_type);
333
                                }
334
 
335
                                result.entries.add(entry);
336
                                section.addConfigEntry(entry);
337
                        }
338
                        }
339
                        result.name = "" + version;
340
                        return result;
341
                } catch (IOException ex) {
342
                        throw ex;
343
                } catch (XPathExpressionException ex) {
344
                        throw new IOException(ex);
345
                } catch (SAXException ex) {
346
                        throw new IOException(ex);
347
                } catch (ParserConfigurationException ex) {
348
                        throw new IOException(ex);
349
                }
350
        }
351
}