| /******************************************************************************* |
| * Copyright (c) 2004, 2016 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.internal.intro.impl.model.loader; |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.OutputKeys; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| |
| import org.eclipse.ui.internal.intro.impl.util.Log; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DocumentType; |
| import org.w3c.dom.Element; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| |
| |
| /** |
| * |
| */ |
| public class IntroContentParser { |
| |
| private static String TAG_INTRO_CONTENT = "introContent"; //$NON-NLS-1$ |
| private static String TAG_HTML = "html"; //$NON-NLS-1$ |
| |
| private Document document; |
| private boolean hasXHTMLContent; |
| |
| /** |
| * Creates a config parser assuming that the passed content represents a URL |
| * to the content file. |
| */ |
| public IntroContentParser(String content) { |
| try { |
| document = parse(content); |
| if (document != null) { |
| // xml file is loaded. It can be either XHTML or intro XML. |
| Element rootElement = document.getDocumentElement(); |
| // DocumentType docType = document.getDoctype(); |
| if (rootElement.getTagName().equals(TAG_INTRO_CONTENT)) { |
| // intro xml file. |
| hasXHTMLContent = false; |
| } else if (rootElement.getTagName().equals(TAG_HTML)) { |
| // rely on root element to detect if we have an XHTML file |
| // and not on doctype. We need to support xhtml files with |
| // no doctype. |
| hasXHTMLContent = true; |
| } else |
| // not intro XML nor XHTML. |
| document = null; |
| } |
| } catch (Exception e) { |
| Log.error("Could not load Intro content file: " + content, e); //$NON-NLS-1$ |
| } |
| } |
| |
| |
| private Document parse(String fileURI) { |
| Document document = null; |
| try { |
| DocumentBuilderFactory docFactory = DocumentBuilderFactory |
| .newInstance(); |
| docFactory.setValidating(false); |
| // if this is not set, Document.getElementsByTagNameNS() will fail. |
| docFactory.setNamespaceAware(true); |
| docFactory.setExpandEntityReferences(false); |
| DocumentBuilder parser = docFactory.newDocumentBuilder(); |
| parser.setEntityResolver((publicId, systemId) -> new InputSource(new StringReader(""))); //$NON-NLS-1$ |
| document = parser.parse(fileURI); |
| return document; |
| |
| } catch (SAXParseException spe) { |
| StringBuffer buffer = new StringBuffer("IntroParser error in line "); //$NON-NLS-1$ |
| buffer.append(spe.getLineNumber()); |
| buffer.append(", uri "); //$NON-NLS-1$ |
| buffer.append(spe.getSystemId()); |
| buffer.append("\n"); //$NON-NLS-1$ |
| buffer.append(spe.getMessage()); |
| |
| // Use the contained exception. |
| Exception x = spe; |
| if (spe.getException() != null) |
| x = spe.getException(); |
| Log.error(buffer.toString(), x); |
| |
| } catch (SAXException sxe) { |
| Exception x = sxe; |
| if (sxe.getException() != null) |
| x = sxe.getException(); |
| Log.error(x.getMessage(), x); |
| |
| } catch (ParserConfigurationException pce) { |
| // Parser with specified options can't be built |
| Log.error(pce.getMessage(), pce); |
| |
| } catch (IOException ioe) { |
| Log.error(ioe.getMessage(), ioe); |
| } |
| return null; |
| } |
| |
| |
| /** |
| * Returned the DOM representing the intro xml content file. May return null |
| * if parsing the file failed. |
| * |
| * @return Returns the document. |
| */ |
| public Document getDocument() { |
| return document; |
| } |
| |
| public boolean hasXHTMLContent() { |
| return hasXHTMLContent; |
| } |
| |
| |
| public static String convertToString(Document document) { |
| try { |
| // identity xslt. |
| TransformerFactory tFactory = TransformerFactory.newInstance(); |
| Transformer transformer = tFactory.newTransformer(); |
| |
| DOMSource source = new DOMSource(document); |
| |
| StringWriter stringBuffer = new StringWriter(); |
| StreamResult result = new StreamResult(stringBuffer); |
| |
| // setup properties, for doctype. |
| DocumentType docType = document.getDoctype(); |
| if (docType != null) { |
| String value = docType.getSystemId(); |
| // transformer.clearParameters(); |
| transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, value); |
| value = document.getDoctype().getPublicId(); |
| transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, value); |
| transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ |
| transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, |
| "yes"); //$NON-NLS-1$ |
| // transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, |
| // "text/html"); |
| // transformer |
| // .setOutputProperty(OutputKeys.ENCODING, "iso-8859-1"); |
| } else |
| Log |
| .warning("XHTML file used to display this Intro page does not have a Document type defined. " //$NON-NLS-1$ |
| + "XHTML requires document types to be defined."); //$NON-NLS-1$ |
| |
| transformer.transform(source, result); |
| return stringBuffer.toString(); |
| |
| } catch (TransformerConfigurationException tce) { |
| // Error generated by the parser |
| Log.error("Transformer Config error: " + tce.getMessage(), null); //$NON-NLS-1$ |
| // Use the contained exception, if any |
| Throwable x = tce; |
| if (tce.getException() != null) |
| x = tce.getException(); |
| Log.error("Transformer Stack trace: ", x); //$NON-NLS-1$ |
| |
| } catch (TransformerException te) { |
| // Error generated by the parser |
| Log.error("Transformer error: " + te.getMessage(), te); //$NON-NLS-1$ |
| // Use the contained exception, if any |
| Throwable x = te; |
| if (te.getException() != null) |
| x = te.getException(); |
| Log.error("Transformer Stack trace: ", x); //$NON-NLS-1$ |
| |
| } |
| return null; |
| |
| } |
| |
| |
| |
| } |