blob: 04d2e2aaa3359986fc534417e70268bb226ede14 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 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.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.eclipse.help.*;
import org.eclipse.help.internal.*;
import org.eclipse.help.internal.toc.*;
import org.eclipse.help.internal.webapp.data.*;
/**
* URL-like description of help table of contents.
* <ul>
* <li>toc/pluginid/tocfile.xml: the toc defined by the specified toc xml</li>
* <li>toc/: all the toc's</li>
* <li>toc/?topic=/pluginid/topic.html: a list of toc that contain the
* specified topic</li>
* </ul>
*/
public class TocServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private String locale;
/**
* Called by the server (via the <code>service</code> method) to allow a
* servlet to handle a GET request.
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
locale = UrlUtil.getLocale(req, resp);
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
resp.setHeader("Cache-Control", "max-age=10000"); //$NON-NLS-1$ //$NON-NLS-2$
if ("/".equals(req.getPathInfo())) { //$NON-NLS-1$
if (req.getParameter("topic") == null) //$NON-NLS-1$
serializeTocs(resp);
else
serializeTocs(
findTocContainingTopic(req.getParameter("topic")), //$NON-NLS-1$
resp);
} else {
serializeToc(req.getPathInfo(), resp);
}
}
/**
*
* Called by the server (via the <code>service</code> method) to allow a
* servlet to handle a POST request.
*
* Handle the search requests,
*
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
/**
* XML representation of TOC
*/
private void serializeToc(String tocID, HttpServletResponse resp)
throws ServletException, IOException {
IToc toc = HelpPlugin.getTocManager().getToc(tocID, locale);
serializeToc(toc, resp);
}
/**
* XML representation of TOC
*/
private void serializeToc(IToc toc, HttpServletResponse resp)
throws ServletException, IOException {
if (toc == null)
throw new ServletException();
TocWriter tocWriter = new TocWriter(resp.getWriter());
tocWriter.generate(toc, true);
tocWriter.close();
}
/**
* XML representation of TOC list
*/
private void serializeTocs(HttpServletResponse resp)
throws ServletException, IOException {
TocManager tocManager = HelpPlugin.getTocManager();
IToc[] tocs = tocManager.getTocs(locale);
TocWriter gen = new TocWriter(resp.getWriter());
gen.println("<tocs>"); //$NON-NLS-1$
gen.pad++;
for (int i = 0; i < tocs.length; i++) {
gen.printPad();
gen.generate(tocs[i], false);
}
gen.pad--;
gen.println("</tocs>"); //$NON-NLS-1$
gen.close();
}
private void serializeTocs(IToc toc, HttpServletResponse resp)
throws ServletException, IOException {
if (toc == null)
throw new ServletException();
TocWriter gen = new TocWriter(resp.getWriter());
gen.println("<tocs>"); //$NON-NLS-1$
gen.pad++;
gen.printPad();
gen.generate(toc, false);
gen.pad--;
gen.println("</tocs>"); //$NON-NLS-1$
gen.close();
}
/**
* Finds a TOC that contains specified topic
*
* @param topic
* the topic href
*/
private IToc findTocContainingTopic(String topic) {
if (topic == null || topic.equals("")) //$NON-NLS-1$
return null;
int index = topic.indexOf("/topic/"); //$NON-NLS-1$
if (index != -1)
topic = topic.substring(index + 6);
index = topic.indexOf('?');
if (index != -1)
topic = topic.substring(0, index);
if (topic == null || topic.equals("")) //$NON-NLS-1$
return null;
IToc[] tocs = HelpPlugin.getTocManager().getTocs(locale);
for (int i = 0; i < tocs.length; i++)
if (tocs[i].getTopic(topic) != null)
return tocs[i];
// nothing found
return null;
}
/**
* This generates the XML file for the help navigation.
*/
private static class TocWriter extends XMLGenerator {
/**
* @param writer
* java.io.Writer
*/
public TocWriter(Writer writer) {
super(writer);
}
/**
* Writes out xml data for a toc
*/
public void generate(IToc toc, boolean genTopics) {
// get the topic description
String topicDescription = ""; //$NON-NLS-1$
ITopic topic = toc.getTopic(null);
if (topic != null)
topicDescription = topic.getHref();
println("<toc label=\"" //$NON-NLS-1$
+ xmlEscape(toc.getLabel()) + "\" href=\"" //$NON-NLS-1$
+ reduceURL(toc.getHref()) + "\" topic=\"" //$NON-NLS-1$
+ reduceURL(topicDescription) + "\">"); //$NON-NLS-1$
if (genTopics) {
ITopic[] topics = toc.getTopics();
for (int i = 0; i < topics.length; i++) {
generate(topics[i]);
}
}
println("</toc>"); //$NON-NLS-1$
}
/**
* Generates part of navigation for a given Topic and it children Topic
*/
protected void generate(ITopic topic) {
pad++;
printPad();
String href = topic.getHref();
print("<topic label=\"" //$NON-NLS-1$
+ xmlEscape(topic.getLabel()) + "\"" //$NON-NLS-1$
+ (href != null ? " href=\"" + reduceURL(href) + "\"" : "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
ITopic[] subtopics = topic.getSubtopics();
if (subtopics.length > 0) {
println(">"); //$NON-NLS-1$
for (int i = 0; i < subtopics.length; i++) {
generate(subtopics[i]);
}
printPad();
println("</topic>"); //$NON-NLS-1$
} else {
println(" />"); //$NON-NLS-1$
}
pad--;
}
/**
* Simplifies url path by removing "string/.." from the path
*
* @return reduced url String
* @param url
* String
*/
protected static String reduceURL(String url) {
if (url == null)
return url;
while (true) {
int index = url.indexOf("/..", 1); //$NON-NLS-1$
if (index <= 0)
break;
//there is no "/.." or nothing before "/.." to simplify
String part1 = url.substring(0, index);
String part2 = url.substring(index + "/..".length()); //$NON-NLS-1$
index = part1.lastIndexOf("/"); //$NON-NLS-1$
if (index >= 0)
url = part1.substring(0, index) + part2;
else
url = part2;
}
return url;
}
}
}