/* * Copyright 2001-2008 Geert Bevin <gbevin[remove] at uwyn dot com> * Licensed under the Apache License, Version 2.0 (the "License") * $Id: Xml2Data.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.xml; import com.uwyn.rife.config.Config; import com.uwyn.rife.config.RifeConfig; import com.uwyn.rife.rep.Rep; import com.uwyn.rife.resources.ResourceFinder; import com.uwyn.rife.resources.ResourceFinderClasspath; import com.uwyn.rife.tools.StringUtils; import com.uwyn.rife.xml.exceptions.FatalParsingErrorsException; import com.uwyn.rife.xml.exceptions.ParserCreationErrorException; import com.uwyn.rife.xml.exceptions.ParserExecutionErrorException; import com.uwyn.rife.xml.exceptions.XmlErrorException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.logging.Logger; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory; public abstract class Xml2Data extends DefaultHandler { private boolean mDisableValidation = false; private boolean mEnableValidation = false; private XmlErrorRedirector mErrorRedirector = null; private String mXmlPath = null; private ResourceFinder mResourceFinder = null; public void disableValidation(boolean activation) { mDisableValidation = activation; if (activation) { mEnableValidation = false; } } public void enableValidation(boolean activation) { mEnableValidation = activation; if (activation) { mDisableValidation = false; } } public void warning(SAXParseException e) { mErrorRedirector.warning(e); } public void error(SAXParseException e) { mErrorRedirector.error(e); } public void fatalError(SAXParseException e) { mErrorRedirector.fatalError(e); } protected String getXmlPath() { return mXmlPath; } protected ResourceFinder getResourceFinder() { return mResourceFinder; } protected XmlErrorRedirector getErrorRedirector() { return mErrorRedirector; } protected XmlErrorRedirector createErrorRedirector() { return new ExceptionErrorRedirector(this); } public synchronized XMLReader processXml(String xmlPath) throws XmlErrorException { return processXml(xmlPath, ResourceFinderClasspath.getInstance(), null); } public synchronized XMLReader processXml(String xmlPath, ResourceFinder resourceFinder) throws XmlErrorException { return processXml(xmlPath, resourceFinder, null); } public synchronized XMLReader processXml(String xmlPath, ResourceFinder resourceFinder, XMLReader reader) throws XmlErrorException { if (null == xmlPath) throw new IllegalArgumentException("xmlPath can't be null."); if (xmlPath.length() == 0) throw new IllegalArgumentException("xmlPath can't be empty."); if (null == resourceFinder) throw new IllegalArgumentException("resourceFinder can't be null."); XmlInputSource inputsource = new XmlInputSource(xmlPath, resourceFinder); mXmlPath = xmlPath; mResourceFinder = resourceFinder; mErrorRedirector = createErrorRedirector(); XmlEntityResolver entity_resolver = new XmlEntityResolver(resourceFinder); if (null == reader) { try { reader = XMLReaderFactory.createXMLReader(); } catch (SAXException e) { try { // JDK 1.4 default parser reader = XMLReaderFactory.createXMLReader("org.apache.crimson.parser.XMLReaderImpl"); } catch (SAXException e2) { throw new ParserCreationErrorException(xmlPath, e); } } } reader.setContentHandler(this); reader.setEntityResolver(entity_resolver); reader.setErrorHandler(mErrorRedirector); try { if (mEnableValidation || (!mDisableValidation && (!Config.hasRepInstance() || !Rep.getParticipant("ParticipantConfig").isFinished() || RifeConfig.Xml.getXmlValidation()))) { reader.setFeature("http://xml.org/sax/features/validation", true); } else { reader.setFeature("http://xml.org/sax/features/validation", false); } } catch (SAXException e) { Logger.getLogger("com.uwyn.rife.xml").warning("The parser '"+reader.getClass().getName()+"' doesn't support validation."); } try { reader.parse(inputsource); } catch (SAXException e) { if (e.getException() != null && e.getException() instanceof RuntimeException) { throw (RuntimeException)e.getException(); } else { throw new ParserExecutionErrorException(xmlPath, e); } } catch (IOException e) { throw new ParserExecutionErrorException(xmlPath, e); } if (mErrorRedirector.hasWarnings()) { Logger.getLogger("com.uwyn.rife.xml").warning("The following XML warnings occured during the parsing of "+xmlPath+"'.\n"+StringUtils.join(formatExceptions(mErrorRedirector.getWarnings()), "\n")); } if (mErrorRedirector.hasErrors()) { Logger.getLogger("com.uwyn.rife.xml").severe("The following XML errors occured during the parsing of "+xmlPath+"'.\n"+StringUtils.join(formatExceptions(mErrorRedirector.getErrors()), "\n")); } if (mErrorRedirector.hasFatalErrors()) { throw new FatalParsingErrorsException(xmlPath, formatExceptions(mErrorRedirector.getFatalErrors())); } return reader; } private Collection<String> formatExceptions(Collection<SAXParseException> exceptions) { if (null == exceptions) { return null; } ArrayList<String> result = new ArrayList<String>(); for (SAXParseException e: exceptions) { StringBuilder formatted = new StringBuilder(); if (e.getSystemId() != null) { formatted.append(e.getSystemId()); } if (e.getPublicId() != null) { if (formatted.length() > 0) { formatted.append(", "); } formatted.append(e.getPublicId()); } if (e.getLineNumber() >= 0) { if (formatted.length() > 0) { formatted.append(", "); } formatted.append("line "); formatted.append(e.getLineNumber()); } if (e.getColumnNumber() >= 0) { if (formatted.length() > 0) { formatted.append(", "); } formatted.append("col "); formatted.append(e.getColumnNumber()); } if (formatted.length() > 0) { formatted.append(" : "); } formatted.append(e.getMessage()); result.add(formatted.toString()); } return result; } }