Major cleanup of Utils class.
[trakem2.git] / ini / trakem2 / tree / TrakEM2MLParser.java
blob66bcbc30034110c66f3db870aead7678773d7782
1 /**
3 TrakEM2 plugin for ImageJ(C).
4 Copyright (C) 2005,2006 Albert Cardona and Rodney Douglas.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation (http://www.gnu.org/licenses/gpl.txt )
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 You may contact Albert Cardona at acardona at ini.phys.ethz.ch
20 Institute of Neuroinformatics, University of Zurich / ETH, Switzerland.
21 **/
23 package ini.trakem2.tree;
26 import org.xml.sax.helpers.DefaultHandler;
27 import org.xml.sax.SAXException;
28 import org.xml.sax.SAXParseException;
29 import org.xml.sax.InputSource;
30 import org.xml.sax.Attributes;
31 import java.io.InputStream;
32 import java.io.BufferedInputStream;
33 import java.io.FileInputStream;
34 import java.util.ArrayList;
36 import javax.xml.parsers.SAXParserFactory;
37 import javax.xml.parsers.SAXParser;
39 import ini.trakem2.utils.IJError;
40 import ini.trakem2.utils.Utils;
43 /**
44 * A class to parse a file in TrakEM2 XML format.
47 public class TrakEM2MLParser {
49 /** The root element of the template. */
50 TemplateThing root = null;
52 public TrakEM2MLParser(String file_path) {
53 InputStream i_stream = null;
54 try {
55 /* // I don't have this apache parser!
56 XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
57 org.xml.sax.ContentHandler handler = new TrakEM2MLHandler();
58 parser.setContentHandler(handler);
59 i_stream = new BufferedInputStream(new FileInputStream(file_path));
60 InputSource input_source = new InputSource(i_stream);
61 parser.parse(input_source);
64 //trying internal java parser
65 SAXParserFactory factory = SAXParserFactory.newInstance();
66 factory.setValidating(true);
67 SAXParser parser = factory.newSAXParser();
68 //SAXParserFactory.newSAXParser();
69 i_stream = new BufferedInputStream(new FileInputStream(file_path));
70 InputSource input_source = new InputSource(i_stream);
71 org.xml.sax.helpers.DefaultHandler handler = new TrakEM2MLHandler();
72 parser.parse(input_source, handler);
74 } catch (Exception e) {
75 IJError.print(e);
76 } finally {
77 if (null != i_stream) {
78 try {
79 i_stream.close();
80 } catch (Exception e) {
81 IJError.print(e);
87 /** Note: will close the xml_stream. */
88 public TrakEM2MLParser(InputStream xml_stream) {
89 try {
90 //internal java parser
91 SAXParserFactory factory = SAXParserFactory.newInstance();
92 factory.setValidating(true);
93 SAXParser parser = factory.newSAXParser();
94 //SAXParserFactory.newSAXParser();
95 InputSource input_source = new InputSource(xml_stream);
96 org.xml.sax.helpers.DefaultHandler handler = new TrakEM2MLHandler();
97 parser.parse(input_source, handler);
99 } catch (Exception e) {
100 IJError.print(e);
101 } finally {
102 if (null != xml_stream) {
103 try {
104 xml_stream.close();
105 } catch (Exception e) {
106 IJError.print(e);
112 /** Get the root node of the parsed XML template tree. */
113 public TemplateThing getTemplateRoot() {
114 return root;
117 /** This handle class constructs the hierarchical tree of TemplateThing objects. */
118 class TrakEM2MLHandler extends DefaultHandler {
120 private TemplateThing current_thing = null;
121 private ArrayList al_open = new ArrayList();
123 public void startElement(String namespace_URI, String local_name, String qualified_name, Attributes attributes) throws SAXException {
125 //debug:
126 //Utils.log("local_name: " + local_name);
127 //Utils.log("qualified_name: " + qualified_name);
129 //create a new Thing
130 TemplateThing new_thing = new TemplateThing(qualified_name);
131 //set the new_thing as the current (to call setValue(String) on it later in the void character(...) method):
132 current_thing = new_thing;
133 // set the new_thing as the root if there is no root yet
134 if (null == root) {
135 root = new_thing;
137 //set attributes:
138 int n_attributes = attributes.getLength();
139 for (int a=0; a<n_attributes; a++) {
140 //debug:
141 //Utils.log("getLocalName(a)=" + attributes.getQName(a));
142 //Utils.log("local: " + attributes.getLocalName(a) + " qname: " + attributes.getQName(a) + " type: " + attributes.getType(a)); // local prints empty
143 if (!new_thing.addAttribute(attributes.getQName(a), attributes.getValue(a))) {
144 Utils.log("Could not add attribute " + attributes.getQName(a) +" to the TemplateThing " + new_thing);
147 // get the previously open thing and add this new_thing to it as a child
148 int size = al_open.size();
149 if (size > 0) {
150 TemplateThing parent = (TemplateThing)al_open.get(size -1);
151 parent.addChild(new_thing);
153 //set the new Thing as open
154 al_open.add(new_thing);
157 public void endElement(String namespace_URI, String local_name, String qualified_name) {
158 // iterate over all open things and find the one that matches the local_name, and set it closed (pop it out of the list):
159 for (int i=al_open.size() -1; i>-1; i--) {
160 TemplateThing tt = (TemplateThing)al_open.get(i);
161 if (tt.getType().equals(qualified_name)) {
162 al_open.remove(tt);
163 break;
168 public void characters(char[] c, int start, int length) {
169 //Utils.log("Characters: " + new String(c));
170 if (length > 0) {
171 String value = new String(c, start, length).trim();
172 if (value.length() > 0) {
173 current_thing.setValue(value);
177 //now check if in the same line of the start element there is a closing element, since in such a case the endElement method below would never be closed:
178 String type = current_thing.getType();
179 String line = new String(c);
180 if (-1 != line.indexOf("/" + type)) {
181 //debug:
182 //Utils.log("calling endElement from characters");
183 endElement(null, null, type);
187 public void fatalError(SAXParseException e) /*throws SAXParseException */{
188 Utils.log("Fatal error: column=" + e.getColumnNumber() + " line=" + e.getLineNumber());
189 // signal:
190 root = null;
193 public void skippedEntity(String name) {
194 Utils.log("SAX Parser has skipped: " + name);
197 public void notationDeclaration(String name, String publicId, String systemId) {
198 Utils.log("Notation declaration: " + name + ", " + publicId + ", " + systemId);
201 public void warning(SAXParseException e) {
202 Utils.log("SAXParseException : " + e);