Subversion Repositories Projects

Rev

Rev 1559 | 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
 
1532 - 261
        public void setData(int[] data) {
262
                int offset = 0;
263
                for (ConfigEntry entry : entries) {
264
                        offset += entry.setValue(data, offset);
265
                }
266
                StringBuilder sbname = new StringBuilder();
267
                for (int i = 0; i < 12; i++) {
268
                        if (data[offset] == 0)
269
                                break;
270
                        sbname.append((char) data[offset++]);
271
                }
272
                name = sbname.toString();
273
        }
274
 
275
        public int getByteCount() {
276
                int result = 0;
277
                for (ConfigEntry e : entries) {
278
                        result += e.getByteCount();
279
                }
280
                return result;
281
        }
282
 
283
        public String toStringWithValues() {
284
                StringBuilder result = new StringBuilder();
285
                result.append(name + "\n");
286
                for (ConfigEntry entry : entries) {
287
                        result.append(entry.toStringWithValues() + "\n");
288
                }
289
                return result.toString();
290
        }
291
 
292
        public String toXML() {
293
                StringBuilder result = new StringBuilder();
294
                result.append("<parameterset eepromVersion=\"" + eepromVersion
295
                                + "\" length=\"" + getByteCount() + "\">\n");
296
                for (int i = 0; i < entries.size(); i++) {
297
                        ConfigEntry entry = entries.get(i);
298
                        entry.toXML(result);
299
                }
300
                result.append("</parameterset>\n");
301
                return result.toString();
302
        }
303
 
304
        public ConfigSet(int eepromVersion) {
305
                super();
306
                this.eepromVersion = eepromVersion;
307
        }
308
 
309
        // This parses only for the purpose of naming and typing parameter sets!
310
        // It does not parse the section and default information, which could be
311
        // useful for GUIs etc.
312
        public static ConfigSet parseXMLConfigSet(int version) throws IOException {
1559 - 313
                String fileName = "configsets/templates/v" + version + ".xml";
1532 - 314
                File f = new File(fileName);
315
                DocumentBuilderFactory saxfac = DocumentBuilderFactory.newInstance();
316
                saxfac.setValidating(false);
317
                try {
318
                        DocumentBuilder bldr = saxfac.newDocumentBuilder();
319
                        Document doc = bldr.parse(f);
320
                        XPath xpath = XPathFactory.newInstance().newXPath();
321
 
322
                        String s_eepromVersion = xpath.evaluate(
1559 - 323
                                        "/parametertemplate/@eepromVersion", doc);
1532 - 324
                        int eepromVersion = Integer.parseInt(s_eepromVersion);
325
 
326
                        if (eepromVersion != version) {
327
                                throw new IOException(
328
                                                "Version mismatch between file name ("
329
                                                                + fileName
1559 - 330
                                                                + ") and the version in the parametertemplate/@eepromVersion attribute("
1532 - 331
                                                                + s_eepromVersion + ")");
332
                        }
333
 
334
                        ConfigSet result = new ConfigSet(eepromVersion);
335
 
336
                        NodeList sectionNodes = (NodeList) xpath.evaluate(
1559 - 337
                                        "/parametertemplate/section", doc, XPathConstants.NODESET);
1532 - 338
 
339
                        for (int i = 0; i < sectionNodes.getLength(); i++) {
1559 - 340
                                Element sectionNode = (Element) sectionNodes.item(i);
1578 - 341
                                Section section = new Section(sectionNode.getAttribute("name"),
342
                                                sectionNode.getAttribute("title"));
1532 - 343
                                result.declaredSections.add(section);
344
 
1578 - 345
                                NodeList parameterNodes = (NodeList) xpath.evaluate(
346
                                                "parameter", sectionNode, XPathConstants.NODESET);
1532 - 347
 
1578 - 348
                                for (int j = 0; j < parameterNodes.getLength(); j++) {
349
                                        Element parameterNode = (Element) parameterNodes.item(j);
1532 - 350
 
1578 - 351
                                        ConfigEntry entry;
1532 - 352
 
1578 - 353
                                        if (!sectionNode.hasAttribute("name")) {
354
                                                throw new IOException("A parameter element (the " + j
355
                                                                + "th in section "
356
                                                                + sectionNode.getAttribute("name")
357
                                                                + ") had no name attribute!");
358
                                        }
1532 - 359
 
1578 - 360
                                        String s_name = parameterNode.getAttribute("name");
361
                                        String s_type;
362
 
363
                                        if (parameterNode.hasAttribute("type")) {
364
                                                s_type = parameterNode.getAttribute("type");
365
                                        } else {
366
                                                s_type = "static";
367
                                        }
368
 
369
                                        if ("static".equals(s_type)) {
370
                                                entry = new ConfigSet.StaticByteEntry(s_name);
371
                                        } else if ("dynamic".equals(s_type)) {
372
                                                ConfigSet.DynamicByteEntry de = new ConfigSet.DynamicByteEntry(s_name);
373
                                                if (parameterNode.hasAttribute("minValue")) {
374
                                                        de.setMinValue(Integer.parseInt(parameterNode.getAttribute("minValue")));
1532 - 375
                                                }
1578 - 376
                                                if (parameterNode.hasAttribute("maxValue")) {
377
                                                        de.setMinValue(Integer.parseInt(parameterNode.getAttribute("maxValue")));
378
                                                }
379
                                                if (parameterNode.hasAttribute("staticCodeName")) {
380
                                                        de.setStaticCodeName(parameterNode.getAttribute("staticCodeName"));
381
                                                } else de.setStaticCodeName(de.getName());
382
                                                if (parameterNode.hasAttribute("dynamicCodeName")) {
383
                                                        de.setDynamicCodeName(parameterNode.getAttribute("dynamicCodeName"));
384
                                                } else de.setDynamicCodeName(de.getName());
385
                                                entry = de;
386
                                        } else if ("bitset".equals(s_type)) {
387
                                                NodeList bitNodes = (NodeList) xpath.evaluate("bit",
388
                                                                parameterNode, XPathConstants.NODESET);
389
                                                String[] bitNames = new String[8];
390
                                                for (int k = 0; k < 8; k++) {
391
                                                        Element bitNode = (Element) bitNodes.item(k);
392
                                                        if (bitNode != null) {
393
                                                                bitNames[k] = bitNode.getAttribute("name");
394
                                                        } else {
395
                                                                bitNames[k] = "Unused";
396
                                                        }
397
                                                }
398
                                                entry = new ConfigSet.BitSetEntry(s_name, bitNames);
399
                                        } else {
400
                                                throw new IOException("Unknown parameter type: "
401
                                                                + s_type);
1532 - 402
                                        }
1578 - 403
 
404
                                        result.entries.add(entry);
405
                                        section.addConfigEntry(entry);
1532 - 406
                                }
407
                        }
408
                        result.name = "" + version;
409
                        return result;
410
                } catch (IOException ex) {
411
                        throw ex;
412
                } catch (XPathExpressionException ex) {
413
                        throw new IOException(ex);
414
                } catch (SAXException ex) {
415
                        throw new IOException(ex);
416
                } catch (ParserConfigurationException ex) {
417
                        throw new IOException(ex);
418
                }
419
        }
1578 - 420
 
421
        public String generateDynamicSubstitutionCode() {
422
                StringBuilder result = new StringBuilder(
423
                                "const MMXLATION XLATIONS[] = {\n");
424
                boolean hasEntries = false;
425
                for (ConfigEntry entry : entries) {
426
                        if (entry instanceof ConfigSet.DynamicByteEntry) {
427
                                if (hasEntries)
428
                                        result.append(",\n");
429
                                else
430
                                        hasEntries = true;
431
                                ConfigSet.DynamicByteEntry de = (ConfigSet.DynamicByteEntry) entry;
432
                                result.append("{offsetof(ParamSet_t, ");
433
                                result.append(de.getStaticCodeName());
434
                                result.append("), offsetof(DynamicParams_t, ");
435
                                result.append(de.getDynamicCodeName());
436
                                result.append("),");
437
                                result.append(Integer.toString(de.getMinValue()));
438
                                result.append(",");
439
                                result.append(Integer.toString(de.getMaxValue()));
440
                                result.append("}");
441
                        }
442
                }
443
                result.append("};");
444
                return result.toString();
445
        }
1532 - 446
}