blob: d55b3b0391b02b60c11e55c53f5485eb6bb6e2fb [file] [log] [blame]
/*******************************************************************************
* 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;
}
}