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: Jdk14Loader.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.cmf.loader.xhtml;
009:
010: import com.uwyn.rife.cmf.dam.exceptions.ContentManagerException;
011: import com.uwyn.rife.cmf.loader.XhtmlContentLoaderBackend;
012: import com.uwyn.rife.resources.ResourceFinderClasspath;
013: import com.uwyn.rife.template.Template;
014: import com.uwyn.rife.template.TemplateFactory;
015: import com.uwyn.rife.xml.LoggingErrorRedirector;
016: import com.uwyn.rife.xml.XmlEntityResolver;
017: import com.uwyn.rife.xml.XmlErrorRedirector;
018: import com.uwyn.rife.xml.exceptions.XmlErrorException;
019: import java.io.IOException;
020: import java.io.Reader;
021: import java.io.StringReader;
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.Set;
025: import org.xml.sax.InputSource;
026: import org.xml.sax.SAXException;
027: import org.xml.sax.SAXParseException;
028: import org.xml.sax.XMLReader;
029: import org.xml.sax.helpers.DefaultHandler;
030: import org.xml.sax.helpers.XMLReaderFactory;
031:
032: public class Jdk14Loader extends XhtmlContentLoaderBackend {
033: public String loadFromString(String data, boolean fragment,
034: Set<String> errors) throws ContentManagerException {
035: return new LoaderDelegate().load(data, fragment, errors);
036: }
037:
038: public boolean isBackendPresent() {
039: try {
040: return null != Class.forName("org.xml.sax.XMLReader");
041: } catch (ClassNotFoundException e) {
042: return false;
043: }
044: }
045:
046: private static class LoaderDelegate extends DefaultHandler {
047: public String load(String data, boolean fragment,
048: Set<String> errors) throws ContentManagerException {
049: XmlEntityResolver entity_resolver = null;
050: XmlErrorRedirector error_redirector = null;
051:
052: String complete_page = data;
053:
054: Reader reader = null;
055: if (fragment) {
056: Template t = TemplateFactory.XHTML
057: .get("cmf.container.template");
058: t.setValue("fragment", data);
059: complete_page = t.getContent();
060: }
061:
062: reader = new StringReader(complete_page);
063:
064: try {
065: InputSource inputsource = new InputSource(reader);
066:
067: entity_resolver = new XmlEntityResolver(
068: ResourceFinderClasspath.getInstance())
069: .addToCatalog(
070: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
071: "/dtd/cmf/xhtml1-transitional.dtd")
072: .addToCatalog(
073: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",
074: "/dtd/cmf/xhtml1-strict.dtd")
075: .addToCatalog(
076: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd",
077: "/dtd/cmf/xhtml1-frameset.dtd")
078: .addToCatalog(
079: "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent",
080: "/dtd/cmf/xhtml-lat1.ent")
081: .addToCatalog(
082: "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent",
083: "/dtd/cmf/xhtml-symbol.ent")
084: .addToCatalog(
085: "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent",
086: "/dtd/cmf/xhtml-special.ent")
087: .restrictToCatalog(true);
088: error_redirector = new LoggingErrorRedirector();
089:
090: XMLReader xml_reader = null;
091:
092: try {
093: xml_reader = XMLReaderFactory.createXMLReader();
094: } catch (SAXException e) {
095: try {
096: xml_reader = XMLReaderFactory
097: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
098: } catch (SAXException e2) {
099: throw new XmlErrorException(e2);
100: }
101: }
102:
103: xml_reader.setEntityResolver(entity_resolver);
104: xml_reader.setErrorHandler(error_redirector);
105:
106: try {
107: xml_reader.setFeature(
108: "http://xml.org/sax/features/validation",
109: true);
110: } catch (SAXException e) {
111: throw new XmlErrorException("The parser '"
112: + xml_reader.getClass().getName()
113: + "' doesn't support validation.", e);
114: }
115:
116: try {
117: xml_reader.parse(inputsource);
118: } catch (SAXParseException e) {
119: if (errors != null) {
120: errors.add(formatException(fragment, e));
121: }
122: } catch (SAXException e) {
123: if (e.getException() != null
124: && e.getException() instanceof RuntimeException) {
125: throw (RuntimeException) e.getException();
126: } else {
127: throw new XmlErrorException(e);
128: }
129: } catch (IOException e) {
130: throw new XmlErrorException(e);
131: }
132:
133: if (errors != null) {
134: if (error_redirector.hasErrors()) {
135: errors.addAll(formatExceptions(fragment,
136: error_redirector.getErrors()));
137: }
138: if (error_redirector.hasFatalErrors()) {
139: errors.addAll(formatExceptions(fragment,
140: error_redirector.getFatalErrors()));
141: }
142: }
143: } catch (RuntimeException e) {
144: if (errors != null) {
145: errors.add(e.getMessage());
146: }
147: return null;
148: }
149:
150: if ((errors != null && errors.size() > 0)
151: || (error_redirector.hasErrors() || error_redirector
152: .hasFatalErrors())) {
153: return null;
154: }
155:
156: return data;
157: }
158:
159: private Collection<String> formatExceptions(boolean fragment,
160: Collection<SAXParseException> exceptions) {
161: if (null == exceptions) {
162: return null;
163: }
164:
165: ArrayList<String> result = new ArrayList<String>();
166: for (SAXParseException e : exceptions) {
167: result.add(formatException(fragment, e));
168: }
169:
170: return result;
171: }
172:
173: private String formatException(boolean fragment,
174: SAXParseException e) {
175: StringBuilder formatted = new StringBuilder();
176: if (e.getSystemId() != null) {
177: formatted.append(e.getSystemId());
178: }
179:
180: if (e.getPublicId() != null) {
181: if (formatted.length() > 0) {
182: formatted.append(", ");
183: }
184: formatted.append(e.getPublicId());
185: }
186:
187: if (e.getLineNumber() >= 0) {
188: if (formatted.length() > 0) {
189: formatted.append(", ");
190: }
191: formatted.append("line ");
192: if (fragment) {
193: formatted.append(e.getLineNumber() - 3);
194: } else {
195: formatted.append(e.getLineNumber());
196: }
197: }
198:
199: if (e.getColumnNumber() >= 0) {
200: if (formatted.length() > 0) {
201: formatted.append(", ");
202: }
203: formatted.append("col ");
204: formatted.append(e.getColumnNumber());
205: }
206:
207: if (formatted.length() > 0) {
208: formatted.append(" : ");
209: }
210: formatted.append(e.getMessage());
211:
212: return formatted.toString();
213: }
214: }
215: }
|