source: java/main/src/main/java/com/framsticks/parsers/Schema.java @ 85

Last change on this file since 85 was 85, checked in by psniegowski, 11 years ago

HIGHLIGHTS:

  • upgrade to Java 7
    • use try-multi-catch clauses
    • use try-with-resources were appropriate
  • configure FindBugs? (use mvn site and then navigate in browser to the report)
    • remove most bugs found
  • parametrize Dispatching environment (Dispatcher, RunAt?) to enforce more control on the place of closures actual call

CHANGELOG:
Rework FavouritesXMLFactory.

FindBugs?. Thread start.

FindBugs?. Minor change.

FindBugs?. Iterate over entrySet.

FindBugs?. Various.

FindBug?.

FindBug?. Encoding.

FindBug?. Final fields.

FindBug?.

Remove synchronization bug in ClientConnection?.

Experiments with findbugs.

Finish parametrization.

Make RunAt? an abstract class.

More changes in parametrization.

More changes in parametrizing dispatching.

Several changes to parametrize tasks.

Rename Runnable to RunAt?.

Add specific framsticks Runnable.

Add JSR305 (annotations).

Add findbugs reporting.

More improvements to ParamBuilder? wording.

Make FramsClass? accept also ParamBuilder?.

Change wording of ParamBuilder?.

Change wording of Request creation.

Use Java 7 exception catch syntax.

Add ScopeEnd? class.

Upgrade to Java 7.

File size: 9.0 KB
Line 
1package com.framsticks.parsers;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.Map;
8
9import com.framsticks.params.*;
10import com.framsticks.util.lang.Numbers;
11import org.apache.log4j.Logger;
12
13import javax.xml.parsers.DocumentBuilder;
14import javax.xml.parsers.DocumentBuilderFactory;
15import javax.xml.parsers.ParserConfigurationException;
16
17import com.framsticks.leftovers.f0.NeuroClass;
18import org.w3c.dom.Document;
19import org.w3c.dom.NamedNodeMap;
20import org.w3c.dom.Node;
21import org.w3c.dom.NodeList;
22import org.xml.sax.SAXException;
23
24/**
25 * The Class Schema, which represent f0 schema (it contains all the possible
26 * classes definitions that can be used in f0 representation). Definitions are
27 * loaded from XML stream.
28 *
29 * @author Jarek Szymczak <name.surname@gmail.com>
30 * (please replace name and surname with my personal data)
31 */
32public class Schema {
33
34        private final static Logger logger = Logger.getLogger(Schema.class);
35
36        protected final Registry registry = new Registry();
37
38        /** The neuro classes (classess representing different types of neurons). */
39        private Map<String, NeuroClass> neuroClasses = new HashMap<String, NeuroClass>();
40
41        public static InputStream getDefaultDefinitionAsStream() {
42                //return new FileInputStream(new File(Schema.class.getResource("/parsers/f0def.xml").getPath()));
43                return Schema.class.getResourceAsStream("/parsers/f0def.xml");
44        }
45
46        /**
47         * Instantiates a new schema.
48         *
49         * @param inputStream
50         *            the xml stream with schema
51         * @throws Exception
52         *             the exception if one occurred while reading the stream
53         */
54        public Schema(InputStream inputStream) throws Exception {
55
56                DocumentBuilderFactory factory;
57                DocumentBuilder db;
58
59                try {
60                        factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
61                        db = factory.newDocumentBuilder();
62
63                        Document document = db.parse(inputStream);
64                        NodeList classes = document.getElementsByTagName("CLASS");
65
66                        for (int i = 0; i < classes.getLength(); i++) {
67                                Node classNode = classes.item(i);
68                                FramsClass framsClass = processClass(classNode);
69                                registry.putInfoIntoCache(framsClass);
70                        }
71
72                        classes = document.getElementsByTagName("NEUROCLASS");
73
74                        for (int i = 0; i < classes.getLength(); i++) {
75                                Node classNode = classes.item(i);
76                                FramsClass framsClass = processClass(classNode);
77
78                                NamedNodeMap attributes = classNode.getAttributes();
79                                int prefInputs = getIntAttribute(attributes, "INPUTS");
80                                int prefOutput = getIntAttribute(attributes, "OUTPUT");
81                                int prefLocation = getIntAttribute(attributes, "LOCATION");
82                                int visualHints = getIntAttribute(attributes, "VISUALHINTS");
83                                String symbolGlymphString = getAttribute(attributes, "SYMBOL");
84                                int[] symbolGlymph = null;
85
86                                if (symbolGlymphString != null) {
87                                        String[] sgha = symbolGlymphString.split(",");
88                                        int length = sgha.length;
89                                        symbolGlymph = new int[length];
90                                        for (int j = 0; j < length; j++) {
91                                                try {
92                                                        symbolGlymph[j] = Integer.parseInt(sgha[j]);
93                                                } catch (NumberFormatException e) {
94                                                        logger.error("an error occurred while parsing symbol glymph, class getId: "
95                                                                        + framsClass.getId()
96                                                                        + ", glymph offset: " + j);
97                                                }
98                                        }
99                                }
100
101                                neuroClasses.put(framsClass.getId(), new NeuroClass(
102                                                framsClass, prefInputs, prefOutput, prefLocation,
103                                                visualHints, symbolGlymph));
104                        }
105
106                } catch (IOException | ParserConfigurationException | SAXException e) {
107                        logger.fatal("unexpected exception occurred: ", e);
108                        throw e;
109                }
110
111        }
112
113        /**
114         * Method used for convenience, it retrieves the Integer value stored in
115         * node under certain attribute getName. If value is not present or is other
116         * getType than integer 0 is returned.
117         *
118         * @return attribute value if value exists and it's integer (0 otherwise)
119         *
120         */
121        private static int getIntAttribute(NamedNodeMap attributes, String name) {
122                String v = getAttribute(attributes, name);
123                if (v == null) {
124                        return 0;
125                }
126                try {
127                        return Integer.parseInt(v);
128                } catch (NullPointerException e) {
129                        return 0;
130                } catch (NumberFormatException e) {
131                        logger.fatal("attribute " + name
132                                        + " should be numeric: " + v);
133                        return 0;
134                }
135        }
136
137        private static String getAttribute(NamedNodeMap attributes, String name) {
138                Node item = attributes.getNamedItem(name);
139                if (item == null) {
140                        return null;
141                }
142                return item.getNodeValue();
143        }
144
145        /**
146         * Method used for convenience, it retrieves the value stored in node under
147         * certain attribute getName. If value is not present method returns null.
148         *
149         * @param attributeName
150         *            the attribute getName
151         * @param node
152         *            the node
153         * @return attribute value if value exists (null otherwise)
154         *
155         */
156        private static String getAttributeFromNode(String attributeName, Node node) {
157                if (node == null) {
158                        return null;
159                }
160                return getAttribute(node.getAttributes(), attributeName);
161        }
162
163        /**
164         * In this method analysis of single class is performed.
165         *
166         * @param classNode
167         *            the class node
168         * @return the param entry list as a class schema
169         * @throws Exception
170         *             the exception in case of any error
171         */
172        private static FramsClass processClass(Node classNode) throws Exception {
173                String classId = null;
174                String className = "";
175                String classDescription = "";
176                try {
177                        classId = classNode.getAttributes().getNamedItem("ID")
178                                        .getNodeValue();
179                } catch (NullPointerException e) {
180                        throw new Exception("Class getId is not defined!");
181                }
182
183                className = getAttributeFromNode("NAME", classNode);
184                classDescription = getAttributeFromNode("DESCRIPTION", classNode);
185
186                FramsClass framsClass = new FramsClass(classId, className, classDescription);
187
188                NodeList classProperties = classNode.getChildNodes();
189
190                for (int j = 0; j < classProperties.getLength(); j++) {
191                        Node node = classProperties.item(j);
192
193                        if ("GROUP".equals(node.getNodeName())) {
194                                NamedNodeMap attributes = node.getAttributes();
195                                String name = getAttribute(attributes, "NAME");
196                                if (name == null) {
197                                        logger.warn("Group name in class \"" + classId + "\" ("
198                                                        + className + ") is undefined");
199                                } else {
200                                        framsClass.appendGroup(new Group(name));
201                                }
202                        } else if ("PROP".equals(node.getNodeName())
203                                        || "NEUROPROP".equals(node.getNodeName())) {
204
205                                NamedNodeMap attributes = node.getAttributes();
206                                Param param = processParameter(attributes, classId);
207                                framsClass.append(param);
208                        }
209
210                }
211
212                return framsClass;
213        }
214
215        private static <T extends Number> T extractAttribute(NamedNodeMap attributes, String name, Class<T> type) {
216                String value = getAttribute(attributes, name);
217                if (value == null) {
218                        return null;
219                }
220                return Numbers.parse(value, type);
221        }
222        /**
223         * It analyses the single property within the class
224         *
225         * @param attributes
226         *            the attributes of property
227         * @param classId
228         *            the class getId
229         * @return the param entry representing single parameter
230         * @throws Exception
231         *             the exception in case of any error
232         */
233        private static Param processParameter(NamedNodeMap attributes, String classId)
234                        throws Exception {
235
236                String id = getAttribute(attributes, "ID");
237                if (id == null)
238                        throw new Exception("Property ID in class \"" + classId
239                                        + "\" is undefined");
240                String type = getAttribute(attributes, "TYPE");
241                if (type == null)
242                        throw new Exception("TYPE of property \"" + id + "\" is undefined");
243
244                String name = getAttribute(attributes, "NAME");
245                String description = getAttribute(attributes, "DESCRIPTION");
246                int group = getIntAttribute(attributes, "GROUP");
247                String flagsString = getAttribute(attributes, "FLAGS");
248
249                Integer flags = 0;
250
251                try {
252                        if (flagsString != null)
253                                for (String flag : flagsString.split("[^0-9]")) {
254                                        if (flag.trim().equals(""))
255                                                continue;
256                                        flags |= Integer.parseInt(flag);
257                                }
258                } catch (NumberFormatException e) {
259                        logger.warn("FLAGS parameter should be an Integer value or separated Integer values. FLAGS are set to: "
260                                        + flags);
261                }
262
263                ParamBuilder builder = Param.build();
264                builder.id(id).name(name).help(description).group(group).flags(flags);
265
266                builder.type(type);
267
268                if ("d".equals(type)) {
269                        builder.min(extractAttribute(attributes, "MIN", Integer.class));
270                        builder.max(extractAttribute(attributes, "MAX", Integer.class));
271                        builder.def(extractAttribute(attributes, "DEF", Integer.class));
272                } else if ("f".equals(type)) {
273                        builder.min(extractAttribute(attributes, "MIN", Double.class));
274                        builder.max(extractAttribute(attributes, "MAX", Double.class));
275                        builder.def(extractAttribute(attributes, "DEF", Double.class));
276                } else if ("s".equals(type)) {
277                        builder.min(extractAttribute(attributes, "MIN", Integer.class));
278                        builder.max(extractAttribute(attributes, "MAX", Integer.class));
279                        builder.def(extractAttribute(attributes, "DEF", Integer.class));
280                        builder.def(getAttribute(attributes, "DEF"));
281                } else {
282                        builder.type(type);
283                }
284                return builder.finish();
285        }
286
287
288        public Map<String, NeuroClass> getNeuroClasses() {
289                return Collections.unmodifiableMap(neuroClasses);
290        }
291
292        public final Registry getRegistry() {
293                return registry;
294        }
295
296
297}
Note: See TracBrowser for help on using the repository browser.