Commit | Line | Data |
---|---|---|
be222f56 PT |
1 | /******************************************************************************* |
2 | * Copyright (c) 2010 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Patrick Tasse - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.internal.tmf.ui.parsers.custom; | |
14 | ||
15 | import java.io.ByteArrayInputStream; | |
16 | import java.io.File; | |
17 | import java.io.FileWriter; | |
18 | import java.io.IOException; | |
19 | import java.io.StringWriter; | |
20 | import java.util.ArrayList; | |
21 | import java.util.List; | |
22 | import java.util.Map; | |
23 | import java.util.regex.Pattern; | |
24 | import java.util.regex.PatternSyntaxException; | |
25 | ||
26 | import javax.xml.parsers.DocumentBuilder; | |
27 | import javax.xml.parsers.DocumentBuilderFactory; | |
28 | import javax.xml.parsers.ParserConfigurationException; | |
29 | import javax.xml.transform.OutputKeys; | |
30 | import javax.xml.transform.Transformer; | |
31 | import javax.xml.transform.TransformerConfigurationException; | |
32 | import javax.xml.transform.TransformerException; | |
33 | import javax.xml.transform.TransformerFactory; | |
34 | import javax.xml.transform.TransformerFactoryConfigurationError; | |
35 | import javax.xml.transform.dom.DOMSource; | |
36 | import javax.xml.transform.stream.StreamResult; | |
37 | ||
38 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; | |
39 | import org.eclipse.linuxtools.internal.tmf.ui.Messages; | |
40 | import org.w3c.dom.Document; | |
41 | import org.w3c.dom.Element; | |
42 | import org.w3c.dom.Node; | |
43 | import org.w3c.dom.NodeList; | |
44 | import org.xml.sax.EntityResolver; | |
45 | import org.xml.sax.ErrorHandler; | |
46 | import org.xml.sax.InputSource; | |
47 | import org.xml.sax.SAXException; | |
48 | import org.xml.sax.SAXParseException; | |
49 | ||
50 | public class CustomTxtTraceDefinition extends CustomTraceDefinition { | |
51 | ||
52 | protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME = "custom_txt_parsers.xml"; //$NON-NLS-1$ | |
53 | protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME = | |
54 | Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME).toString(); | |
55 | ||
56 | private static final String CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomTxtTraceDefinition_definitionRootElement; | |
57 | private static final String DEFINITION_ELEMENT = Messages.CustomTxtTraceDefinition_definition; | |
58 | private static final String NAME_ATTRIBUTE = Messages.CustomTxtTraceDefinition_name; | |
59 | private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomTxtTraceDefinition_timestampOutputFormat; | |
60 | private static final String INPUT_LINE_ELEMENT = Messages.CustomTxtTraceDefinition_inputLine; | |
61 | private static final String CARDINALITY_ELEMENT = Messages.CustomTxtTraceDefinition_cardinality; | |
62 | private static final String MIN_ATTRIBUTE = Messages.CustomTxtTraceDefinition_min; | |
63 | private static final String MAX_ATTRIBUTE = Messages.CustomTxtTraceDefinition_max; | |
64 | private static final String REGEX_ELEMENT = Messages.CustomTxtTraceDefinition_regEx; | |
65 | private static final String INPUT_DATA_ELEMENT = Messages.CustomTxtTraceDefinition_inputData; | |
66 | private static final String ACTION_ATTRIBUTE = Messages.CustomTxtTraceDefinition_action; | |
67 | private static final String FORMAT_ATTRIBUTE = Messages.CustomTxtTraceDefinition_format; | |
68 | private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomTxtTraceDefinition_outputColumn; | |
69 | ||
70 | public List<InputLine> inputs; | |
71 | ||
72 | public CustomTxtTraceDefinition() { | |
73 | this("", new ArrayList<InputLine>(0), new ArrayList<OutputColumn>(0), ""); //$NON-NLS-1$ //$NON-NLS-2$ | |
74 | } | |
75 | ||
76 | public CustomTxtTraceDefinition(String logtype, List<InputLine> inputs, List<OutputColumn> outputs, String timeStampOutputFormat) { | |
77 | this.definitionName = logtype; | |
78 | this.inputs = inputs; | |
79 | this.outputs = outputs; | |
80 | this.timeStampOutputFormat = timeStampOutputFormat; | |
81 | } | |
82 | ||
83 | public static class InputLine { | |
84 | public List<InputData> columns; | |
85 | public Cardinality cardinality; | |
86 | private String regex; | |
87 | private Pattern pattern; | |
88 | public InputLine parentInput; | |
89 | public int level; | |
90 | public InputLine nextInput; | |
91 | public List<InputLine> childrenInputs; | |
92 | ||
93 | public InputLine() {} | |
94 | ||
95 | public InputLine(Cardinality cardinality, String regex, List<InputData> columns) { | |
96 | this.cardinality = cardinality; | |
97 | this.regex = regex; | |
98 | this.columns = columns; | |
99 | } | |
100 | ||
101 | public void setRegex(String regex) { | |
102 | this.regex = regex; | |
103 | this.pattern = null; | |
104 | } | |
105 | ||
106 | public String getRegex() { | |
107 | return regex; | |
108 | } | |
109 | ||
110 | public Pattern getPattern() throws PatternSyntaxException { | |
111 | if (pattern == null) { | |
112 | pattern = Pattern.compile(regex); | |
113 | } | |
114 | return pattern; | |
115 | } | |
116 | ||
117 | public void addChild(InputLine input) { | |
118 | if (childrenInputs == null) { | |
119 | childrenInputs = new ArrayList<InputLine>(1); | |
120 | } else if (childrenInputs.size() > 0) { | |
121 | InputLine last = childrenInputs.get(childrenInputs.size() - 1); | |
122 | last.nextInput = input; | |
123 | } | |
124 | childrenInputs.add(input); | |
125 | input.parentInput = this; | |
126 | input.level = this.level + 1; | |
127 | } | |
128 | ||
129 | public void addNext(InputLine input) { | |
130 | if (parentInput != null) { | |
131 | int index = parentInput.childrenInputs.indexOf(this); | |
132 | parentInput.childrenInputs.add(index + 1, input); | |
133 | InputLine next = nextInput; | |
134 | nextInput = input; | |
135 | input.nextInput = next; | |
136 | } | |
137 | input.parentInput = this.parentInput; | |
138 | input.level = this.level; | |
139 | } | |
140 | ||
141 | public void moveUp() { | |
142 | if (parentInput != null) { | |
143 | int index = parentInput.childrenInputs.indexOf(this); | |
144 | if (index > 0) { | |
145 | parentInput.childrenInputs.add(index - 1 , parentInput.childrenInputs.remove(index)); | |
146 | parentInput.childrenInputs.get(index).nextInput = nextInput; | |
147 | nextInput = parentInput.childrenInputs.get(index); | |
148 | } | |
149 | } | |
150 | } | |
151 | ||
152 | public void moveDown() { | |
153 | if (parentInput != null) { | |
154 | int index = parentInput.childrenInputs.indexOf(this); | |
155 | if (index < parentInput.childrenInputs.size() - 1) { | |
156 | parentInput.childrenInputs.add(index + 1 , parentInput.childrenInputs.remove(index)); | |
157 | nextInput = parentInput.childrenInputs.get(index).nextInput; | |
158 | parentInput.childrenInputs.get(index).nextInput = this; | |
159 | } | |
160 | } | |
161 | } | |
162 | ||
163 | public void addColumn(InputData column) { | |
164 | if (columns == null) { | |
165 | columns = new ArrayList<InputData>(1); | |
166 | } | |
167 | columns.add(column); | |
168 | } | |
169 | ||
170 | public List<InputLine> getNextInputs(Map<InputLine, Integer> countMap) { | |
171 | List<InputLine> nextInputs = new ArrayList<InputLine>(); | |
172 | InputLine next = nextInput; | |
173 | while (next != null) { | |
174 | nextInputs.add(next); | |
175 | if (next.cardinality.min > 0) { | |
176 | return nextInputs; | |
177 | } | |
178 | next = next.nextInput; | |
179 | } | |
180 | if (parentInput != null && parentInput.level > 0) { | |
181 | int parentCount = countMap.get(parentInput); | |
182 | if (parentCount < parentInput.getMaxCount()) { | |
183 | nextInputs.add(parentInput); | |
184 | } | |
185 | if (parentCount < parentInput.getMinCount()) { | |
186 | return nextInputs; | |
187 | } | |
188 | nextInputs.addAll(parentInput.getNextInputs(countMap)); | |
189 | } | |
190 | return nextInputs; | |
191 | } | |
192 | ||
193 | public int getMinCount() { | |
194 | return cardinality.min; | |
195 | } | |
196 | ||
197 | public int getMaxCount() { | |
198 | return cardinality.max; | |
199 | } | |
200 | ||
201 | @Override | |
202 | public String toString() { | |
203 | return regex + " " + cardinality; //$NON-NLS-1$ | |
204 | } | |
205 | ||
206 | } | |
207 | ||
208 | public static class InputData { | |
209 | public String name; | |
210 | public int action; | |
211 | public String format; | |
212 | ||
213 | public InputData() {} | |
214 | ||
215 | public InputData(String name, int action, String format) { | |
216 | this.name = name; | |
217 | this.action = action; | |
218 | this.format = format; | |
219 | } | |
220 | ||
221 | public InputData(String name, int action) { | |
222 | this.name = name; | |
223 | this.action = action; | |
224 | } | |
225 | } | |
226 | ||
227 | public static class Cardinality { | |
228 | public final static int INF = Integer.MAX_VALUE; | |
229 | public final static Cardinality ONE = new Cardinality(1, 1); | |
230 | public final static Cardinality ONE_OR_MORE = new Cardinality(1, INF); | |
231 | public final static Cardinality ZERO_OR_ONE = new Cardinality(0, 1); | |
232 | public final static Cardinality ZERO_OR_MORE = new Cardinality(0, INF); | |
233 | ||
234 | private final int min; | |
235 | private final int max; | |
236 | ||
237 | public Cardinality(int min, int max) { | |
238 | this.min = min; | |
239 | this.max = max; | |
240 | } | |
241 | ||
242 | @Override | |
243 | public String toString() { | |
244 | return "(" + (min >= 0 ? min : "?") + "," + (max == INF ? "\u221E" : (max >= 0 ? max : "?")) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ | |
245 | } | |
246 | ||
247 | /* (non-Javadoc) | |
248 | * @see java.lang.Object#hashCode() | |
249 | */ | |
250 | @Override | |
251 | public int hashCode() { | |
252 | final int prime = 31; | |
253 | int result = 1; | |
254 | result = prime * result + max; | |
255 | result = prime * result + min; | |
256 | return result; | |
257 | } | |
258 | ||
259 | /* (non-Javadoc) | |
260 | * @see java.lang.Object#equals(java.lang.Object) | |
261 | */ | |
262 | @Override | |
263 | public boolean equals(Object obj) { | |
264 | if (this == obj) { | |
265 | return true; | |
266 | } | |
267 | if (obj == null) { | |
268 | return false; | |
269 | } | |
270 | if (!(obj instanceof Cardinality)) { | |
271 | return false; | |
272 | } | |
273 | Cardinality other = (Cardinality) obj; | |
274 | return (this.min == other.min && this.max == other.max); | |
275 | } | |
276 | } | |
277 | ||
278 | @Override | |
279 | public void save() { | |
280 | save(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); | |
281 | } | |
282 | ||
283 | @Override | |
284 | public void save(String path) { | |
285 | try { | |
286 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
287 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
288 | ||
289 | // The following allows xml parsing without access to the dtd | |
290 | EntityResolver resolver = new EntityResolver () { | |
291 | @Override | |
292 | public InputSource resolveEntity (String publicId, String systemId) { | |
293 | String empty = ""; //$NON-NLS-1$ | |
294 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
295 | return new InputSource(bais); | |
296 | } | |
297 | }; | |
298 | db.setEntityResolver(resolver); | |
299 | ||
300 | // The following catches xml parsing exceptions | |
301 | db.setErrorHandler(new ErrorHandler(){ | |
302 | @Override | |
303 | public void error(SAXParseException saxparseexception) throws SAXException {} | |
304 | @Override | |
305 | public void warning(SAXParseException saxparseexception) throws SAXException {} | |
306 | @Override | |
307 | public void fatalError(SAXParseException saxparseexception) throws SAXException { | |
308 | throw saxparseexception; | |
309 | }}); | |
310 | ||
311 | Document doc = null; | |
312 | File file = new File(path); | |
313 | if (file.canRead()) { | |
314 | doc = db.parse(file); | |
315 | if (! doc.getDocumentElement().getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
316 | return; | |
317 | } | |
318 | } else { | |
319 | doc = db.newDocument(); | |
320 | Node node = doc.createElement(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT); | |
321 | doc.appendChild(node); | |
322 | } | |
323 | ||
324 | Element root = doc.getDocumentElement(); | |
325 | ||
326 | NodeList nodeList = root.getChildNodes(); | |
327 | for (int i = 0; i < nodeList.getLength(); i++) { | |
328 | Node node = nodeList.item(i); | |
329 | if (node instanceof Element && | |
330 | node.getNodeName().equals(DEFINITION_ELEMENT) && | |
331 | definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) { | |
332 | root.removeChild(node); | |
333 | } | |
334 | } | |
335 | Element definitionElement = doc.createElement(DEFINITION_ELEMENT); | |
336 | root.appendChild(definitionElement); | |
337 | definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName); | |
338 | ||
339 | Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT); | |
340 | definitionElement.appendChild(formatElement); | |
341 | formatElement.appendChild(doc.createTextNode(timeStampOutputFormat)); | |
342 | ||
343 | if (inputs != null) { | |
344 | for (InputLine inputLine : inputs) { | |
345 | definitionElement.appendChild(createInputLineElement(inputLine, doc)); | |
346 | } | |
347 | } | |
348 | ||
349 | if (outputs != null) { | |
350 | for (OutputColumn output : outputs) { | |
351 | Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT); | |
352 | definitionElement.appendChild(outputColumnElement); | |
353 | outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name); | |
354 | } | |
355 | } | |
356 | ||
357 | Transformer transformer = TransformerFactory.newInstance().newTransformer(); | |
358 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ | |
359 | ||
360 | //initialize StreamResult with File object to save to file | |
361 | StreamResult result = new StreamResult(new StringWriter()); | |
362 | DOMSource source = new DOMSource(doc); | |
363 | transformer.transform(source, result); | |
364 | String xmlString = result.getWriter().toString(); | |
365 | ||
366 | FileWriter writer = new FileWriter(file); | |
367 | writer.write(xmlString); | |
368 | writer.close(); | |
369 | } catch (ParserConfigurationException e) { | |
370 | Activator.getDefault().logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
371 | } catch (TransformerConfigurationException e) { | |
372 | Activator.getDefault().logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
373 | } catch (TransformerFactoryConfigurationError e) { | |
374 | Activator.getDefault().logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
375 | } catch (TransformerException e) { | |
376 | Activator.getDefault().logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
377 | } catch (IOException e) { | |
378 | Activator.getDefault().logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
379 | } catch (SAXException e) { | |
380 | Activator.getDefault().logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
381 | } | |
382 | } | |
383 | ||
384 | private Element createInputLineElement(InputLine inputLine, Document doc) { | |
385 | Element inputLineElement = doc.createElement(INPUT_LINE_ELEMENT); | |
386 | ||
387 | Element cardinalityElement = doc.createElement(CARDINALITY_ELEMENT); | |
388 | inputLineElement.appendChild(cardinalityElement); | |
389 | cardinalityElement.setAttribute(MIN_ATTRIBUTE, Integer.toString(inputLine.cardinality.min)); | |
390 | cardinalityElement.setAttribute(MAX_ATTRIBUTE, Integer.toString(inputLine.cardinality.max)); | |
391 | ||
392 | Element regexElement = doc.createElement(REGEX_ELEMENT); | |
393 | inputLineElement.appendChild(regexElement); | |
394 | regexElement.appendChild(doc.createTextNode(inputLine.regex)); | |
395 | ||
396 | if (inputLine.columns != null) { | |
397 | for (InputData inputData : inputLine.columns) { | |
398 | Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); | |
399 | inputLineElement.appendChild(inputDataElement); | |
400 | inputDataElement.setAttribute(NAME_ATTRIBUTE, inputData.name); | |
401 | inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputData.action)); | |
402 | if (inputData.format != null) { | |
403 | inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputData.format); | |
404 | } | |
405 | } | |
406 | } | |
407 | ||
408 | if (inputLine.childrenInputs != null) { | |
409 | for (InputLine childInputLine : inputLine.childrenInputs) { | |
410 | inputLineElement.appendChild(createInputLineElement(childInputLine, doc)); | |
411 | } | |
412 | } | |
413 | ||
414 | return inputLineElement; | |
415 | } | |
416 | ||
417 | public static CustomTxtTraceDefinition[] loadAll() { | |
418 | return loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); | |
419 | } | |
420 | ||
421 | public static CustomTxtTraceDefinition[] loadAll(String path) { | |
422 | try { | |
423 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
424 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
425 | ||
426 | // The following allows xml parsing without access to the dtd | |
427 | EntityResolver resolver = new EntityResolver () { | |
428 | @Override | |
429 | public InputSource resolveEntity (String publicId, String systemId) { | |
430 | String empty = ""; //$NON-NLS-1$ | |
431 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
432 | return new InputSource(bais); | |
433 | } | |
434 | }; | |
435 | db.setEntityResolver(resolver); | |
436 | ||
437 | // The following catches xml parsing exceptions | |
438 | db.setErrorHandler(new ErrorHandler(){ | |
439 | @Override | |
440 | public void error(SAXParseException saxparseexception) throws SAXException {} | |
441 | @Override | |
442 | public void warning(SAXParseException saxparseexception) throws SAXException {} | |
443 | @Override | |
444 | public void fatalError(SAXParseException saxparseexception) throws SAXException { | |
445 | throw saxparseexception; | |
446 | }}); | |
447 | ||
448 | File file = new File(path); | |
449 | if (!file.canRead()) { | |
450 | return new CustomTxtTraceDefinition[0]; | |
451 | } | |
452 | Document doc = db.parse(file); | |
453 | ||
454 | Element root = doc.getDocumentElement(); | |
455 | if (! root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
456 | return new CustomTxtTraceDefinition[0]; | |
457 | } | |
458 | ||
459 | ArrayList<CustomTxtTraceDefinition> defList = new ArrayList<CustomTxtTraceDefinition>(); | |
460 | NodeList nodeList = root.getChildNodes(); | |
461 | for (int i = 0; i < nodeList.getLength(); i++) { | |
462 | Node node = nodeList.item(i); | |
463 | if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { | |
464 | CustomTxtTraceDefinition def = extractDefinition((Element) node); | |
465 | if (def != null) { | |
466 | defList.add(def); | |
467 | } | |
468 | } | |
469 | } | |
470 | return defList.toArray(new CustomTxtTraceDefinition[0]); | |
471 | } catch (ParserConfigurationException e) { | |
472 | Activator.getDefault().logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
473 | } catch (SAXException e) { | |
474 | Activator.getDefault().logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
475 | } catch (IOException e) { | |
476 | Activator.getDefault().logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
477 | } | |
478 | return new CustomTxtTraceDefinition[0]; | |
479 | } | |
480 | ||
481 | public static CustomTxtTraceDefinition load(String definitionName) { | |
482 | try { | |
483 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
484 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
485 | ||
486 | // The following allows xml parsing without access to the dtd | |
487 | EntityResolver resolver = new EntityResolver () { | |
488 | @Override | |
489 | public InputSource resolveEntity (String publicId, String systemId) { | |
490 | String empty = ""; //$NON-NLS-1$ | |
491 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
492 | return new InputSource(bais); | |
493 | } | |
494 | }; | |
495 | db.setEntityResolver(resolver); | |
496 | ||
497 | // The following catches xml parsing exceptions | |
498 | db.setErrorHandler(new ErrorHandler(){ | |
499 | @Override | |
500 | public void error(SAXParseException saxparseexception) throws SAXException {} | |
501 | @Override | |
502 | public void warning(SAXParseException saxparseexception) throws SAXException {} | |
503 | @Override | |
504 | public void fatalError(SAXParseException saxparseexception) throws SAXException { | |
505 | throw saxparseexception; | |
506 | }}); | |
507 | ||
508 | File file = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); | |
509 | Document doc = db.parse(file); | |
510 | ||
511 | Element root = doc.getDocumentElement(); | |
512 | if (! root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
513 | return null; | |
514 | } | |
515 | ||
516 | NodeList nodeList = root.getChildNodes(); | |
517 | for (int i = 0; i < nodeList.getLength(); i++) { | |
518 | Node node = nodeList.item(i); | |
519 | if (node instanceof Element && | |
520 | node.getNodeName().equals(DEFINITION_ELEMENT) && | |
521 | definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) { | |
522 | return extractDefinition((Element) node); | |
523 | } | |
524 | } | |
525 | } catch (ParserConfigurationException e) { | |
526 | Activator.getDefault().logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
527 | } catch (SAXException e) { | |
528 | Activator.getDefault().logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
529 | } catch (IOException e) { | |
530 | Activator.getDefault().logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
531 | } | |
532 | return null; | |
533 | } | |
534 | ||
535 | public static CustomTxtTraceDefinition extractDefinition(Element definitionElement) { | |
536 | CustomTxtTraceDefinition def = new CustomTxtTraceDefinition(); | |
537 | ||
538 | def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE); | |
539 | if (def.definitionName == null) { | |
540 | return null; | |
541 | } | |
542 | ||
543 | NodeList nodeList = definitionElement.getChildNodes(); | |
544 | for (int i = 0; i < nodeList.getLength(); i++) { | |
545 | Node node = nodeList.item(i); | |
546 | String nodeName = node.getNodeName(); | |
547 | if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) { | |
548 | Element formatElement = (Element) node; | |
549 | def.timeStampOutputFormat = formatElement.getTextContent(); | |
550 | } else if (nodeName.equals(INPUT_LINE_ELEMENT)) { | |
551 | InputLine inputLine = extractInputLine((Element) node); | |
552 | if (inputLine != null) { | |
553 | def.inputs.add(inputLine); | |
554 | } | |
555 | } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) { | |
556 | Element outputColumnElement = (Element) node; | |
557 | OutputColumn outputColumn = new OutputColumn(); | |
558 | outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE); | |
559 | def.outputs.add(outputColumn); | |
560 | } | |
561 | } | |
562 | return def; | |
563 | } | |
564 | ||
565 | private static InputLine extractInputLine(Element inputLineElement) { | |
566 | InputLine inputLine = new InputLine(); | |
567 | NodeList nodeList = inputLineElement.getChildNodes(); | |
568 | for (int i = 0; i < nodeList.getLength(); i++) { | |
569 | Node node = nodeList.item(i); | |
570 | String nodeName = node.getNodeName(); | |
571 | if (nodeName.equals(CARDINALITY_ELEMENT)) { | |
572 | Element cardinalityElement = (Element) node; | |
573 | try { | |
574 | int min = Integer.parseInt(cardinalityElement.getAttribute(MIN_ATTRIBUTE)); | |
575 | int max = Integer.parseInt(cardinalityElement.getAttribute(MAX_ATTRIBUTE)); | |
576 | inputLine.cardinality = new Cardinality(min, max); | |
577 | } catch (NumberFormatException e) { | |
578 | return null; | |
579 | } | |
580 | } else if (nodeName.equals(REGEX_ELEMENT)) { | |
581 | Element regexElement = (Element) node; | |
582 | inputLine.regex = regexElement.getTextContent(); | |
583 | } else if (nodeName.equals(INPUT_DATA_ELEMENT)) { | |
584 | Element inputDataElement = (Element) node; | |
585 | InputData inputData = new InputData(); | |
586 | inputData.name = inputDataElement.getAttribute(NAME_ATTRIBUTE); | |
587 | inputData.action = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); | |
588 | inputData.format = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); | |
589 | inputLine.addColumn(inputData); | |
590 | } else if (nodeName.equals(INPUT_LINE_ELEMENT)) { | |
591 | Element childInputLineElement = (Element) node; | |
592 | InputLine childInputLine = extractInputLine(childInputLineElement); | |
593 | if (childInputLine != null) { | |
594 | inputLine.addChild(childInputLine); | |
595 | } | |
596 | } | |
597 | } | |
598 | return inputLine; | |
599 | } | |
600 | ||
601 | public static void delete(String definitionName) { | |
602 | try { | |
603 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
604 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
605 | ||
606 | // The following allows xml parsing without access to the dtd | |
607 | EntityResolver resolver = new EntityResolver () { | |
608 | @Override | |
609 | public InputSource resolveEntity (String publicId, String systemId) { | |
610 | String empty = ""; //$NON-NLS-1$ | |
611 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
612 | return new InputSource(bais); | |
613 | } | |
614 | }; | |
615 | db.setEntityResolver(resolver); | |
616 | ||
617 | // The following catches xml parsing exceptions | |
618 | db.setErrorHandler(new ErrorHandler(){ | |
619 | @Override | |
620 | public void error(SAXParseException saxparseexception) throws SAXException {} | |
621 | @Override | |
622 | public void warning(SAXParseException saxparseexception) throws SAXException {} | |
623 | @Override | |
624 | public void fatalError(SAXParseException saxparseexception) throws SAXException { | |
625 | throw saxparseexception; | |
626 | }}); | |
627 | ||
628 | File file = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); | |
629 | Document doc = db.parse(file); | |
630 | ||
631 | Element root = doc.getDocumentElement(); | |
632 | if (! root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
633 | return; | |
634 | } | |
635 | ||
636 | NodeList nodeList = root.getChildNodes(); | |
637 | for (int i = 0; i < nodeList.getLength(); i++) { | |
638 | Node node = nodeList.item(i); | |
639 | if (node instanceof Element && | |
640 | node.getNodeName().equals(DEFINITION_ELEMENT) && | |
641 | definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) { | |
642 | root.removeChild(node); | |
643 | } | |
644 | } | |
645 | ||
646 | Transformer transformer = TransformerFactory.newInstance().newTransformer(); | |
647 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ | |
648 | ||
649 | //initialize StreamResult with File object to save to file | |
650 | StreamResult result = new StreamResult(new StringWriter()); | |
651 | DOMSource source = new DOMSource(doc); | |
652 | transformer.transform(source, result); | |
653 | String xmlString = result.getWriter().toString(); | |
654 | ||
655 | FileWriter writer = new FileWriter(file); | |
656 | writer.write(xmlString); | |
657 | writer.close(); | |
658 | } catch (ParserConfigurationException e) { | |
659 | Activator.getDefault().logError("Error deleting CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
660 | } catch (SAXException e) { | |
661 | Activator.getDefault().logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$ | |
662 | } catch (IOException e) { | |
663 | Activator.getDefault().logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$ | |
664 | } catch (TransformerConfigurationException e) { | |
665 | Activator.getDefault().logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$ | |
666 | } catch (TransformerFactoryConfigurationError e) { | |
667 | Activator.getDefault().logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$ | |
668 | } catch (TransformerException e) { | |
669 | Activator.getDefault().logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$ | |
670 | } | |
671 | } | |
672 | } |