1 package org.jmux.app;
2
3 import org.jmux.app.component.config.Config;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6 import org.xml.sax.Attributes;
7 import org.xml.sax.Locator;
8 import org.xml.sax.SAXException;
9 import org.xml.sax.SAXParseException;
10 import org.xml.sax.helpers.DefaultHandler;
11
12 import javax.xml.parsers.SAXParserFactory;
13 import java.io.File;
14 import java.io.IOException;
15 import java.util.Stack;
16
17 /******************************************************************************
18 jmux - Java Modules Using XML
19 Copyright © 2006 jmux.org
20
21 This library is free software; you can redistribute it and/or
22 modify it under the terms of the GNU Lesser General Public
23 License as published by the Free Software Foundation; either
24 version 2.1 of the License, or (at your option) any later version.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 Lesser General Public License for more details.
30
31 You should have received a copy of the GNU Lesser General Public
32 License along with this library; if not, write to the Free Software
33 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
34 *****************************************************************************/
35
36 /***
37 * @author donaldw
38 */
39 public class ConfigSAXParser extends DefaultHandler {
40 private static Config result;
41 private final File configFile;
42 private Locator locator;
43 private Logger logger = LoggerFactory.getLogger(this.getClass());
44 private Stack<StringBuilder> charStack = new Stack<StringBuilder>();
45 private Stack<ConfigImpl> confStack = new Stack<ConfigImpl>();
46
47 public ConfigSAXParser(File configFile) {
48 this.configFile = configFile;
49 }
50
51 public void parse() {
52 try {
53 SAXParserFactory.newInstance().newSAXParser().parse(configFile, this);
54 } catch (Exception ex) {
55 throw new AppException("Error whilst parsing configFile: ", ex);
56 }
57 }
58
59 public void setDocumentLocator(Locator locator) {
60 super.setDocumentLocator(locator);
61 this.locator = locator;
62 }
63
64 public void warning(SAXParseException saxParseException) {
65 handleProblem("Warning", saxParseException);
66 }
67
68 public void error(SAXParseException saxParseException) {
69 handleProblem("Error", saxParseException);
70 }
71
72 public void fatalError(SAXParseException saxParseException) {
73 handleProblem("Fatal Error", saxParseException);
74 }
75
76 private void handleProblem(String message, SAXParseException saxParseException) {
77 String canonicalPath;
78 try {
79 canonicalPath = configFile.getCanonicalPath();
80 } catch (IOException e) {
81 canonicalPath = configFile.getAbsolutePath();
82 }
83 logger.error(
84 message + " in "
85 + canonicalPath + " at "
86 + locator.getLineNumber() + ':'
87 + locator.getColumnNumber(), saxParseException);
88 }
89
90 public void characters(char[] ch, int start, int length) throws SAXException {
91 StringBuilder sb = charStack.lastElement();
92 sb.append(ch, start, length);
93 }
94
95 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
96 characters(ch, start, length);
97 }
98
99 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
100 start(qName, attributes);
101 }
102
103 public void endElement(String uri, String localName, String qName) throws SAXException {
104 end();
105 }
106
107 public void startDocument() throws SAXException {
108 logger.debug("Starting to parse");
109 }
110
111 public void endDocument() throws SAXException {
112 logger.debug("Finished parsing");
113 }
114
115 private void start(String name, Attributes atts) {
116 ConfigImpl configImpl = new ConfigImpl(name);
117
118
119
120 for (int i = 0; i < atts.getLength(); i++) {
121 ConfigImpl attConfigImpl = new ConfigImpl(atts.getQName(i));
122 attConfigImpl.setValue(atts.getValue(i));
123 configImpl.setConf(attConfigImpl.getName(), attConfigImpl);
124 }
125
126 charStack.push(new StringBuilder());
127 confStack.push(configImpl);
128 }
129
130 private void end() {
131 StringBuilder sb = charStack.pop();
132 ConfigImpl configImpl = confStack.pop();
133 configImpl.setValue(sb.toString().trim());
134
135 if (confStack.size() != 0) {
136 ConfigImpl parent = confStack.lastElement();
137 parent.setConf(configImpl.getName(), configImpl);
138 } else {
139 result = configImpl;
140 }
141 }
142
143 public Config getConfig() {
144 return result;
145 }
146 }
147