001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: Xml2Data.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.xml;
009:
010: import com.uwyn.rife.config.Config;
011: import com.uwyn.rife.config.RifeConfig;
012: import com.uwyn.rife.rep.Rep;
013: import com.uwyn.rife.resources.ResourceFinder;
014: import com.uwyn.rife.resources.ResourceFinderClasspath;
015: import com.uwyn.rife.tools.StringUtils;
016: import com.uwyn.rife.xml.exceptions.FatalParsingErrorsException;
017: import com.uwyn.rife.xml.exceptions.ParserCreationErrorException;
018: import com.uwyn.rife.xml.exceptions.ParserExecutionErrorException;
019: import com.uwyn.rife.xml.exceptions.XmlErrorException;
020: import java.io.IOException;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.logging.Logger;
024: import org.xml.sax.SAXException;
025: import org.xml.sax.SAXParseException;
026: import org.xml.sax.XMLReader;
027: import org.xml.sax.helpers.DefaultHandler;
028: import org.xml.sax.helpers.XMLReaderFactory;
029:
030: public abstract class Xml2Data extends DefaultHandler {
031: private boolean mDisableValidation = false;
032: private boolean mEnableValidation = false;
033: private XmlErrorRedirector mErrorRedirector = null;
034: private String mXmlPath = null;
035: private ResourceFinder mResourceFinder = null;
036:
037: public void disableValidation(boolean activation) {
038: mDisableValidation = activation;
039: if (activation) {
040: mEnableValidation = false;
041: }
042: }
043:
044: public void enableValidation(boolean activation) {
045: mEnableValidation = activation;
046: if (activation) {
047: mDisableValidation = false;
048: }
049: }
050:
051: public void warning(SAXParseException e) {
052: mErrorRedirector.warning(e);
053: }
054:
055: public void error(SAXParseException e) {
056: mErrorRedirector.error(e);
057: }
058:
059: public void fatalError(SAXParseException e) {
060: mErrorRedirector.fatalError(e);
061: }
062:
063: protected String getXmlPath() {
064: return mXmlPath;
065: }
066:
067: protected ResourceFinder getResourceFinder() {
068: return mResourceFinder;
069: }
070:
071: protected XmlErrorRedirector getErrorRedirector() {
072: return mErrorRedirector;
073: }
074:
075: protected XmlErrorRedirector createErrorRedirector() {
076: return new ExceptionErrorRedirector(this );
077: }
078:
079: public synchronized XMLReader processXml(String xmlPath)
080: throws XmlErrorException {
081: return processXml(xmlPath, ResourceFinderClasspath
082: .getInstance(), null);
083: }
084:
085: public synchronized XMLReader processXml(String xmlPath,
086: ResourceFinder resourceFinder) throws XmlErrorException {
087: return processXml(xmlPath, resourceFinder, null);
088: }
089:
090: public synchronized XMLReader processXml(String xmlPath,
091: ResourceFinder resourceFinder, XMLReader reader)
092: throws XmlErrorException {
093: if (null == xmlPath)
094: throw new IllegalArgumentException("xmlPath can't be null.");
095: if (xmlPath.length() == 0)
096: throw new IllegalArgumentException(
097: "xmlPath can't be empty.");
098: if (null == resourceFinder)
099: throw new IllegalArgumentException(
100: "resourceFinder can't be null.");
101:
102: XmlInputSource inputsource = new XmlInputSource(xmlPath,
103: resourceFinder);
104:
105: mXmlPath = xmlPath;
106: mResourceFinder = resourceFinder;
107: mErrorRedirector = createErrorRedirector();
108:
109: XmlEntityResolver entity_resolver = new XmlEntityResolver(
110: resourceFinder);
111:
112: if (null == reader) {
113: try {
114: reader = XMLReaderFactory.createXMLReader();
115: } catch (SAXException e) {
116: try {
117: // JDK 1.4 default parser
118: reader = XMLReaderFactory
119: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
120: } catch (SAXException e2) {
121: throw new ParserCreationErrorException(xmlPath, e);
122: }
123: }
124: }
125:
126: reader.setContentHandler(this );
127: reader.setEntityResolver(entity_resolver);
128: reader.setErrorHandler(mErrorRedirector);
129:
130: try {
131: if (mEnableValidation
132: || (!mDisableValidation && (!Config
133: .hasRepInstance()
134: || !Rep.getParticipant("ParticipantConfig")
135: .isFinished() || RifeConfig.Xml
136: .getXmlValidation()))) {
137: reader.setFeature(
138: "http://xml.org/sax/features/validation", true);
139: } else {
140: reader
141: .setFeature(
142: "http://xml.org/sax/features/validation",
143: false);
144: }
145: } catch (SAXException e) {
146: Logger.getLogger("com.uwyn.rife.xml").warning(
147: "The parser '" + reader.getClass().getName()
148: + "' doesn't support validation.");
149: }
150:
151: try {
152: reader.parse(inputsource);
153: } catch (SAXException e) {
154: if (e.getException() != null
155: && e.getException() instanceof RuntimeException) {
156: throw (RuntimeException) e.getException();
157: } else {
158: throw new ParserExecutionErrorException(xmlPath, e);
159: }
160: } catch (IOException e) {
161: throw new ParserExecutionErrorException(xmlPath, e);
162: }
163:
164: if (mErrorRedirector.hasWarnings()) {
165: Logger.getLogger("com.uwyn.rife.xml").warning(
166: "The following XML warnings occured during the parsing of "
167: + xmlPath
168: + "'.\n"
169: + StringUtils.join(
170: formatExceptions(mErrorRedirector
171: .getWarnings()), "\n"));
172: }
173: if (mErrorRedirector.hasErrors()) {
174: Logger.getLogger("com.uwyn.rife.xml").severe(
175: "The following XML errors occured during the parsing of "
176: + xmlPath
177: + "'.\n"
178: + StringUtils.join(
179: formatExceptions(mErrorRedirector
180: .getErrors()), "\n"));
181: }
182: if (mErrorRedirector.hasFatalErrors()) {
183: throw new FatalParsingErrorsException(xmlPath,
184: formatExceptions(mErrorRedirector.getFatalErrors()));
185: }
186:
187: return reader;
188: }
189:
190: private Collection<String> formatExceptions(
191: Collection<SAXParseException> exceptions) {
192: if (null == exceptions) {
193: return null;
194: }
195:
196: ArrayList<String> result = new ArrayList<String>();
197: for (SAXParseException e : exceptions) {
198: StringBuilder formatted = new StringBuilder();
199: if (e.getSystemId() != null) {
200: formatted.append(e.getSystemId());
201: }
202:
203: if (e.getPublicId() != null) {
204: if (formatted.length() > 0) {
205: formatted.append(", ");
206: }
207: formatted.append(e.getPublicId());
208: }
209:
210: if (e.getLineNumber() >= 0) {
211: if (formatted.length() > 0) {
212: formatted.append(", ");
213: }
214: formatted.append("line ");
215: formatted.append(e.getLineNumber());
216: }
217:
218: if (e.getColumnNumber() >= 0) {
219: if (formatted.length() > 0) {
220: formatted.append(", ");
221: }
222: formatted.append("col ");
223: formatted.append(e.getColumnNumber());
224: }
225:
226: if (formatted.length() > 0) {
227: formatted.append(" : ");
228: }
229: formatted.append(e.getMessage());
230:
231: result.add(formatted.toString());
232: }
233:
234: return result;
235: }
236: }
|