| /******************************************************************************* |
| * 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$ |
| } |
| } |
| } |