blob: 97058e2c0b3f8ba9e23f21df2f9df9ca845879e1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 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.webapp.servlet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.help.internal.util.ProductPreferences;
import org.eclipse.help.internal.webapp.WebappResources;
import org.eclipse.help.internal.webapp.data.UrlUtil;
import org.eclipse.help.internal.xhtml.DynamicXHTMLProcessor;
import org.eclipse.help.webapp.IFilter;
/*
* A filter that performs any required XHTML processing, if the content is
* XHTML. Using a servlet path of /rtopic (raw topic) will turn off this
* filter.
*/
public class DynamicXHTMLFilter implements IFilter {
private static final String ERROR_PAGE_PREFIX = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n</head>\n<body>"; //$NON-NLS-1$
private static final String ERROR_PAGE_SUFFIX = "</body>\n</html>"; //$NON-NLS-1$
private static final String CHARSET_UTF8 = "UTF-8"; //$NON-NLS-1$
/* (non-Javadoc)
* @see org.eclipse.help.internal.webapp.servlet.IFilter#filter(javax.servlet.http.HttpServletRequest, java.io.OutputStream)
*/
@Override
public OutputStream filter(final HttpServletRequest req, final OutputStream out) {
final String uri = req.getRequestURI();
if (uri == null || !uri.endsWith("html") && !uri.endsWith("htm")) { //$NON-NLS-1$ //$NON-NLS-2$
return out;
}
/*
* Remote help does all XHTML processing on the client side, so we
* want raw XHTML topics from the remote help server.
*/
if ("/rtopic".equals(req.getServletPath())) { //$NON-NLS-1$
return out;
}
/*
* Buffers the contents of the document until stream is closed, where
* the document is processed then pushed through the filter.
*/
ByteArrayOutputStream out2 = new ByteArrayOutputStream() {
@Override
public void close() throws IOException {
super.close();
byte[] buf = toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(buf);
String locale = UrlUtil.getLocale(req, null);
String contextPath = req.getContextPath();
String servletPath = req.getServletPath();
String href = uri;
if (href.startsWith(contextPath)) {
href = href.substring(contextPath.length());
}
if (href.startsWith(servletPath)) {
href = href.substring(servletPath.length());
}
try {
boolean filter = ProductPreferences.useEnablementFilters();
InputStream in2 = DynamicXHTMLProcessor.process(href, in, locale, filter);
transferContent(in2, out);
}
catch (Throwable t) {
PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, CHARSET_UTF8));
writer.println(ERROR_PAGE_PREFIX);
writer.println("<p>"); //$NON-NLS-1$
writer.println(WebappResources.getString("ProcessingError", req.getLocale())); //$NON-NLS-1$
writer.println("</p>"); //$NON-NLS-1$
writer.println("<pre>"); //$NON-NLS-1$
StringWriter w1 = new StringWriter();
PrintWriter w2 = new PrintWriter(w1);
t.printStackTrace(w2);
writer.println(UrlUtil.htmlEncode(w1.getBuffer().toString()));
writer.println("</pre>"); //$NON-NLS-1$
writer.println(ERROR_PAGE_SUFFIX);
writer.close();
}
}
};
return out2;
}
/*
* Forward the contents of the input stream to the output stream.
*/
private void transferContent(InputStream in, OutputStream out)
throws IOException {
byte[] buffer = new byte[4096];
int len = 0;
while (true) {
len = in.read(buffer);
if (len == -1)
break;
out.write(buffer, 0, len);
}
}
}