1 11 package org.eclipse.help.internal.webapp.servlet; 12 13 import java.io.IOException ; 14 import java.util.ArrayList ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Map ; 18 import java.util.WeakHashMap ; 19 20 import javax.servlet.ServletException ; 21 import javax.servlet.http.HttpServlet ; 22 import javax.servlet.http.HttpServletRequest ; 23 import javax.servlet.http.HttpServletResponse ; 24 25 import org.eclipse.help.IIndex; 26 import org.eclipse.help.IIndexEntry; 27 import org.eclipse.help.ITopic; 28 import org.eclipse.help.internal.HelpPlugin; 29 import org.eclipse.help.internal.base.BaseHelpSystem; 30 import org.eclipse.help.internal.webapp.WebappResources; 31 import org.eclipse.help.internal.webapp.data.ActivitiesData; 32 import org.eclipse.help.internal.webapp.data.EnabledTopicUtils; 33 import org.eclipse.help.internal.webapp.data.UrlUtil; 34 35 43 public class IndexFragmentServlet extends HttpServlet { 44 45 private static final long serialVersionUID = 1L; 46 private static Map locale2Response = new WeakHashMap (); 47 private String startParameter; 48 private String sizeParameter; 49 private String entryParameter; 50 private String modeParameter; 51 private String showAllParameter; 52 private int size; 53 private int entry; 54 private static final String NEXT = "next"; private static final String PREVIOUS = "previous"; private static final String SIZE = "size"; private static final String MODE = "mode"; private static final String ENTRY = "entry"; private static final String SHOW_ALL = "showAll"; 61 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 62 throws ServletException , IOException { 63 String locale = UrlUtil.getLocale(req, resp); 64 startParameter = req.getParameter("start"); if (startParameter != null) { 66 startParameter = startParameter.toLowerCase(); 67 } 68 69 size = 30; 70 sizeParameter = req.getParameter(SIZE); 71 if (sizeParameter != null) { 72 try { 73 size = Integer.parseInt(sizeParameter); 74 } catch (NumberFormatException n) { 75 } 76 } 77 78 entry = -1; 79 entryParameter = req.getParameter(ENTRY); 80 if (entryParameter != null) { 81 try { 82 entry = Integer.parseInt(entryParameter); 83 } catch (NumberFormatException n) { 84 } 85 } 86 87 modeParameter = req.getParameter(MODE); 88 showAllParameter = req.getParameter(SHOW_ALL); 89 if (showAllParameter != null) { 90 new ActivitiesData(this.getServletContext(), req, resp); 92 } 93 94 req.setCharacterEncoding("UTF-8"); resp.setContentType("application/xml; charset=UTF-8"); if (BaseHelpSystem.getMode() != BaseHelpSystem.MODE_INFOCENTER) { 99 resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); resp.setDateHeader ("Expires", 0); } 103 Serializer serializer = new Serializer(locale); 104 String response = serializer.generateIndexXml(); 105 locale2Response.put(locale, response); 106 resp.getWriter().write(response); 107 } 108 109 112 private class Serializer { 113 114 private IIndex index; 115 private StringBuffer buf; 116 private int count = 0; 117 private String locale; 118 private List entryList; 119 private IIndexEntry[] entries; 120 private boolean enablePrevious = true; 121 private boolean enableNext = true; 122 123 public Serializer(String locale) { 124 this.locale = locale; 125 index = HelpPlugin.getIndexManager().getIndex(locale); 126 buf = new StringBuffer (); 127 } 128 129 135 private String generateIndexXml() { 136 137 entries = index.getEntries(); 138 if (entries.length == 0) { 139 generateEmptyIndexMessage(); 140 } else { 141 entryList = new ArrayList (); 142 int nextEntry = findFirstEntry(entries); 143 if (PREVIOUS.equals(modeParameter)) { 144 int remaining = getPreviousEntries(nextEntry, size); 145 getNextEntries(nextEntry, remaining); 146 } else { 147 int remaining = getNextEntries(nextEntry, size); 148 if (remaining == size) { 149 size = 1; 151 getPreviousEntries(nextEntry, 1); 152 } 153 } 154 for (Iterator iter = entryList.iterator(); iter.hasNext();) { 155 Integer entryId = (Integer )iter.next(); 156 generateEntry(entries[entryId.intValue()], 0, "e" + entryId.intValue()); } 158 } 159 String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tree_data enableNext = \"" + Boolean.toString(enableNext) + "\" enablePrevious = \"" + Boolean.toString(enablePrevious) + "\">\n"; buf.append("</tree_data>\n"); return header + buf.toString(); 163 } 164 165 private int getCategory(String keyword) { 166 if (keyword != null && keyword.length() > 0) { 167 char c = keyword.charAt(0); 168 if (Character.isDigit(c)) { 169 return 2; 170 } else if (Character.isLetter(c)) { 171 return 3; 172 } 173 return 1; 174 } 175 return 4; 176 } 177 178 private int compare (String left, String right) { 179 int catLeft = getCategory(left); 180 int catRight = getCategory(right); 181 if (catLeft != catRight) { 182 return catLeft - catRight; 183 } else { 184 return left.compareTo(right); 185 } 186 } 187 188 private int findFirstEntry(IIndexEntry[] entries) { 189 if (NEXT.equals(modeParameter)) { 190 if (entry >= entries.length - 1) { 191 return entries.length - 1; 192 } else { 193 return entry + 1; 194 } 195 } 196 if (PREVIOUS.equals(modeParameter)) { 197 if (entry <= 0) { 198 return 0; 199 } else { 200 return entry - 1; 201 } 202 } 203 if (startParameter == null) { 204 return 0; 205 } 206 int nextEntry = 0; 207 while (nextEntry < entries.length) { 208 String keyword = entries[nextEntry].getKeyword().toLowerCase(); 209 if (keyword != null) { 210 if (compare(startParameter, keyword) <= 0) { 211 break; 212 } 213 } 214 nextEntry++; 215 } 216 return nextEntry; 217 } 218 219 private int getNextEntries(int nextEntry, int remaining) { 220 while (nextEntry < entries.length) { 221 int entrySize = enabledEntryCount(entries[nextEntry]); 222 if (remaining == size || remaining > entrySize) { 223 entryList.add(new Integer (nextEntry)); 224 setFlags(nextEntry); 225 remaining -= entrySize; 226 } else { 227 break; 228 } 229 nextEntry++; 230 } 231 return remaining; 232 } 233 234 private int getPreviousEntries(int nextEntry, int remaining) { 235 nextEntry--; 236 while (nextEntry >= 0) { 237 int entrySize = enabledEntryCount(entries[nextEntry]); 238 if (remaining == size || remaining > entrySize) { 239 entryList.add(0, new Integer (nextEntry)); 240 241 setFlags(nextEntry); 242 remaining -= entrySize; 243 } else { 244 break; 245 } 246 nextEntry--; 247 } 248 return remaining; 249 } 250 251 private void setFlags(int nextEntry) { 252 if (nextEntry == 0) { 253 enablePrevious = false; 254 } 255 if (nextEntry == entries.length - 1) { 256 enableNext = false; 257 } 258 } 259 260 private int enabledEntryCount(IIndexEntry entry) { 261 if (!EnabledTopicUtils.isEnabled(entry)) return 0; 262 if (entry.getKeyword() == null || entry.getKeyword().length() == 0) { 263 return 0; 264 } 265 int count = 1; 266 ITopic[] topics = EnabledTopicUtils.getEnabled(entry.getTopics()); 267 IIndexEntry[] subentries = EnabledTopicUtils.getEnabled(entry.getSubentries()); 268 if (topics.length > 1) { 269 count += topics.length; 270 } 271 for (int i=0;i<subentries.length;++i) { 272 count += enabledEntryCount(subentries[i]); 273 } 274 return count; 275 } 276 277 private void generateEmptyIndexMessage() { 278 buf.append("<node"); buf.append('\n' + " title=\"" + XMLGenerator.xmlEscape(WebappResources.getString("IndexEmpty", UrlUtil.getLocale(locale))) + '"'); buf.append('\n' + " id=\"no_index\""); buf.append(">\n"); buf.append("</node>\n"); enableNext = false; 284 enablePrevious = false; 285 } 286 287 private void generateEntry(IIndexEntry entry, int level, String id) { 288 if (!EnabledTopicUtils.isEnabled(entry)) return; 289 if (entry.getKeyword() != null && entry.getKeyword().length() > 0) { 290 ITopic[] topics = EnabledTopicUtils.getEnabled(entry.getTopics()); 291 IIndexEntry[] subentries = EnabledTopicUtils.getEnabled(entry.getSubentries()); 292 boolean multipleTopics = topics.length > 1; 293 boolean singleTopic = topics.length == 1; 294 295 buf.append("<node"); if (entry.getKeyword() != null) { 297 buf.append('\n' + " title=\"" + XMLGenerator.xmlEscape(entry.getKeyword()) + '"'); } 299 300 buf.append('\n' + " id=\"" + id + '"'); 302 String href; 303 if (singleTopic) { 304 href = UrlUtil.getHelpURL((entry.getTopics()[0]).getHref()); 305 buf.append('\n' + " HREF=\"" + XMLGenerator.xmlEscape(href) + "\""); } 308 buf.append(">\n"); 310 if (multipleTopics || subentries.length > 0) { 311 if (multipleTopics) generateTopicList(entry); 312 generateSubentries(entry, level + 1); 313 } 314 315 buf.append("</node>\n"); } 317 } 318 319 private void generateSubentries(IIndexEntry entry, int level) { 320 IIndexEntry[] subentries = entry.getSubentries(); 321 for (int i=0;i<subentries.length;++i) { 322 generateEntry(subentries[i], level, "s" + count++); } 324 } 325 326 private void generateTopicList(IIndexEntry entry) { 327 ITopic[] topics = entry.getTopics(); 328 329 for (int i = 0; i < topics.length; ++i) { 330 ITopic topic = (ITopic)topics[i]; 331 332 String label = UrlUtil.htmlEncode(topic.getLabel()); 334 if (label == null) { 335 label = UrlUtil.htmlEncode(topic.getLabel()); 336 } 337 338 339 buf.append("<node"); if (entry.getKeyword() != null) { 341 buf.append('\n' + " title=\"" + label + '"'); } 343 344 count++; 345 buf.append('\n' + " id=\"i" + count + '"'); String href = UrlUtil.getHelpURL(topic.getHref()); 347 buf.append('\n' + " HREF=\"" + XMLGenerator.xmlEscape(href) + "\""); buf.append(">\n"); buf.append("</node>\n"); 352 } 353 } 354 } 355 356 } 357 | Popular Tags |