1 11 package org.eclipse.help.internal.webapp.data; 12 13 import java.io.IOException ; 14 import java.io.Writer ; 15 import java.util.ArrayList ; 16 import java.util.Arrays ; 17 import java.util.Collections ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.StringTokenizer ; 21 22 import javax.servlet.ServletContext ; 23 import javax.servlet.http.HttpServletRequest ; 24 import javax.servlet.http.HttpServletResponse ; 25 26 import org.eclipse.help.IToc; 27 import org.eclipse.help.ITopic; 28 import org.eclipse.help.UAContentFilter; 29 import org.eclipse.help.internal.HelpPlugin; 30 import org.eclipse.help.internal.base.HelpBasePlugin; 31 import org.eclipse.help.internal.base.HelpEvaluationContext; 32 import org.eclipse.help.internal.base.remote.RemoteHelp; 33 34 37 public class TocData extends ActivitiesData { 38 private static int loadBookAtOnceLimit; 40 private static int dynamicLoadDepths; 42 private static int honorLevelsLimit; 46 47 private String tocParameter; 49 private String topicHref; 50 51 private String topicHelpHref; 53 private int selectedToc; 55 private int[] rootPath = null; 57 private ITopic[] topicPath = null; 59 private int topicsGenerated = 0; 61 62 private IToc[] tocs; 64 67 private String imagesDirectory; 69 70 76 public TocData(ServletContext context, HttpServletRequest request, 77 HttpServletResponse response) { 78 super(context, request, response); 79 if (dynamicLoadDepths < 1) { 80 WebappPreferences pref = new WebappPreferences(); 81 loadBookAtOnceLimit = pref.getBookAtOnceLimit(); 82 dynamicLoadDepths = pref.getLoadDepth(); 83 honorLevelsLimit = loadBookAtOnceLimit / 4; 84 } 85 86 this.tocParameter = request.getParameter("toc"); this.topicHref = request.getParameter("topic"); if (tocParameter != null && tocParameter.length() == 0) 89 tocParameter = null; 90 if (topicHref != null && topicHref.length() == 0) 91 topicHref = null; 92 93 String anchor = request.getParameter("anchor"); if (topicHref != null && anchor != null) { 95 topicHref = topicHref + '#' + anchor; 96 } 97 String pathStr = request.getParameter("path"); if (pathStr != null && pathStr.length() > 0) { 100 String [] paths = pathStr.split("_", -1); int[] indexes = new int[paths.length]; 102 boolean indexesOK = true; 103 for (int i = 0; i < paths.length; i++) { 104 try { 105 indexes[i] = Integer.parseInt(paths[i]); 106 } catch (NumberFormatException nfe) { 107 indexesOK = false; 108 break; 109 } 110 if (indexesOK) { 111 rootPath = indexes; 112 } 113 } 114 } 115 116 imagesDirectory = preferences.getImagesDirectory(); 117 118 loadTocs(); 119 } 120 121 125 private static int countTopics(IToc toc) { 126 return countTopics(toc.getTopics()) + 1; 127 } 128 129 133 private static int countTopics(ITopic[] topics) { 134 int count = topics.length; 135 for (int i=0;i<topics.length;++i) { 136 ITopic[] subtopics = topics[i].getSubtopics(); 137 if (subtopics != null && subtopics.length > 0) { 138 count += countTopics(subtopics); 139 } 140 } 141 return count; 142 } 143 144 148 public boolean isRemoteHelpError() { 149 boolean isError = (RemoteHelp.getError() != null); 150 if (isError) { 151 RemoteHelp.clearError(); 152 } 153 return isError; 154 } 155 156 public int getTocCount() { 157 return tocs.length; 158 } 159 160 public String getTocLabel(int i) { 161 return tocs[i].getLabel(); 162 } 163 164 public String getTocHref(int i) { 165 return tocs[i].getHref(); 166 } 167 168 public String getTocDescriptionTopic(int i) { 169 return UrlUtil.getHelpURL(tocs[i].getTopic(null).getHref()); 170 } 171 172 176 private static ITopic[] getTopicPathInToc(ITopic topicToFind, IToc toc) { 177 if (topicToFind.getLabel().equals(toc.getLabel())) { 178 return new ITopic[0]; 179 } 180 ITopic topics[] = toc.getTopics(); 181 if (topics != null) { 182 for (int i=0;i<topics.length;++i) { 183 List reversePath = getTopicPathInToc(topicToFind, topics[i]); 185 if (reversePath != null) { 186 ITopic[] path = new ITopic[reversePath.size()]; 188 for (int j=0;j<path.length;++j) { 189 path[j] = (ITopic)reversePath.get((path.length - 1) - j); 190 } 191 return path; 192 } 193 } 194 } 195 return null; 196 } 197 198 202 private static List getTopicPathInToc(ITopic topicToFind, ITopic topic) { 203 if (topic.getLabel().equals(topicToFind.getLabel())) { 204 List path = new ArrayList (); 206 path.add(topic); 207 return path; 208 } 209 else { 210 ITopic[] subtopics = topic.getSubtopics(); 211 for (int i=0;i<subtopics.length;++i) { 212 List path = getTopicPathInToc(topicToFind, subtopics[i]); 213 if (path != null) { 214 path.add(topic); 216 return path; 217 } 218 } 219 } 220 return null; 221 } 222 223 228 public int getSelectedToc() { 229 return selectedToc; 230 } 231 232 239 public String getSelectedTopic() { 240 if (topicHref != null && topicHref.length() > 0) 241 return UrlUtil.getHelpURL(topicHref); 242 else 243 if (selectedToc == -1) 244 return null; 245 IToc toc = tocs[selectedToc]; 246 ITopic tocDescription = toc.getTopic(null); 247 if (tocDescription != null) 248 return UrlUtil.getHelpURL(tocDescription.getHref()); 249 return UrlUtil.getHelpURL(null); 250 } 251 252 258 public IToc[] getTocs() { 259 return tocs; 260 } 261 262 268 public boolean isEnabled(int toc) { 269 if (!isEnabled(tocs[toc])) { 270 return false; 271 } 272 return (getEnabledSubtopicList(tocs[toc]).size() > 0); 274 } 275 281 private boolean isEnabled(IToc toc) { 282 if(!isAdvancedUI()){ 283 return true; 285 } 286 return HelpBasePlugin.getActivitySupport().isEnabled(toc.getHref()) && 287 !UAContentFilter.isFiltered(toc, HelpEvaluationContext.getContext()); 288 } 289 290 private void loadTocs() { 291 tocs = HelpPlugin.getTocManager().getTocs(getLocale()); 292 selectedToc = -1; 294 if (tocParameter != null && tocParameter.length() > 0) { 295 tocs = getTocs(); 296 for (int i = 0; selectedToc == -1 && i < tocs.length; i++) { 297 if (tocParameter.equals(tocs[i].getHref())) { 298 selectedToc = i; 299 } 300 } 301 } else { 302 304 int index = -1; 305 do { 306 selectedToc = findTocContainingTopic(topicHref); 307 308 ITopic topic = findTopic(); 309 if (topic != null && selectedToc >= 0) { 310 topicPath = getTopicPathInToc(topic, tocs[selectedToc]); 311 } 312 if (topicPath == null && topicHref != null) { 314 index = topicHref.indexOf('#'); 315 if (index != -1) 316 topicHref = topicHref.substring(0, index); 317 } 318 } while (topicPath == null && index != -1); 320 } 321 } 322 323 329 private int findTocContainingTopic(String topic) { 330 if (topic == null || topic.equals("")) return -1; 332 333 int index = topic.indexOf("/topic/"); if (index != -1) { 335 topic = topic.substring(index + 6); 336 } 337 else { 338 index = topic.indexOf("/nav/"); if (index != -1) { 341 String nav = topic.substring(index + 5); 343 String book; 344 index = nav.indexOf('_'); 345 if (index == -1) { 346 book = nav; 347 } else { 348 book = nav.substring(0, index); 349 } 350 351 try { 352 return Integer.parseInt(book); 353 } 354 catch (Exception e) { 355 } 357 } 358 } 359 index = topic.indexOf('?'); 360 if (index != -1) 361 topic = topic.substring(0, index); 362 363 if (topic == null || topic.equals("")) return -1; 365 366 tocs = getTocs(); 367 for (int i = 0; i < tocs.length; i++) 369 if (isEnabled(i)) 370 if (tocs[i].getTopic(topic) != null) 371 return i; 372 for (int i = 0; i < tocs.length; i++) 374 if (!isEnabled(i)) 375 if (tocs[i].getTopic(topic) != null) 376 return i; 377 return -1; 379 } 380 385 private ITopic findTopic() { 386 String topic = getSelectedTopic(); 387 if (topic == null || topic.equals("")) return null; 389 390 int index = topic.indexOf("/topic/"); if (index != -1) { 392 topic = topic.substring(index + 6); 393 } 394 else { 395 index = topic.indexOf("/nav/"); if (index != -1) { 398 String nav = topic.substring(index + 5); 399 StringTokenizer tok = new StringTokenizer (nav, "_"); try { 401 index = Integer.parseInt(tok.nextToken()); 403 ITopic current = getTocs()[index].getTopic(null); 404 while (tok.hasMoreTokens()) { 405 index = Integer.parseInt(tok.nextToken()); 406 current = current.getSubtopics()[index]; 407 } 408 return current; 409 } 410 catch (Exception e) { 411 } 413 } 414 } 415 index = topic.indexOf('?'); 416 if (index != -1) 417 topic = topic.substring(0, index); 418 419 if (topic == null || topic.equals("")) return null; 421 422 if (getSelectedToc() < 0) 423 return null; 424 IToc selectedToc = getTocs()[getSelectedToc()]; 425 if (selectedToc == null) 426 return null; 427 return selectedToc.getTopic(topic); 428 } 429 430 437 public void generateToc(int toc, Writer out) throws IOException { 438 ITopic[] topics = getEnabledSubtopics(tocs[toc]); 439 if (topics.length <= 0) { 440 return; 442 } 443 444 int maxLevels = dynamicLoadDepths; 445 if (countTopics(tocs[toc]) <= loadBookAtOnceLimit) { 446 maxLevels = -1; 447 } 448 StringBuffer id = new StringBuffer (); 450 if (rootPath != null) { 451 for (int p = 0; p < rootPath.length; p++) { 453 if (id.length() > 0) { 454 id.append('_'); 455 } 456 topics = getEnabledSubtopics(topics[rootPath[p]]); 457 id.append(rootPath[p]); 458 } 459 out.write("<ul class='expanded' id=\"" + id.toString() + "\">\n"); } 461 462 for (int i = 0; i < topics.length; i++) { 463 String idPrefix = id.toString(); 464 if (idPrefix.length() > 0) { 465 idPrefix = idPrefix + "_" + Integer.toString(i); } else { 467 idPrefix = Integer.toString(i); 468 } 469 470 generateTopic(topics[i], out, idPrefix, maxLevels, rootPath == null 471 ? 0 472 : rootPath.length); 473 } 474 475 if (rootPath != null) { 476 out.write("</ul>\n"); } 478 479 } 480 481 491 private void generateTopic(ITopic topic, Writer out, String id, 492 int maxLevels, int currentLevel) throws IOException { 493 if (maxLevels == 0) { 494 return; 495 } 496 497 topicsGenerated++; 498 if (maxLevels > 1 && topicsGenerated > honorLevelsLimit) { 499 maxLevels = 1; 500 } 501 502 ITopic[] topics = getEnabledSubtopics(topic); 503 boolean hasNodes = topics.length > 0; 504 505 if (hasNodes) { 506 out.write("<li>"); out.write("<img SRC='"); out.write(imagesDirectory); 509 out 510 .write("/plus.gif' class='collapsed' alt=\"" + ServletResources.getString("topicClosed", request) + "\" title=\"" + ServletResources.getString("topicClosed", request) + "\">"); out.write("<a HREF=" +"\""+ UrlUtil.getHelpURL(topic.getHref()) + "\""+">"); out.write("<img SRC='"); out.write(imagesDirectory); 514 out.write("/container_obj.gif' alt=\"\">"); out.write(UrlUtil.htmlEncode(topic.getLabel())); 516 out.write("</a>"); 518 boolean isAncestor = topicPath != null 520 && topicPath.length > currentLevel + 1 521 && topicPath[currentLevel] == topic; 522 523 if (maxLevels != 1 || isAncestor) { 524 out.write("<ul class='collapsed'>\n"); } else { 526 out.write("<ul class='collapsed' id=\"" + id + "\">\n"); } 529 530 if (1 <= maxLevels && maxLevels <= dynamicLoadDepths && isAncestor) { 531 for (int i = 0; i < topics.length; i++) { 533 generateTopic(topics[i], out, id + "_" + i, dynamicLoadDepths, currentLevel + 1); 535 } 536 } else { 537 for (int i = 0; i < topics.length; i++) { 538 generateTopic(topics[i], out, id + "_" + i, maxLevels - 1, currentLevel + 1); 540 } 541 } 542 543 out.write("</ul>\n"); } else { 545 out.write("<li>"); out.write("<img SRC='"); out.write(imagesDirectory); 548 out.write("/plus.gif' class='h' alt=\"\">"); out.write("<a HREF=" +"\""+ UrlUtil.getHelpURL(topic.getHref()) + "\""+">"); out.write("<img SRC='"); out.write(imagesDirectory); 552 out.write("/topic.gif' alt=\"\">"); out.write(UrlUtil.htmlEncode(topic.getLabel())); 554 out.write("</a>"); } 556 557 out.write("</li>\n"); } 559 560 567 public void generateBasicToc(int toc, Writer out) throws IOException { 568 ITopic[] topics = getEnabledSubtopics(tocs[toc]); 569 for (int i = 0; i < topics.length; i++) { 570 generateBasicTopic(topics[i], out); 571 } 572 573 } 574 575 private void generateBasicTopic(ITopic topic, Writer out) 576 throws IOException { 577 578 out.write("<li>"); ITopic[] topics = getEnabledSubtopics(topic); 580 boolean hasNodes = topics.length > 0; 581 if (hasNodes) { 582 out.write("<nobr>"); out.write("<a "); if (getSelectedTopicHelpHref().equals(topic.getHref())) { 585 out.write("name=\"selectedItem\" "); } 587 out.write("href="+"\"" + UrlUtil.getHelpURL(topic.getHref())+"\"" + ">"); out.write("<img SRC='"); out.write(imagesDirectory); 590 out.write("/container_obj.gif' alt=\"\" border=0> "); out.write(UrlUtil.htmlEncode(topic.getLabel())); 592 out.write("</a>"); out.write("</nobr>"); 595 out.write("<ul>\n"); 597 for (int i = 0; i < topics.length; i++) { 598 generateBasicTopic(topics[i], out); 599 } 600 601 out.write("</ul>\n"); } else { 603 out.write("<nobr>"); out.write("<a "); if (getSelectedTopicHelpHref().equals(topic.getHref())) { 606 out.write("name=\"selectedItem\" "); } 608 out.write("href="+"\"" + UrlUtil.getHelpURL(topic.getHref()) +"\""+ ">"); out.write("<img SRC='"); out.write(imagesDirectory); 611 out.write("/topic.gif' alt=\"\" border=0> "); out.write(UrlUtil.htmlEncode(topic.getLabel())); 613 out.write("</a>"); out.write("</nobr>"); } 616 617 out.write("</li>\n"); } 619 622 private String getSelectedTopicHelpHref() { 623 if (topicHelpHref == null) { 624 String topic = getSelectedTopic(); 625 if (topic == null || topic.length() == 0) { 626 topicHelpHref = ""; return topicHelpHref; 628 } 629 int index = topic.indexOf("/topic/"); if (index != -1) 631 topic = topic.substring(index + 6); 632 index = topic.indexOf('?'); 633 if (index != -1) 634 topic = topic.substring(0, index); 635 topicHelpHref = topic; 636 if (topic == null) { 637 topicHelpHref = ""; } 639 } 640 return topicHelpHref; 641 } 642 649 public ITopic[] getEnabledSubtopics(Object element) { 650 List topics = getEnabledSubtopicList(element); 651 return (ITopic[])topics.toArray(new ITopic[topics.size()]); 652 } 653 660 private List getEnabledSubtopicList(Object element) { 661 if (element instanceof IToc && !isEnabled((IToc) element)) 662 return Collections.EMPTY_LIST; 663 List children; 664 if (element instanceof IToc) { 665 children = Arrays.asList(((IToc)element).getTopics()); 666 } 667 else if (element instanceof ITopic) { 668 children = Arrays.asList(((ITopic)element).getSubtopics()); 669 } 670 else { 671 return Collections.EMPTY_LIST; 673 } 674 List childTopics = new ArrayList (children.size()); 675 for (Iterator childrenIt = children.iterator(); childrenIt.hasNext();) { 676 Object c = childrenIt.next(); 677 if ((c instanceof ITopic)) { 678 if (((((ITopic) c).getHref() != null && ((ITopic) c) 681 .getHref().length() > 0) || getEnabledSubtopicList(c).size() > 0) && 682 !UAContentFilter.isFiltered(c, HelpEvaluationContext.getContext())) { 683 childTopics.add(c); 684 } 685 } else { 686 childTopics.addAll(getEnabledSubtopicList(c)); 689 } 690 } 691 return childTopics; 692 } 693 private void generateTopicLinks(ITopic topic, Writer w, int indent) { 694 String topicHref = topic.getHref(); 695 try { 696 if (indent == 0) 697 w.write("<b>"); for (int tab = 0; tab < indent; tab++) { 699 w.write(" "); } 701 if (topicHref != null && topicHref.length() > 0) { 702 w.write("<a HREF=\""); if ('/' == topicHref.charAt(0)) { 704 w.write("topic"); } 706 w.write(topicHref); 707 w.write("\">"); w.write(UrlUtil.htmlEncode(topic.getLabel())); 709 w.write("</a>"); } else { 711 w.write(UrlUtil.htmlEncode(topic.getLabel())); 712 } 713 w.write("<br>\n"); if (indent == 0) 715 w.write("</b>"); } catch (IOException ioe) { 717 } 718 ITopic[] topics = topic.getSubtopics(); 719 for (int i = 0; i < topics.length; i++) { 720 generateTopicLinks(topics[i], w, indent + 1); 721 } 722 } 723 724 public void generateLinks(Writer out) { 725 for (int i = 0; i < tocs.length; i++) { 726 IToc toc = tocs[i]; 727 ITopic tocTopic = toc.getTopic(null); 728 generateTopicLinks(tocTopic, out, 0); 729 ITopic[] topics = toc.getTopics(); 730 for (int t = 0; t < topics.length; t++) { 731 generateTopicLinks(topics[t], out, 1); 732 } 733 } 734 735 } 736 737 public ITopic[] getTopicPath() { 738 return topicPath; 739 } 740 741 public int[] getRootPath() { 742 return rootPath; 743 } 744 745 public String getTopicHref() { 746 return topicHref; 747 } 748 } 749 | Popular Tags |