/* * Copyright 2001-2008 Geert Bevin <gbevin[remove] at uwyn dot com> * Licensed under the Apache License, Version 2.0 (the "License") * $Id: Jdk14Loader.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.cmf.loader.xhtml; import com.uwyn.rife.cmf.dam.exceptions.ContentManagerException; import com.uwyn.rife.cmf.loader.XhtmlContentLoaderBackend; import com.uwyn.rife.resources.ResourceFinderClasspath; import com.uwyn.rife.template.Template; import com.uwyn.rife.template.TemplateFactory; import com.uwyn.rife.xml.LoggingErrorRedirector; import com.uwyn.rife.xml.XmlEntityResolver; import com.uwyn.rife.xml.XmlErrorRedirector; import com.uwyn.rife.xml.exceptions.XmlErrorException; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import java.util.Set; import org.xml.sax.InputSource; 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 class Jdk14Loader extends XhtmlContentLoaderBackend { public String loadFromString(String data, boolean fragment, Set<String> errors) throws ContentManagerException { return new LoaderDelegate().load(data, fragment, errors); } public boolean isBackendPresent() { try { return null != Class.forName("org.xml.sax.XMLReader"); } catch (ClassNotFoundException e) { return false; } } private static class LoaderDelegate extends DefaultHandler { public String load(String data, boolean fragment, Set<String> errors) throws ContentManagerException { XmlEntityResolver entity_resolver = null; XmlErrorRedirector error_redirector = null; String complete_page = data; Reader reader = null; if (fragment) { Template t = TemplateFactory.XHTML.get("cmf.container.template"); t.setValue("fragment", data); complete_page = t.getContent(); } reader = new StringReader(complete_page); try { InputSource inputsource = new InputSource(reader); entity_resolver = new XmlEntityResolver(ResourceFinderClasspath.getInstance()) .addToCatalog("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "/dtd/cmf/xhtml1-transitional.dtd") .addToCatalog("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", "/dtd/cmf/xhtml1-strict.dtd") .addToCatalog("http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd", "/dtd/cmf/xhtml1-frameset.dtd") .addToCatalog("http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent", "/dtd/cmf/xhtml-lat1.ent") .addToCatalog("http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent", "/dtd/cmf/xhtml-symbol.ent") .addToCatalog("http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent", "/dtd/cmf/xhtml-special.ent") .restrictToCatalog(true); error_redirector = new LoggingErrorRedirector(); XMLReader xml_reader = null; try { xml_reader = XMLReaderFactory.createXMLReader(); } catch (SAXException e) { try { xml_reader = XMLReaderFactory.createXMLReader("org.apache.crimson.parser.XMLReaderImpl"); } catch (SAXException e2) { throw new XmlErrorException(e2); } } xml_reader.setEntityResolver(entity_resolver); xml_reader.setErrorHandler(error_redirector); try { xml_reader.setFeature("http://xml.org/sax/features/validation", true); } catch (SAXException e) { throw new XmlErrorException("The parser '"+xml_reader.getClass().getName()+"' doesn't support validation.", e); } try { xml_reader.parse(inputsource); } catch (SAXParseException e) { if (errors != null) { errors.add(formatException(fragment, e)); } } catch (SAXException e) { if (e.getException() != null && e.getException() instanceof RuntimeException) { throw (RuntimeException)e.getException(); } else { throw new XmlErrorException(e); } } catch (IOException e) { throw new XmlErrorException(e); } if (errors != null) { if (error_redirector.hasErrors()) { errors.addAll(formatExceptions(fragment, error_redirector.getErrors())); } if (error_redirector.hasFatalErrors()) { errors.addAll(formatExceptions(fragment, error_redirector.getFatalErrors())); } } } catch (RuntimeException e) { if (errors != null) { errors.add(e.getMessage()); } return null; } if ((errors != null && errors.size() > 0) || (error_redirector.hasErrors() || error_redirector.hasFatalErrors())) { return null; } return data; } private Collection<String> formatExceptions(boolean fragment, Collection<SAXParseException> exceptions) { if (null == exceptions) { return null; } ArrayList<String> result = new ArrayList<String>(); for (SAXParseException e : exceptions) { result.add(formatException(fragment, e)); } return result; } private String formatException(boolean fragment, SAXParseException e) { 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 "); if (fragment) { formatted.append(e.getLineNumber()-3); } else { 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()); return formatted.toString(); } } }