Subversion Repositories Projects

Rev

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