001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.intro.impl.model.loader;
011:
012: import java.io.IOException;
013: import java.io.StringReader;
014: import java.io.StringWriter;
015:
016: import javax.xml.parsers.DocumentBuilder;
017: import javax.xml.parsers.DocumentBuilderFactory;
018: import javax.xml.parsers.ParserConfigurationException;
019: import javax.xml.transform.OutputKeys;
020: import javax.xml.transform.Transformer;
021: import javax.xml.transform.TransformerConfigurationException;
022: import javax.xml.transform.TransformerException;
023: import javax.xml.transform.TransformerFactory;
024: import javax.xml.transform.dom.DOMSource;
025: import javax.xml.transform.stream.StreamResult;
026:
027: import org.eclipse.ui.internal.intro.impl.util.Log;
028: import org.w3c.dom.Document;
029: import org.w3c.dom.DocumentType;
030: import org.w3c.dom.Element;
031: import org.xml.sax.EntityResolver;
032: import org.xml.sax.InputSource;
033: import org.xml.sax.SAXException;
034: import org.xml.sax.SAXParseException;
035:
036: /**
037: *
038: */
039: public class IntroContentParser {
040:
041: private static String TAG_INTRO_CONTENT = "introContent"; //$NON-NLS-1$
042: private static String TAG_HTML = "html"; //$NON-NLS-1$
043:
044: private Document document;
045: private boolean hasXHTMLContent;
046:
047: /**
048: * Creates a config parser assuming that the passed content represents a URL
049: * to the content file.
050: */
051: public IntroContentParser(String content) {
052: try {
053: document = parse(content);
054: if (document != null) {
055: // xml file is loaded. It can be either XHTML or intro XML.
056: Element rootElement = document.getDocumentElement();
057: // DocumentType docType = document.getDoctype();
058: if (rootElement.getTagName().equals(TAG_INTRO_CONTENT)) {
059: // intro xml file.
060: hasXHTMLContent = false;
061: } else if (rootElement.getTagName().equals(TAG_HTML)) {
062: // rely on root element to detect if we have an XHTML file
063: // and not on doctype. We need to support xhtml files with
064: // no doctype.
065: hasXHTMLContent = true;
066: } else
067: // not intro XML nor XHTML.
068: document = null;
069: }
070: } catch (Exception e) {
071: Log.error(
072: "Could not load Intro content file: " + content, e); //$NON-NLS-1$
073: }
074: }
075:
076: private Document parse(String fileURI) {
077: Document document = null;
078: try {
079: DocumentBuilderFactory docFactory = DocumentBuilderFactory
080: .newInstance();
081: docFactory.setValidating(false);
082: // if this is not set, Document.getElementsByTagNameNS() will fail.
083: docFactory.setNamespaceAware(true);
084: docFactory.setExpandEntityReferences(false);
085: DocumentBuilder parser = docFactory.newDocumentBuilder();
086: parser.setEntityResolver(new EntityResolver() {
087: public InputSource resolveEntity(String publicId,
088: String systemId) throws SAXException {
089: return new InputSource(new StringReader("")); //$NON-NLS-1$
090: }
091: });
092: document = parser.parse(fileURI);
093: return document;
094:
095: } catch (SAXParseException spe) {
096: StringBuffer buffer = new StringBuffer(
097: "IntroParser error in line "); //$NON-NLS-1$
098: buffer.append(spe.getLineNumber());
099: buffer.append(", uri "); //$NON-NLS-1$
100: buffer.append(spe.getSystemId());
101: buffer.append("\n"); //$NON-NLS-1$
102: buffer.append(spe.getMessage());
103:
104: // Use the contained exception.
105: Exception x = spe;
106: if (spe.getException() != null)
107: x = spe.getException();
108: Log.error(buffer.toString(), x);
109:
110: } catch (SAXException sxe) {
111: Exception x = sxe;
112: if (sxe.getException() != null)
113: x = sxe.getException();
114: Log.error(x.getMessage(), x);
115:
116: } catch (ParserConfigurationException pce) {
117: // Parser with specified options can't be built
118: Log.error(pce.getMessage(), pce);
119:
120: } catch (IOException ioe) {
121: Log.error(ioe.getMessage(), ioe);
122: }
123: return null;
124: }
125:
126: /**
127: * Returned the DOM representing the intro xml content file. May return null
128: * if parsing the file failed.
129: *
130: * @return Returns the document.
131: */
132: public Document getDocument() {
133: return document;
134: }
135:
136: public boolean hasXHTMLContent() {
137: return hasXHTMLContent;
138: }
139:
140: public static String convertToString(Document document) {
141: try {
142: // identity xslt.
143: TransformerFactory tFactory = TransformerFactory
144: .newInstance();
145: Transformer transformer = tFactory.newTransformer();
146:
147: DOMSource source = new DOMSource(document);
148:
149: StringWriter stringBuffer = new StringWriter();
150: StreamResult result = new StreamResult(stringBuffer);
151:
152: // setup properties, for doctype.
153: DocumentType docType = document.getDoctype();
154: if (docType != null) {
155: String value = docType.getSystemId();
156: // transformer.clearParameters();
157: transformer.setOutputProperty(
158: OutputKeys.DOCTYPE_SYSTEM, value);
159: value = document.getDoctype().getPublicId();
160: transformer.setOutputProperty(
161: OutputKeys.DOCTYPE_PUBLIC, value);
162: transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
163: transformer.setOutputProperty(
164: OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$
165: // transformer.setOutputProperty(OutputKeys.MEDIA_TYPE,
166: // "text/html");
167: // transformer
168: // .setOutputProperty(OutputKeys.ENCODING, "iso-8859-1");
169: } else
170: Log
171: .warning("XHTML file used to display this Intro page does not have a Document type defined. " //$NON-NLS-1$
172: + "XHTML requires document types to be defined."); //$NON-NLS-1$
173:
174: transformer.transform(source, result);
175: return stringBuffer.toString();
176:
177: } catch (TransformerConfigurationException tce) {
178: // Error generated by the parser
179: Log
180: .error(
181: "Transformer Config error: " + tce.getMessage(), null); //$NON-NLS-1$
182: // Use the contained exception, if any
183: Throwable x = tce;
184: if (tce.getException() != null)
185: x = tce.getException();
186: Log.error("Transformer Stack trace: ", x); //$NON-NLS-1$
187:
188: } catch (TransformerException te) {
189: // Error generated by the parser
190: Log.error("Transformer error: " + te.getMessage(), te); //$NON-NLS-1$
191: // Use the contained exception, if any
192: Throwable x = te;
193: if (te.getException() != null)
194: x = te.getException();
195: Log.error("Transformer Stack trace: ", x); //$NON-NLS-1$
196:
197: }
198: return null;
199:
200: }
201:
202: }
|