Subversion Repositories Projects

Rev

Rev 1578 | 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;
1578 - 25
 
1532 - 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>();
1578 - 32
 
1532 - 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
                }
1578 - 41
 
1532 - 42
                public List<ConfigEntry> getEntries() {
43
                        return entries;
44
                }
1578 - 45
 
46
                public String getName() {
47
                        return name;
48
                }
49
 
50
                public String getTitle() {
51
                        return title;
52
                }
1532 - 53
        }
1578 - 54
 
1532 - 55
        public static abstract class ConfigEntry {
56
                String name;
57
 
58
                ConfigEntry(String name) {
59
                        this.name = name;
60
                }
61
 
62
                abstract int getByteCount();
63
 
64
                abstract String toStringWithValues();
65
 
66
                abstract void toXML(StringBuilder result);
67
 
68
                abstract int setValue(int[] data, int offset);
69
 
70
                public String getName() {
71
                        return name;
72
                }
73
 
74
                public String getSection() {
75
                        return name;
76
                }
77
        }
78
 
1578 - 79
        public static class StaticByteEntry extends ConfigEntry {
80
                StaticByteEntry(String name) {
1532 - 81
                        super(name);
82
                }
83
 
84
                int value;
85
 
86
                int getByteCount() {
87
                        return 1;
88
                }
89
 
90
                int getValue() {
91
                        return value;
92
                }
93
 
94
                int setValue(int[] data, int offset) {
95
                        this.value = data[offset];
96
                        return getByteCount();
97
                }
98
 
99
                String toStringWithValues() {
100
                        return name + ":\t" + value;
101
                }
102
 
103
                void toXML(StringBuilder result) {
104
                        String s_value;
1578 - 105
                        s_value = Integer.toString(value);
106
                        result.append("  <parameter name=\"" + name + "\" value=\""
107
                                        + s_value + "\"/>\n");
108
                }
109
        }
110
 
111
        public static class DynamicByteEntry extends StaticByteEntry {
112
                int minValue = 0;
113
                int maxValue = 255;
114
                String staticCodeName;
115
                String dynamicCodeName;
116
 
117
                DynamicByteEntry(String name) {
118
                        super(name);
119
                }
120
 
121
                int getMinValue() {
122
                        return minValue;
123
                }
124
 
125
                int getMaxValue() {
126
                        return maxValue;
127
                }
128
 
129
                void setMinValue(int minValue) {
130
                        this.minValue = minValue;
131
                }
132
 
133
                void setMaxValue(int maxValue) {
134
                        this.maxValue = maxValue;
135
                }
136
 
137
                String getStaticCodeName() {
138
                        return staticCodeName;
139
                }
140
 
141
                String getDynamicCodeName() {
142
                        return dynamicCodeName;
143
                }
144
 
145
                void setStaticCodeName(String staticCodeName) {
146
                        this.staticCodeName = staticCodeName;
147
                }
148
 
149
                void setDynamicCodeName(String dynamicCodeName) {
150
                        this.dynamicCodeName = dynamicCodeName;
151
                }
152
 
153
                void toXML(StringBuilder result) {
154
                        String s_value;
155
                        int numberOfLowestVariable = 256 - NUMBER_OF_VARIABLES;
156
                        if (value >= numberOfLowestVariable) {
1532 - 157
                                s_value = "var" + (value - numberOfLowestVariable);
158
                        } else
159
                                s_value = Integer.toString(value);
160
                        result.append("  <parameter name=\"" + name + "\" value=\""
161
                                        + s_value + "\"/>\n");
162
                }
163
        }
164
 
165
        public static class BitSetEntry extends ConfigEntry {
166
                BitSetEntry(String name, String[] bitNames) {
167
                        super(name);
168
                        this.bitNames = bitNames;
169
                }
170
 
171
                int value;
172
                String[] bitNames;
173
 
174
                int getByteCount() {
175
                        return 1;
176
                }
177
 
178
                int getValue() {
179
                        return value;
180
                }
181
 
182
                int setValue(int[] data, int offset) {
183
                        value = data[offset];
184
                        return getByteCount();
185
                }
186
 
187
                String toStringWithValues() {
188
                        StringBuilder result = new StringBuilder(name + "\t[");
189
                        for (int i = 0; i < Math.min(bitNames.length, 8); i++) {
190
                                if (i != 0)
191
                                        result.append(", ");
192
                                result.append(bitNames[i] + ":"
193
                                                + ((value & (1 << i)) != 0 ? "1" : "0"));
194
                        }
195
                        return result.toString();
196
                }
197
 
198
                void toXML(StringBuilder result) {
199
                        result.append("  <parameter name=\"" + name + "\">\n");
200
                        for (int i = 0; i < Math.min(bitNames.length, 8); i++) {
201
                                result.append("    <bit name=\"" + bitNames[i] + "\" value=\""
202
                                                + ((value & (1 << i)) != 0 ? "1" : "0") + "\"/>\n");
203
                        }
204
                        result.append("  </parameter>\n");
205
                }
206
        }
207
 
208
        public static class ArrayEntry extends ConfigEntry {
209
                int length;
210
                boolean isDynamic;
211
                int[] values;
212
 
213
                ArrayEntry(String name, boolean isDynamic, int length) {
214
                        super(name);
215
                        this.isDynamic = isDynamic;
216
                        this.length = length;
217
                }
218
 
219
                int[] getValue() {
220
                        return values;
221
                }
222
 
223
                int setValue(int[] data, int offset) {
224
                        values = new int[length];
225
                        System.arraycopy(data, offset, values, 0, length);
226
                        return length;
227
                }
228
 
229
                int getByteCount() {
230
                        return length;
231
                }
232
 
233
                String toStringWithValues() {
234
                        StringBuilder result = new StringBuilder(name + ":\t{");
235
                        for (int i = 0; i < length; i++) {
236
                                if (i != 0)
237
                                        result.append(",");
238
                                result.append(values[i]);
239
                        }
240
                        result.append("}");
241
                        return result.toString();
242
                }
243
 
244
                void toXML(StringBuilder result) {
245
                        result.append("  <list name=\"" + name + "\">\n");
246
                        for (int i = 0; i < length; i++) {
247
                                result.append("    <entry value=\"" + values[i] + "\"/>\n");
248
                        }
249
                        result.append("  </list>\n");
250
                }
251
        }
252
 
253
        public List<ConfigEntry> getEntries() {
254
                return entries;
255
        }
256
 
257
        public List<Section> getDeclaredSections() {
258
                return declaredSections;
259
        }
1578 - 260
 
1601 - 261
        public void setData(int[] data) throws IOException {
1532 - 262
                int offset = 0;
1601 - 263
                int dataLength = data.length - 12;
264
                if (dataLength != getByteCount()) {
265
                        throw new IOException("The received number of databytes (" + dataLength + ") was not equal to the length of the declared parameter set(" + getByteCount()+").");
266
                }
267
 
1532 - 268
                for (ConfigEntry entry : entries) {
269
                        offset += entry.setValue(data, offset);
270
                }
271
                StringBuilder sbname = new StringBuilder();
272
                for (int i = 0; i < 12; i++) {
273
                        if (data[offset] == 0)
274
                                break;
275
                        sbname.append((char) data[offset++]);
276
                }
277
                name = sbname.toString();
278
        }
279
 
280
        public int getByteCount() {
281
                int result = 0;
282
                for (ConfigEntry e : entries) {
283
                        result += e.getByteCount();
284
                }
285
                return result;
286
        }
287
 
288
        public String toStringWithValues() {
289
                StringBuilder result = new StringBuilder();
290
                result.append(name + "\n");
291
                for (ConfigEntry entry : entries) {
292
                        result.append(entry.toStringWithValues() + "\n");
293
                }
294
                return result.toString();
295
        }
296
 
297
        public String toXML() {
298
                StringBuilder result = new StringBuilder();
299
                result.append("<parameterset eepromVersion=\"" + eepromVersion
300
                                + "\" length=\"" + getByteCount() + "\">\n");
301
                for (int i = 0; i < entries.size(); i++) {
302
                        ConfigEntry entry = entries.get(i);
303
                        entry.toXML(result);
304
                }
305
                result.append("</parameterset>\n");
306
                return result.toString();
307
        }
308
 
309
        public ConfigSet(int eepromVersion) {
310
                super();
311
                this.eepromVersion = eepromVersion;
312
        }
313
 
314
        // This parses only for the purpose of naming and typing parameter sets!
315
        // It does not parse the section and default information, which could be
316
        // useful for GUIs etc.
317
        public static ConfigSet parseXMLConfigSet(int version) throws IOException {
1559 - 318
                String fileName = "configsets/templates/v" + version + ".xml";
1532 - 319
                File f = new File(fileName);
320
                DocumentBuilderFactory saxfac = DocumentBuilderFactory.newInstance();
321
                saxfac.setValidating(false);
322
                try {
323
                        DocumentBuilder bldr = saxfac.newDocumentBuilder();
324
                        Document doc = bldr.parse(f);
325
                        XPath xpath = XPathFactory.newInstance().newXPath();
326
 
327
                        String s_eepromVersion = xpath.evaluate(
1559 - 328
                                        "/parametertemplate/@eepromVersion", doc);
1532 - 329
                        int eepromVersion = Integer.parseInt(s_eepromVersion);
330
 
1601 - 331
                        String s_declaredLength = xpath.evaluate(
332
                                        "/parametertemplate/@length", doc);
333
                        int declaredLength = Integer.parseInt(s_declaredLength);
334
 
1532 - 335
                        if (eepromVersion != version) {
336
                                throw new IOException(
337
                                                "Version mismatch between file name ("
338
                                                                + fileName
1559 - 339
                                                                + ") and the version in the parametertemplate/@eepromVersion attribute("
1532 - 340
                                                                + s_eepromVersion + ")");
341
                        }
342
 
343
                        ConfigSet result = new ConfigSet(eepromVersion);
344
 
345
                        NodeList sectionNodes = (NodeList) xpath.evaluate(
1559 - 346
                                        "/parametertemplate/section", doc, XPathConstants.NODESET);
1532 - 347
 
348
                        for (int i = 0; i < sectionNodes.getLength(); i++) {
1559 - 349
                                Element sectionNode = (Element) sectionNodes.item(i);
1578 - 350
                                Section section = new Section(sectionNode.getAttribute("name"),
351
                                                sectionNode.getAttribute("title"));
1532 - 352
                                result.declaredSections.add(section);
353
 
1578 - 354
                                NodeList parameterNodes = (NodeList) xpath.evaluate(
355
                                                "parameter", sectionNode, XPathConstants.NODESET);
1532 - 356
 
1578 - 357
                                for (int j = 0; j < parameterNodes.getLength(); j++) {
358
                                        Element parameterNode = (Element) parameterNodes.item(j);
1532 - 359
 
1578 - 360
                                        ConfigEntry entry;
1532 - 361
 
1578 - 362
                                        if (!sectionNode.hasAttribute("name")) {
363
                                                throw new IOException("A parameter element (the " + j
364
                                                                + "th in section "
365
                                                                + sectionNode.getAttribute("name")
366
                                                                + ") had no name attribute!");
367
                                        }
1532 - 368
 
1578 - 369
                                        String s_name = parameterNode.getAttribute("name");
370
                                        String s_type;
371
 
372
                                        if (parameterNode.hasAttribute("type")) {
373
                                                s_type = parameterNode.getAttribute("type");
374
                                        } else {
375
                                                s_type = "static";
376
                                        }
377
 
378
                                        if ("static".equals(s_type)) {
379
                                                entry = new ConfigSet.StaticByteEntry(s_name);
380
                                        } else if ("dynamic".equals(s_type)) {
381
                                                ConfigSet.DynamicByteEntry de = new ConfigSet.DynamicByteEntry(s_name);
382
                                                if (parameterNode.hasAttribute("minValue")) {
383
                                                        de.setMinValue(Integer.parseInt(parameterNode.getAttribute("minValue")));
1532 - 384
                                                }
1578 - 385
                                                if (parameterNode.hasAttribute("maxValue")) {
386
                                                        de.setMinValue(Integer.parseInt(parameterNode.getAttribute("maxValue")));
387
                                                }
388
                                                if (parameterNode.hasAttribute("staticCodeName")) {
389
                                                        de.setStaticCodeName(parameterNode.getAttribute("staticCodeName"));
390
                                                } else de.setStaticCodeName(de.getName());
391
                                                if (parameterNode.hasAttribute("dynamicCodeName")) {
392
                                                        de.setDynamicCodeName(parameterNode.getAttribute("dynamicCodeName"));
393
                                                } else de.setDynamicCodeName(de.getName());
394
                                                entry = de;
395
                                        } else if ("bitset".equals(s_type)) {
396
                                                NodeList bitNodes = (NodeList) xpath.evaluate("bit",
397
                                                                parameterNode, XPathConstants.NODESET);
398
                                                String[] bitNames = new String[8];
399
                                                for (int k = 0; k < 8; k++) {
400
                                                        Element bitNode = (Element) bitNodes.item(k);
401
                                                        if (bitNode != null) {
402
                                                                bitNames[k] = bitNode.getAttribute("name");
403
                                                        } else {
404
                                                                bitNames[k] = "Unused";
405
                                                        }
406
                                                }
407
                                                entry = new ConfigSet.BitSetEntry(s_name, bitNames);
408
                                        } else {
409
                                                throw new IOException("Unknown parameter type: "
410
                                                                + s_type);
1532 - 411
                                        }
1578 - 412
 
413
                                        result.entries.add(entry);
414
                                        section.addConfigEntry(entry);
1532 - 415
                                }
416
                        }
417
                        result.name = "" + version;
1601 - 418
                        if (result.getByteCount() != declaredLength) {
419
                                throw new IOException("The number of parameters in the set (" + result.getEntries().size() + ") was not equal to the declared length (" + declaredLength + ").");
420
                        }
1532 - 421
                        return result;
422
                } catch (IOException ex) {
423
                        throw ex;
424
                } catch (XPathExpressionException ex) {
425
                        throw new IOException(ex);
426
                } catch (SAXException ex) {
427
                        throw new IOException(ex);
428
                } catch (ParserConfigurationException ex) {
429
                        throw new IOException(ex);
430
                }
431
        }
1578 - 432
 
433
        public String generateDynamicSubstitutionCode() {
434
                StringBuilder result = new StringBuilder(
435
                                "const MMXLATION XLATIONS[] = {\n");
436
                boolean hasEntries = false;
437
                for (ConfigEntry entry : entries) {
438
                        if (entry instanceof ConfigSet.DynamicByteEntry) {
439
                                if (hasEntries)
440
                                        result.append(",\n");
441
                                else
442
                                        hasEntries = true;
443
                                ConfigSet.DynamicByteEntry de = (ConfigSet.DynamicByteEntry) entry;
444
                                result.append("{offsetof(ParamSet_t, ");
445
                                result.append(de.getStaticCodeName());
446
                                result.append("), offsetof(DynamicParams_t, ");
447
                                result.append(de.getDynamicCodeName());
448
                                result.append("),");
449
                                result.append(Integer.toString(de.getMinValue()));
450
                                result.append(",");
451
                                result.append(Integer.toString(de.getMaxValue()));
452
                                result.append("}");
453
                        }
454
                }
455
                result.append("};");
456
                return result.toString();
457
        }
1532 - 458
}