blob: 9f5b1831f12b6d6bce669bd427b029ff4f30370d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2015 Intel Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Intel Corporation - initial API and implementation
* IBM Corporation - 122967 [Help] Remote help system
* 163558 Dynamic content support for all UA
*******************************************************************************/
package org.eclipse.help.internal.webapp.data;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.help.IIndex;
import org.eclipse.help.IIndexEntry;
import org.eclipse.help.ITopic;
import org.eclipse.help.internal.HelpPlugin;
/**
* Helper class for Index view initialization
*/
public class IndexData extends ActivitiesData {
private IIndex index;
// images directory
private String imagesDirectory;
// plus/minus image file name
private String plusMinusImage;
// name of expand/collapse class for IMG, UL tags
private String expandedCollapsed;
// use or not expand/collapse feature
private boolean usePlusMinus;
// expand all by default flag
private boolean expandAll;
// flag right-to-left direction of text
private boolean isRTL;
// global writer for private generate...() methods
private Writer out;
/**
* Constructs the data for the index page.
* @param context
* @param request
*/
public IndexData(ServletContext context, HttpServletRequest request,
HttpServletResponse response) {
super(context, request, response);
imagesDirectory = preferences.getImagesDirectory();
usePlusMinus = preferences.isIndexPlusMinus();
expandAll = preferences.isIndexExpandAll();
plusMinusImage = expandAll ? "/minus.gif" : "/plus.gif"; //$NON-NLS-1$ //$NON-NLS-2$
expandedCollapsed = expandAll ? "expanded" : "collapsed"; //$NON-NLS-1$ //$NON-NLS-2$
isRTL = UrlUtil.isRTL(request, response);
index = HelpPlugin.getIndexManager().getIndex(getLocale());
}
/**
* Generates values for array of ids of list items
* avaliable to be navigated through typein feature.
*
* Currently only first level items can be navigated.
*
* @param out
* @throws IOException
*/
public void generateIds(Writer out) throws IOException {
boolean first = true;
IIndexEntry[] entries = index.getEntries();
for (IIndexEntry entry : entries) {
if (entry != null && entry.getKeyword() != null && entry.getKeyword().length() > 0) {
if (first) {
first = false;
} else {
out.write(",\n"); //$NON-NLS-1$
}
out.write("\""); //$NON-NLS-1$
out.write(UrlUtil.JavaScriptEncode(entry.getKeyword()));
out.write("\""); //$NON-NLS-1$
}
}
}
/**
* Generates the HTML code (a list) for the index.
*
* @param out
* @throws IOException
*/
public void generateIndex(Writer out) throws IOException {
this.out = out;
IIndexEntry[] entries = index.getEntries();
for (IIndexEntry entrie : entries) {
if (EnabledTopicUtils.isEnabled(entrie)) {
generateEntry(entrie, 0);
}
}
}
/**
* Generates the HTML code for an index entry.
*
* @param entry
* @param level
* @throws IOException
*/
/*
* For advanced UI:
* <li>[ plus_image ]<a ...>...</a>
* [<ul>list of topics</ul>]
* [<ul>nested entries</ul>]
* </li>
*
* For basic UI:
* <li><a ...>...</a>
* [<ul>
* list of topics
* nested entries
* </ul>]
* </li>
*/
private void generateEntry(IIndexEntry entry, int level) throws IOException {
if (entry.getKeyword() != null && entry.getKeyword().length() > 0) {
ITopic[] topics = EnabledTopicUtils.getEnabled(entry.getTopics());
IIndexEntry[] subentries = EnabledTopicUtils.getEnabled(entry.getSubentries());
boolean multipleTopics = topics.length > 1;
boolean singleTopic = topics.length == 1;
out.write("<li>"); //$NON-NLS-1$
if (usePlusMinus && advancedUI) generatePlusImage(multipleTopics);
generateAnchor(singleTopic, entry, level);
if (multipleTopics || subentries.length > 0) {
if (!advancedUI) {
out.write("<ul>\n"); //$NON-NLS-1$
}
if (multipleTopics) generateTopicList(entry);
generateSubentries(entry, level + 1);
if (!advancedUI) {
out.write("</ul>\n"); //$NON-NLS-1$
}
}
out.write("</li>\n"); //$NON-NLS-1$
}
}
/**
* Generates the HTML code (a list) for the index.
* Basic UI version.
*
* @param out
* @throws IOException
*/
public void generateBasicIndex(Writer out) throws IOException {
this.out = out;
IIndexEntry[] entries = index.getEntries();
for (IIndexEntry entrie : entries) {
generateBasicEntry(entrie, 0);
}
}
/**
* Generates the HTML code for an index entry.
* Basic UI version.
*
* @param entry
* @param level
* @throws IOException
*/
/*
* <tr><td align={ "left" | "right" } nowrap>
* <a ...>...</a>
* </td></tr>
* [<tr><td align={ "left" | "right" } nowrap><ul>
* list of topics
* nested entries
* </ul></td></tr>]
*/
private void generateBasicEntry(IIndexEntry entry, int level) throws IOException {
ITopic[] topics = entry.getTopics();
IIndexEntry[] subentries = entry.getSubentries();
boolean multipleTopics = topics.length > 1;
boolean singleTopic = topics.length == 1;
out.write("<tr><td align=\""); //$NON-NLS-1$
out.write(isRTL ? "right" : "left"); //$NON-NLS-1$ //$NON-NLS-2$
out.write("\" nowrap>\n"); //$NON-NLS-1$
generateAnchor(singleTopic, entry, level);
out.write("</td></tr>\n"); //$NON-NLS-1$
if (multipleTopics || subentries.length > 0) {
out.write("<tr><td align=\""); //$NON-NLS-1$
out.write(isRTL ? "right" : "left"); //$NON-NLS-1$ //$NON-NLS-2$
out.write("\" nowrap><ul>\n"); //$NON-NLS-1$
if (multipleTopics) generateTopicList(entry);
generateSubentries(entry, level + 1);
out.write("</ul></td></tr>\n"); //$NON-NLS-1$
}
}
/**
* Generates the HTML code for the plus/minus image.
*
* @param multipleTopics
* @throws IOException
*/
/*
* <img scr="images/plus.gif" class={ "collapsed" | "expanded" | "h" } alt="...">
*/
private void generatePlusImage(boolean multipleTopics) throws IOException {
out.write("<img src=\""); //$NON-NLS-1$
out.write(imagesDirectory);
out.write(plusMinusImage);
out.write("\" class=\""); //$NON-NLS-1$
if (multipleTopics) {
out.write(expandedCollapsed);
} else {
out.write("h"); //$NON-NLS-1$
}
out.write("\" alt=\""); //$NON-NLS-1$
if (multipleTopics) {
if (expandAll) {
out.write(ServletResources.getString("collapseTopicTitles", request)); //$NON-NLS-1$
} else {
out.write(ServletResources.getString("expandTopicTitles", request)); //$NON-NLS-1$
}
}
out.write("\">"); //$NON-NLS-1$
}
/**
* Generates the HTML code for an index entry anchor tag.
*
* @param singleTopic
* @param entry
* @param level
* @throws IOException
*/
/*
* For advanced UI:
* <a [ id="..." ] [ class="nolink" ] href="...">...</a>
*
* For basic UI:
* <a href="...">...</a>
*/
private void generateAnchor(boolean singleTopic, IIndexEntry entry, int level) throws IOException {
out.write("<a "); //$NON-NLS-1$
if (level == 0 && advancedUI) {
out.write("id=\""); //$NON-NLS-1$
out.write(entry.getKeyword());
out.write("\" "); //$NON-NLS-1$
}
if (singleTopic) {
out.write("href=\""); //$NON-NLS-1$
out.write(UrlUtil.getHelpURL((entry.getTopics()[0]).getHref()));
out.write("\">"); //$NON-NLS-1$
} else {
if (advancedUI) {
out.write("class=\"nolink\" "); //$NON-NLS-1$
}
out.write("href=\"about:blank\">"); //$NON-NLS-1$
}
out.write(UrlUtil.htmlEncode(entry.getKeyword()));
out.write("</a>\n"); //$NON-NLS-1$
}
/**
* Generates the HTML code for a list of topics.
*
* @param entry
* @throws IOException
*/
/*
* For advanced UI:
* <ul class={"collapsed" | "expanded"}>
* <li><img class="h" src="images/plus.gif" alt=""><a href="..."><img src="images/topic.gif" alt="">...</a></li>
* <li>...
* </ul>
*
* For basic UI:
* <li><a href="..."><img src="images/topic.gif" border=0 alt="">...</a></li>
* <li>...
*/
private void generateTopicList(IIndexEntry entry) throws IOException {
ITopic[] topics = entry.getTopics();
if (advancedUI) {
out.write("\n<ul class=\""); //$NON-NLS-1$
out.write(expandedCollapsed);
out.write("\">\n"); //$NON-NLS-1$
}
for (ITopic topic : topics) {
out.write("<li>"); //$NON-NLS-1$
if (usePlusMinus && advancedUI) {
out.write("<img class=\"h\" src=\""); //$NON-NLS-1$
out.write(imagesDirectory);
out.write(plusMinusImage);
out.write("\" alt=\"\">"); //$NON-NLS-1$
}
out.write("<a href=\""); //$NON-NLS-1$
out.write(UrlUtil.getHelpURL(topic.getHref()));
out.write("\"><img src=\""); //$NON-NLS-1$
out.write(imagesDirectory);
out.write("/topic.gif\" "); //$NON-NLS-1$
if (!advancedUI) {
out.write("border=0 "); //$NON-NLS-1$
}
out.write("alt=\"\">"); //$NON-NLS-1$
out.write(UrlUtil.htmlEncode(topic.getLabel()));
out.write("</a></li>\n"); //$NON-NLS-1$
}
if (advancedUI) {
out.write("</ul>\n"); //$NON-NLS-1$
}
}
/**
* Generates the HTML for nested index entries.
*
* @param entry
* @param level
* @throws IOException
*/
/*
* For advanced UI:
* <ul class="expanded">
* entries...
* </ul>
*
* For basic UI:
* entries...
*/
private void generateSubentries(IIndexEntry entry, int level) throws IOException {
if (advancedUI) {
out.write("<ul class=\"expanded\">\n"); //$NON-NLS-1$
}
IIndexEntry[] subentries = entry.getSubentries();
for (IIndexEntry subentrie : subentries) {
generateEntry(subentrie, level);
}
if (advancedUI) {
out.write("</ul>\n"); //$NON-NLS-1$
}
}
}