1 11 package org.eclipse.ui.internal.intro.impl.model; 12 13 import java.util.Hashtable ; 14 import java.util.Vector ; 15 16 import org.eclipse.core.runtime.IPath; 17 import org.eclipse.core.runtime.Path; 18 import org.eclipse.core.runtime.Platform; 19 import org.eclipse.help.internal.UAElement; 20 import org.eclipse.help.internal.UAElementFactory; 21 import org.eclipse.help.internal.dynamic.DocumentProcessor; 22 import org.eclipse.help.internal.dynamic.FilterHandler; 23 import org.eclipse.help.internal.dynamic.ProcessorHandler; 24 import org.eclipse.ui.internal.intro.impl.IIntroConstants; 25 import org.eclipse.ui.internal.intro.impl.model.loader.ExtensionPointManager; 26 import org.eclipse.ui.internal.intro.impl.model.loader.IntroContentParser; 27 import org.eclipse.ui.internal.intro.impl.model.loader.ModelLoaderUtil; 28 import org.eclipse.ui.internal.intro.impl.model.util.BundleUtil; 29 import org.eclipse.ui.internal.intro.impl.model.util.ModelUtil; 30 import org.eclipse.ui.internal.intro.impl.util.IntroEvaluationContext; 31 import org.eclipse.ui.internal.intro.impl.util.Log; 32 import org.eclipse.ui.internal.intro.impl.util.StringUtil; 33 import org.osgi.framework.Bundle; 34 import org.w3c.dom.Document ; 35 import org.w3c.dom.Element ; 36 import org.w3c.dom.Node ; 37 import org.w3c.dom.NodeList ; 38 39 54 public abstract class AbstractIntroPage extends AbstractIntroContainer { 55 56 protected static final String TAG_PAGE = "page"; private static final String ATT_STYLE = "style"; private static final String ATT_ALT_STYLE = "alt-style"; private static final String ATT_CONTENT = "content"; private static final String ATT_SHARED_STYLE = "shared-style"; private static final String INVALID_CONTENT = "invalidPage/invalidPage.xhtml"; private static final String INVALID_CONTENT_BASE = "invalidPage"; 64 private String style; 65 private String altStyle; 66 private String sharedStyle; 67 private IntroPageTitle title; 68 private String content; 69 70 private IntroInjectedIFrame iframe; 73 74 private String originalId; 76 77 private Document dom; 80 81 private DocumentProcessor domProcessor; 82 83 private boolean isXHTMLPage; 85 86 private String initialBase; 92 93 114 private Vector styles; 115 private Hashtable altStyles; 116 117 126 AbstractIntroPage(Element element, Bundle bundle, String base) { 127 super(element, bundle, base); 128 this.initialBase = base; 129 content = getAttribute(element, ATT_CONTENT); 130 if (content == null) { 131 } 135 else { 136 IPath subBase = ModelUtil.getParentFolderPath(content); 147 this.base = new Path(base).append(subBase).toString(); 148 content = BundleUtil.getResolvedResourceLocation(base, content, 149 bundle); 150 } 151 this.sharedStyle = getAttribute(element, ATT_SHARED_STYLE); 154 if (sharedStyle == null) 155 sharedStyle = "true"; 157 } 158 159 public void setParent(AbstractIntroElement parent) { 160 super.setParent(parent); 161 if (content == null) 162 init(element, getBundle(), initialBase); 163 } 164 165 170 171 public String getRawContent() { 172 return getAttribute(element, ATT_CONTENT); 173 } 174 175 183 private void init(Element element, Bundle bundle, String base) { 184 String [] styleValues = getAttributeList(element, ATT_STYLE); 185 if (styleValues != null && styleValues.length > 0) { 186 style = styleValues[0]; 187 style = BundleUtil.getResolvedResourceLocation(base, style, bundle); 188 for (int i = 1; i < styleValues.length; i++) { 189 String style = styleValues[i]; 190 style = BundleUtil.getResolvedResourceLocation(base, style, 191 bundle); 192 addStyle(style); 193 } 194 } 195 196 String [] altStyleValues = getAttributeList(element, ATT_ALT_STYLE); 197 if (altStyleValues != null && altStyleValues.length > 0) { 198 altStyle = altStyleValues[0]; 199 altStyle = BundleUtil.getResolvedResourceLocation(base, altStyle, 200 bundle); 201 for (int i = 1; i < altStyleValues.length; i++) { 202 String style = altStyleValues[i]; 203 style = BundleUtil.getResolvedResourceLocation(base, style, 204 bundle); 205 addAltStyle(style, bundle); 206 } 207 } 208 } 209 210 211 212 213 218 public String getTitle() { 219 getChildren(); 224 if (title == null) { 225 IntroPageTitle[] titles = (IntroPageTitle[]) getChildrenOfType(AbstractIntroElement.PAGE_TITLE); 227 if (titles.length > 0) 228 title = titles[0]; 229 } 230 231 if (title == null) 232 return null; 234 return title.getTitle(); 235 } 236 237 240 public String getStyle() { 241 return style; 242 } 243 244 247 public String getAltStyle() { 248 return altStyle; 249 } 250 251 262 public String [] getStyles() { 263 getChildren(); 266 if (styles == null) 267 return new String [0]; 269 String [] stylesArray = new String [styles.size()]; 270 styles.copyInto(stylesArray); 271 return stylesArray; 272 } 273 274 286 public Hashtable getAltStyles() { 287 getChildren(); 290 return altStyles; 291 } 292 293 299 protected void addStyle(String style) { 300 if (!initStyles(style)) 301 return; 302 if (styles.contains(style)) 303 return; 304 styles.add(style); 305 } 306 307 public void insertStyle(String style, int location) { 308 if (!initStyles(style)) 309 return; 310 if (styles.contains(style)) 311 return; 312 styles.add(location, style); 313 } 314 315 316 317 323 protected void addAltStyle(String altStyle, Bundle bundle) { 324 if (!initAltStyles(altStyle)) 325 return; 326 if (altStyles.containsKey(altStyle)) 327 return; 328 altStyles.put(altStyle, bundle); 329 } 330 331 332 336 protected void addStyles(String [] styles) { 337 if (styles == null) 338 return; 339 for (int i = 0; i < styles.length; i++) 340 addStyle(styles[i]); 341 } 342 343 346 protected void addAltStyles(Hashtable altStyles) { 347 if (altStyles == null) 348 return; 349 if (this.altStyles == null) 350 this.altStyles = new Hashtable (); 352 this.altStyles.putAll(altStyles); 353 } 354 355 356 private boolean initStyles(String style) { 357 if (style == null) 358 return false; 359 if (this.styles == null) 360 this.styles = new Vector (); 362 return true; 363 } 364 365 private boolean initAltStyles(String style) { 366 if (style == null) 367 return false; 368 if (this.altStyles == null) 369 this.altStyles = new Hashtable (); 371 return true; 372 } 373 374 375 380 public int getType() { 381 return AbstractIntroElement.ABSTRACT_PAGE; 382 } 383 384 391 protected void resolveChildren() { 392 if (isXHTMLPage) 394 resolvePage(); 395 else 396 super.resolveChildren(); 397 } 398 399 400 401 407 protected AbstractIntroElement getModelChild(Element childElement, 408 Bundle bundle, String base) { 409 AbstractIntroElement child = null; 410 if (childElement.getNodeName().equalsIgnoreCase(IntroHead.TAG_HEAD)) { 411 child = new IntroHead(childElement, bundle, base); 412 } else if (childElement.getNodeName().equalsIgnoreCase( 413 IntroPageTitle.TAG_TITLE)) { 414 if (title == null) { 417 child = new IntroPageTitle(childElement, bundle); 418 } 419 } 420 if (child != null) 421 return child; 422 return super.getModelChild(childElement, bundle, base); 423 } 424 425 431 public IntroHead[] getHTMLHeads() { 432 return (IntroHead[]) getChildrenOfType(AbstractIntroElement.HEAD); 433 } 434 435 436 444 protected void loadChildren() { 445 if (content == null) { 446 super.loadChildren(); 448 return; 449 } 450 451 IntroContentParser parser = new IntroContentParser(content); 457 Document dom = parser.getDocument(); 458 if (dom == null) { 459 Bundle introBundle = Platform.getBundle(IIntroConstants.PLUGIN_ID); 463 ModelUtil.ensureFileURLsExist(introBundle, INVALID_CONTENT); 464 465 String invalidContentFilePath = BundleUtil 466 .getResolvedResourceLocation(INVALID_CONTENT, introBundle); 467 parser = new IntroContentParser(invalidContentFilePath); 468 dom = parser.getDocument(); 469 content = invalidContentFilePath; 472 this.base = INVALID_CONTENT_BASE; 473 setBundle(introBundle); 474 } 475 476 if (parser.hasXHTMLContent()) { 479 loadXHTMLContent(dom); 480 init(element, getBundle(), initialBase); 482 super.loadChildren(); 483 } else 484 loadXMLContent(dom); 486 } 487 488 495 private void loadXMLContent(Document dom) { 496 Element[] pages = ModelUtil.getElementsByTagName(dom, 497 AbstractIntroPage.TAG_PAGE); 498 if (pages.length == 0) { 499 Log.warning("Content file has no pages."); return; 501 } 502 boolean foundMatchingPage = false; 506 for (int i = 0; i < pages.length; i++) { 507 Element pageElement = pages[i]; 508 if (pageElement.getAttribute(AbstractIntroIdElement.ATT_ID).equals( 509 getId())) { 510 this.element = pageElement; 511 init(pageElement, getBundle(), base); 514 style_id = getAttribute(element, 517 AbstractBaseIntroElement.ATT_STYLE_ID); 518 filteredFrom = getAttribute(element, 519 AbstractBaseIntroElement.ATT_FILTERED_FROM); 520 sharedStyle = getAttribute(element, ATT_SHARED_STYLE); 521 if (sharedStyle == null) 522 sharedStyle = "true"; foundMatchingPage = true; 524 } 525 } 526 if (foundMatchingPage) 527 super.loadChildren(); 529 else { 530 children = new Vector (); 533 loaded = true; 534 element = null; 536 Log.warning("Content file does not have page with id= " + getId()); } 538 } 539 540 private void loadXHTMLContent(Document dom) { 541 this.dom = dom; 544 this.isXHTMLPage = true; 545 children = new Vector (); 547 loaded = true; 548 } 549 550 557 public Document getResolvedDocument() { 558 getChildren(); 560 return dom; 561 } 562 563 564 571 public Document getDocument() { 572 if (!loaded) 574 loadChildren(); 575 return dom; 576 } 577 578 579 586 public boolean isXHTMLPage() { 587 if (!loaded) 591 loadChildren(); 592 return isXHTMLPage; 593 } 594 595 596 607 public Element findDomChild(String id, String localElementName) { 608 if (!loaded) 609 loadChildren(); 610 return ModelUtil.getElementById(dom, id, localElementName); 613 } 614 615 621 public Element findDomChild(String id) { 622 return findDomChild(id, "*"); 624 } 625 626 627 628 638 protected void resolvePage() { 639 ModelUtil.insertBase(dom, ModelUtil.getParentFolderOSString(content)); 641 642 ModelUtil.updateResourceAttributes(dom.getDocumentElement(), this); 645 646 IntroModelRoot modelRoot = (IntroModelRoot)getParent(); 648 IntroPartPresentation presentation = modelRoot.getPresentation(); 649 String [] styles = presentation!=null?presentation.getImplementationStyles():null; 650 if (styles != null && injectSharedStyle()) { 651 for (int i=0; i<styles.length; i++) 652 ModelUtil.insertStyle(dom, styles[i]); 653 } 654 655 if (domProcessor == null) { 657 domProcessor = new DocumentProcessor(new ProcessorHandler[] { new FilterHandler(IntroEvaluationContext.getContext()) }); 658 } 659 UAElement element = UAElementFactory.newElement(dom.getDocumentElement()); 660 domProcessor.process(element, null); 661 662 resolveIncludes(); 664 665 ModelUtil.removeAllElements(dom, IntroAnchor.TAG_ANCHOR); 667 resolved = true; 668 } 669 670 675 protected void resolveIncludes() { 676 NodeList includes = dom.getElementsByTagNameNS("*", IntroInclude.TAG_INCLUDE); 679 Node [] nodes = ModelUtil.getArray(includes); 682 for (int i = 0; i < nodes.length; i++) { 683 Element includeElement = (Element) nodes[i]; 684 IntroInclude include = new IntroInclude(includeElement, getBundle()); 685 Object [] results = findDOMIncludeTarget(include); 687 Element targetElement = (Element) results[1]; 688 if (targetElement == null) { 689 String message = "Could not resolve following include: " + ModelLoaderUtil.getLogString(getBundle(), 691 includeElement, IntroInclude.ATT_PATH); 692 Log.warning(message); 693 return; 694 } 695 696 Node targetNode = dom.importNode(targetElement, true); 698 AbstractIntroPage page = ((AbstractIntroPage) results[0]); 701 ModelUtil.updateResourceAttributes((Element) targetNode, page); 702 includeElement.getParentNode().replaceChild(targetNode, 706 includeElement); 707 } 708 } 709 710 711 720 private Object [] findDOMIncludeTarget(IntroInclude include) { 721 String path = include.getPath(); 722 IntroModelRoot targetModelRoot = (IntroModelRoot) getParentPage() 723 .getParent(); 724 String targetConfigID = include.getConfigId(); 725 if (targetConfigID != null) 726 targetModelRoot = ExtensionPointManager.getInst().getModel( 727 targetConfigID); 728 if (targetModelRoot == null) 729 return null; 731 return findDOMTarget(targetModelRoot, path); 732 733 } 734 735 736 737 751 public Object [] findDOMTarget(IntroModelRoot model, String path) { 752 Object [] results = new Object [2]; 753 String [] pathSegments = StringUtil.split(path, "/"); if (pathSegments.length != 2) 757 return results; 759 760 AbstractIntroPage targetPage = (AbstractIntroPage) model.findChild( 762 pathSegments[0], ABSTRACT_PAGE); 763 764 if (targetPage != null) { 765 results[0] = targetPage; 766 Element targetElement = targetPage.findDomChild(pathSegments[1]); 767 if (targetElement != null) 768 results[1] = targetElement; 769 } 770 return results; 771 } 772 773 774 777 public String getContent() { 778 return content; 779 } 780 781 782 783 786 public Object clone() throws CloneNotSupportedException { 787 AbstractIntroPage clone = (AbstractIntroPage) super.clone(); 788 if (title != null) { 789 IntroPageTitle clonedTitle = (IntroPageTitle) title.clone(); 790 clonedTitle.setParent(clone); 791 clone.title = clonedTitle; 792 } 793 if (styles != null) 795 clone.styles = (Vector ) styles.clone(); 796 if (altStyles != null) 797 clone.altStyles = (Hashtable ) altStyles.clone(); 798 return clone; 799 } 800 801 807 public void setId(String id) { 808 this.originalId = this.id; 809 this.id = id; 810 } 811 812 815 public boolean injectIFrame(String url, String embedTarget) { 816 IntroGroup divToReplace = (IntroGroup) findTarget(embedTarget); 819 if (divToReplace == null) { 820 Log.warning("Failed to find embedTarget: " + embedTarget + " in page " + getId()); return false; 824 } 825 826 this.iframe = new IntroInjectedIFrame(getElement(), getBundle()); 827 this.iframe.setParent(divToReplace); 828 this.iframe.setIFrameURL(url); 829 divToReplace.clearChildren(); 830 divToReplace.addChild(iframe); 831 return true; 832 } 833 834 839 public boolean isIFramePage() { 840 return (iframe != null) ? true : false; 841 } 842 843 844 public String getUnmangledId() { 845 if (isIFramePage()) 846 return originalId; 847 return id; 848 } 849 850 851 856 public void setIFrameURL(String url) { 857 if (!isIFramePage()) 858 return; 859 this.iframe.setIFrameURL(url); 860 } 861 862 867 public String getIFrameURL() { 868 if (!isIFramePage()) 869 return null; 870 return this.iframe.getIFrameURL(); 871 } 872 873 876 public String getInitialBase() { 877 return initialBase; 878 } 879 880 885 public boolean injectSharedStyle() { 886 return this.sharedStyle.equals("true") ? true : false; } 888 889 } 890 | Popular Tags |