| /******************************************************************************* |
| * Copyright (c) 2006, 2015 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.help.internal.xhtml; |
| |
| import java.io.BufferedInputStream; |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerException; |
| |
| import org.eclipse.core.runtime.content.IContentDescriber; |
| import org.eclipse.help.internal.base.HelpEvaluationContext; |
| import org.eclipse.help.internal.dynamic.DocumentReader; |
| import org.eclipse.help.internal.dynamic.ExtensionHandler; |
| import org.eclipse.help.internal.dynamic.FilterHandler; |
| import org.eclipse.help.internal.dynamic.IncludeHandler; |
| import org.eclipse.help.internal.dynamic.ProcessorHandler; |
| import org.eclipse.help.internal.dynamic.XMLProcessor; |
| import org.eclipse.help.internal.search.HTMLDocParser; |
| import org.xml.sax.SAXException; |
| |
| /* |
| * Performs any needed XHTML processing on the given input stream. If the input |
| * is not XHTML, simply forwards the stream. |
| */ |
| public class DynamicXHTMLProcessor { |
| |
| private static IContentDescriber xhtmlDescriber; |
| private static XMLProcessor xmlProcessor; |
| private static XMLProcessor xmlProcessorNoFilter; |
| |
| /* |
| * Performs any needed processing. Does nothing if not XHTML. |
| */ |
| public static InputStream process(String href, InputStream in, String locale, boolean filter) throws IOException, SAXException, ParserConfigurationException, TransformerConfigurationException, TransformerException { |
| BufferedInputStream buf = new BufferedInputStream(in, XHTMLContentDescriber.BUFFER_SIZE); |
| int bufferSize = Math.max(XHTMLContentDescriber.BUFFER_SIZE, HTMLDocParser.MAX_OFFSET); |
| byte[] buffer = new byte[bufferSize]; |
| buf.mark(Math.max(XHTMLContentDescriber.BUFFER_SIZE, HTMLDocParser.MAX_OFFSET)); |
| buf.read(buffer); |
| buf.reset(); |
| boolean isXHTML = isXHTML(new ByteArrayInputStream(buffer)); |
| if (isXHTML) { |
| String charset = HTMLDocParser.getCharsetFromHTML(new ByteArrayInputStream(buffer)); |
| if (filter) { |
| if (xmlProcessor == null) { |
| DocumentReader reader = new DocumentReader(); |
| xmlProcessor = new XMLProcessor(new ProcessorHandler[] { |
| new IncludeHandler(reader, locale), |
| new ExtensionHandler(reader, locale), |
| new XHTMLCharsetHandler(), |
| new FilterHandler(HelpEvaluationContext.getContext()) |
| }); |
| } |
| return xmlProcessor.process(buf, href, charset); |
| } |
| if (xmlProcessorNoFilter == null) { |
| DocumentReader reader = new DocumentReader(); |
| xmlProcessorNoFilter = new XMLProcessor(new ProcessorHandler[] { |
| new IncludeHandler(reader, locale), |
| new ExtensionHandler(reader, locale), |
| new XHTMLCharsetHandler() |
| }); |
| } |
| return xmlProcessorNoFilter.process(buf, href, charset); |
| } |
| return buf; |
| } |
| |
| /* |
| * Returns whether or not the given input stream is XHTML content. |
| */ |
| private static synchronized boolean isXHTML(InputStream in) { |
| if (xhtmlDescriber == null) { |
| xhtmlDescriber = new XHTMLContentDescriber(); |
| } |
| if (in != null) { |
| try { |
| return (xhtmlDescriber.describe(in, null) == IContentDescriber.VALID); |
| } |
| catch (IOException e) { |
| } |
| } |
| return false; |
| } |
| } |