1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.jeuclid.elements.support.operatordict;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.ObjectInput;
24 import java.io.ObjectInputStream;
25 import java.io.Serializable;
26 import java.util.EnumMap;
27 import java.util.Map;
28 import java.util.TreeMap;
29
30 import javax.xml.parsers.ParserConfigurationException;
31 import javax.xml.parsers.SAXParserFactory;
32
33 import net.sourceforge.jeuclid.elements.presentation.token.Mo;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.xml.sax.Attributes;
38 import org.xml.sax.InputSource;
39 import org.xml.sax.SAXException;
40 import org.xml.sax.XMLReader;
41 import org.xml.sax.helpers.DefaultHandler;
42
43
44
45
46
47
48 public final class OperatorDictionary implements Serializable {
49
50
51
52
53 public static final String NAME_VERYVERYTHINMATHSPACE = "veryverythinmathspace";
54
55
56
57
58 public static final String NAME_VERYTHINMATHSPACE = "verythinmathspace";
59
60
61
62
63 public static final String NAME_THINMATHSPACE = "thinmathspace";
64
65
66
67
68 public static final String NAME_MEDIUMMATHSPACE = "mediummathspace";
69
70
71
72
73 public static final String NAME_THICKMATHSPACE = "thickmathspace";
74
75
76
77
78 public static final String NAME_VERYTHICKMATHSPACE = "verythickmathspace";
79
80
81
82
83 public static final String NAME_VERYVERYTHICKMATHSPACE = "veryverythickmathspace";
84
85
86
87
88 public static final String NAME_INFINITY = "infinity";
89
90
91 public static final String FORM_PREFIX = "prefix";
92
93
94 public static final String FORM_INFIX = "infix";
95
96
97 public static final String FORM_POSTFIX = "postfix";
98
99
100
101
102
103 public static final String VALUE_UNKNOWN = "NULL";
104
105
106
107
108 private static final Log LOGGER = LogFactory
109 .getLog(OperatorDictionary.class);
110
111
112
113
114 private static final long serialVersionUID = 1L;
115
116
117
118
119 private static final String DICTIONARY_FILE = "/moDictionary.xml";
120
121
122
123
124 private static OperatorDictionary instance;
125
126 private final Map<OperatorAttribute, Map<String, Map<OperatorForm, String>>> dict;
127
128 private OperatorDictionary() {
129 this.dict = new EnumMap<OperatorAttribute, Map<String, Map<OperatorForm, String>>>(
130 OperatorAttribute.class);
131 this.initializeFromXML();
132 }
133
134
135
136
137
138
139 public static synchronized OperatorDictionary getInstance() {
140 if (OperatorDictionary.instance == null) {
141 OperatorDictionary newDict = null;
142 try {
143 final InputStream is = OperatorDictionary.class
144 .getResourceAsStream("/moDictionary.ser");
145 final ObjectInput oi = new ObjectInputStream(is);
146 newDict = (OperatorDictionary) oi.readObject();
147 oi.close();
148 } catch (final ClassNotFoundException cnfe) {
149 newDict = null;
150 } catch (final IllegalArgumentException e) {
151 newDict = null;
152 } catch (final IOException e) {
153 newDict = null;
154 } catch (final NullPointerException e) {
155 newDict = null;
156 }
157 if (newDict == null) {
158 OperatorDictionary.instance = new OperatorDictionary();
159 } else {
160 OperatorDictionary.instance = newDict;
161 }
162 }
163 return OperatorDictionary.instance;
164 }
165
166
167
168
169 private void initializeFromXML() {
170 try {
171 final InputStream dictInput = OperatorDictionary.class
172 .getResourceAsStream(OperatorDictionary.DICTIONARY_FILE);
173 final SAXParserFactory factory = SAXParserFactory.newInstance();
174 final XMLReader reader = factory.newSAXParser().getXMLReader();
175 reader.setContentHandler(new DictionaryReader());
176 reader.parse(new InputSource(dictInput));
177 } catch (final ParserConfigurationException e) {
178 OperatorDictionary.LOGGER.warn("Cannot get SAXParser:"
179 + e.getMessage());
180 } catch (final SAXException e) {
181 OperatorDictionary.LOGGER
182 .warn("SAXException while parsing dictionary:"
183 + e.getMessage());
184 } catch (final IOException e) {
185 OperatorDictionary.LOGGER.warn(
186 "Read error while accessing XML dictionary", e);
187 }
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 public String getDefaultAttributeValue(final String operator,
204 final String form, final String attributeName)
205 throws UnknownAttributeException {
206 final OperatorForm intForm = OperatorForm.parseOperatorForm(form);
207 return this.getDefaultAttributeValue(operator, intForm,
208 OperatorAttribute.parseOperatorAttribute(attributeName));
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 private String getDefaultAttributeValue(final String operator,
226 final OperatorForm form, final OperatorAttribute attribute) {
227
228 final Map<String, Map<OperatorForm, String>> opForAttr = this.dict
229 .get(attribute);
230 if (opForAttr == null) {
231 return attribute.getDefaultValue();
232 }
233 final Map<OperatorForm, String> valuesPerForm = opForAttr.get(operator);
234 String retVal;
235 if (valuesPerForm == null) {
236 retVal = attribute.getDefaultValue();
237 } else {
238 retVal = valuesPerForm.get(form);
239 if (retVal == null) {
240 retVal = valuesPerForm.get(OperatorForm.INFIX);
241 }
242 if (retVal == null) {
243 retVal = valuesPerForm.get(OperatorForm.POSTFIX);
244 }
245 if (retVal == null) {
246 retVal = valuesPerForm.get(OperatorForm.PREFIX);
247 }
248 if (retVal == null) {
249 retVal = attribute.getDefaultValue();
250 }
251 }
252 return retVal;
253 }
254
255
256
257
258
259 private class DictionaryReader extends DefaultHandler {
260 private static final String ELEMENT_ELEMENT = "element";
261
262 private String currentOperator;
263
264 private OperatorForm currentFormIndex;
265
266 private Map<OperatorAttribute, String> currentEntry;
267
268 public DictionaryReader() {
269
270 this.currentEntry = null;
271 }
272
273 @Override
274 public void startDocument() throws SAXException {
275
276 }
277
278 @Override
279 public void endDocument() throws SAXException {
280
281 }
282
283 @Override
284 public void startElement(final String uri, final String localName,
285 final String rawName, final Attributes attlist)
286 throws SAXException {
287
288 if (rawName
289 .equals(OperatorDictionary.DictionaryReader.ELEMENT_ELEMENT)) {
290 this.currentEntry = new TreeMap<OperatorAttribute, String>();
291 final String form = attlist.getValue(Mo.ATTR_FORM);
292 if (form == null) {
293
294
295 OperatorDictionary.LOGGER
296 .fatal("Error in dictionary, attribute 'form' is required attribute for the dictionary");
297 this.currentFormIndex = OperatorForm.INFIX;
298 } else {
299 this.currentFormIndex = OperatorForm
300 .parseOperatorForm(form);
301 }
302 for (int i = 0; i < attlist.getLength(); i++) {
303 final String attName = attlist.getQName(i);
304 final String attValue = attlist.getValue(i);
305 if (!attName.equals(Mo.ATTR_FORM)) {
306 try {
307 this.currentEntry.put(OperatorAttribute
308 .parseOperatorAttribute(attName), attValue);
309 } catch (final UnknownAttributeException e) {
310 OperatorDictionary.LOGGER.fatal(e.getMessage());
311 }
312 }
313 }
314 }
315 }
316
317 @Override
318 public void endElement(final String uri, final String localName,
319 final String rawName) throws SAXException {
320 if (rawName
321 .equals(OperatorDictionary.DictionaryReader.ELEMENT_ELEMENT)) {
322
323 for (final Map.Entry<OperatorAttribute, String> attributeValues : this.currentEntry
324 .entrySet()) {
325 final OperatorAttribute attribute = attributeValues
326 .getKey();
327 final String value = attributeValues.getValue();
328 Map<String, Map<OperatorForm, String>> mapForAttr = OperatorDictionary.this.dict
329 .get(attribute);
330 if (mapForAttr == null) {
331 mapForAttr = new TreeMap<String, Map<OperatorForm, String>>();
332 OperatorDictionary.this.dict.put(attribute, mapForAttr);
333 }
334 Map<OperatorForm, String> valueForForm = mapForAttr
335 .get(this.currentOperator);
336 if (valueForForm == null) {
337 valueForForm = new EnumMap<OperatorForm, String>(
338 OperatorForm.class);
339 mapForAttr.put(this.currentOperator, valueForForm);
340 }
341 valueForForm.put(this.currentFormIndex, value);
342 }
343 }
344 this.currentEntry = null;
345 this.currentOperator = null;
346 }
347
348 @Override
349 public void characters(final char[] data, final int start,
350 final int length) throws SAXException {
351 if (this.currentEntry != null) {
352 final char[] temp = new char[length];
353 System.arraycopy(data, start, temp, 0, length);
354 if (this.currentOperator == null) {
355 this.currentOperator = new String(temp);
356 } else {
357 this.currentOperator += new String(temp);
358 }
359 this.currentOperator = this.currentOperator.trim();
360 }
361 }
362 }
363
364 }