1 11 12 package org.eclipse.ui.internal.intro.impl.model; 13 14 import java.util.Iterator ; 15 import java.util.Vector ; 16 17 import org.eclipse.core.runtime.IConfigurationElement; 18 import org.eclipse.help.UAContentFilter; 19 import org.eclipse.help.internal.UAElementFactory; 20 import org.eclipse.ui.internal.intro.impl.model.loader.ExtensionPointManager; 21 import org.eclipse.ui.internal.intro.impl.util.IntroEvaluationContext; 22 import org.eclipse.ui.internal.intro.impl.util.Log; 23 import org.eclipse.ui.internal.intro.impl.util.StringUtil; 24 import org.osgi.framework.Bundle; 25 import org.w3c.dom.Element ; 26 import org.w3c.dom.Node ; 27 import org.w3c.dom.NodeList ; 28 29 32 public abstract class AbstractIntroContainer extends AbstractBaseIntroElement { 33 34 protected static final String ATT_BG_IMAGE = "bgImage"; protected Vector children; 38 protected boolean loaded = false; 39 protected boolean resolved = false; 40 protected Element element; 41 42 protected String base; 44 45 48 AbstractIntroContainer(IConfigurationElement element) { 49 super(element); 50 } 51 52 55 AbstractIntroContainer(Element element, Bundle bundle) { 56 super(element, bundle); 57 this.element = element; 58 } 59 60 63 AbstractIntroContainer(Element element, Bundle bundle, String base) { 64 super(element, bundle); 65 this.element = element; 66 this.base = base; 67 } 68 69 70 76 public AbstractIntroElement[] getChildren() { 77 if (!loaded) 78 loadChildren(); 79 80 if (!loaded) 81 return new AbstractIntroElement[0]; 84 85 if (!resolved) 86 resolveChildren(); 87 88 Vector filtered = filterChildren(children); 89 90 AbstractIntroElement[] childrenElements = (AbstractIntroElement[]) convertToModelArray( 91 filtered, AbstractIntroElement.ELEMENT); 92 return childrenElements; 93 } 94 95 131 public Object [] getChildrenOfType(int elementMask) { 132 133 AbstractIntroElement[] childrenElements = getChildren(); 134 Vector typedChildren = new Vector (); 137 for (int i = 0; i < childrenElements.length; i++) { 138 AbstractIntroElement element = childrenElements[i]; 139 if (element.isOfType(elementMask)) 140 typedChildren.addElement(element); 141 } 142 return convertToModelArray(typedChildren, elementMask); 143 } 144 145 155 private Object [] convertToModelArray(Vector vector, int elementMask) { 156 int size = vector.size(); 157 Object [] src = null; 158 switch (elementMask) { 159 case AbstractIntroElement.GROUP: 161 src = new IntroGroup[size]; 162 break; 163 case AbstractIntroElement.LINK: 164 src = new IntroLink[size]; 165 break; 166 case AbstractIntroElement.TEXT: 167 src = new IntroText[size]; 168 break; 169 case AbstractIntroElement.IMAGE: 170 src = new IntroImage[size]; 171 break; 172 case AbstractIntroElement.HR: 173 src = new IntroSeparator[size]; 174 break; 175 case AbstractIntroElement.HTML: 176 src = new IntroHTML[size]; 177 break; 178 case AbstractIntroElement.INCLUDE: 179 src = new IntroInclude[size]; 180 break; 181 case AbstractIntroElement.PAGE: 182 src = new IntroPage[size]; 183 break; 184 case AbstractIntroElement.ABSTRACT_PAGE: 185 src = new AbstractIntroPage[size]; 186 break; 187 case AbstractIntroElement.ABSTRACT_CONTAINER: 188 src = new AbstractIntroContainer[size]; 189 break; 190 case AbstractIntroElement.HEAD: 191 src = new IntroHead[size]; 192 break; 193 case AbstractIntroElement.PAGE_TITLE: 194 src = new IntroPageTitle[size]; 195 break; 196 case AbstractIntroElement.ANCHOR: 197 src = new IntroAnchor[size]; 198 break; 199 case AbstractIntroElement.CONTENT_PROVIDER: 200 src = new IntroContentProvider[size]; 201 break; 202 203 default: 204 src = new AbstractIntroElement[size]; 206 break; 207 } 208 if (src == null) 209 return new Object [0]; 210 211 vector.copyInto(src); 212 return src; 213 214 } 215 216 221 protected void loadChildren() { 222 children = new Vector (); 224 225 226 NodeList nodeList = element.getChildNodes(); 227 Vector vector = new Vector (); 228 for (int i = 0; i < nodeList.getLength(); i++) { 229 Node node = nodeList.item(i); 230 if (node.getNodeType() == Node.ELEMENT_NODE) 231 vector.add(node); 232 } 233 Element[] filteredElements = new Element[vector.size()]; 234 vector.copyInto(filteredElements); 235 insertElementsBefore(filteredElements, getBundle(), base, children 237 .size(), null); 238 loaded = true; 239 } 242 243 249 protected void insertElementsBefore(Element[] childElements, Bundle bundle, 250 String base, int index, String mixinStyle) { 251 for (int i = 0; i < childElements.length; i++) { 252 Element childElement = childElements[i]; 253 AbstractIntroElement child = getModelChild(childElement, bundle, 254 base); 255 if (child != null) { 256 child.setParent(this); 257 child.setMixinStyle(mixinStyle); 258 children.add(index, child); 259 index++; 261 } 262 } 263 } 264 265 271 protected void insertElementsBefore(Element[] childElements, Bundle bundle, 272 String base, AbstractIntroElement child, String mixinStyle) { 273 int childLocation = children.indexOf(child); 274 if (childLocation == -1) 275 return; 277 insertElementsBefore(childElements, bundle, base, childLocation, mixinStyle); 278 } 279 280 281 282 288 protected AbstractIntroElement getModelChild(Element childElement, 289 Bundle bundle, String base) { 290 291 AbstractIntroElement child = null; 292 if (childElement.getNodeName().equalsIgnoreCase(IntroGroup.TAG_GROUP)) 293 child = new IntroGroup(childElement, bundle, base); 294 else if (childElement.getNodeName() 295 .equalsIgnoreCase(IntroLink.TAG_LINK)) 296 child = new IntroLink(childElement, bundle, base); 297 else if (childElement.getNodeName() 298 .equalsIgnoreCase(IntroText.TAG_TEXT)) 299 child = new IntroText(childElement, bundle); 300 else if (childElement.getNodeName().equalsIgnoreCase( 301 IntroImage.TAG_IMAGE)) 302 child = new IntroImage(childElement, bundle, base); 303 else if (childElement.getNodeName().equalsIgnoreCase( 304 IntroSeparator.TAG_HR)) 305 child = new IntroSeparator(childElement, bundle, base); 306 else if (childElement.getNodeName() 307 .equalsIgnoreCase(IntroHTML.TAG_HTML)) 308 child = new IntroHTML(childElement, bundle, base); 309 else if (childElement.getNodeName().equalsIgnoreCase( 310 IntroInclude.TAG_INCLUDE)) 311 child = new IntroInclude(childElement, bundle); 312 else if (childElement.getNodeName().equalsIgnoreCase( 313 IntroAnchor.TAG_ANCHOR)) 314 child = new IntroAnchor(childElement, bundle); 315 else if (childElement.getNodeName().equalsIgnoreCase( 316 IntroContentProvider.TAG_CONTENT_PROVIDER)) 317 child = new IntroContentProvider(childElement, bundle); 318 return child; 319 } 320 321 322 326 protected void resolveChildren() { 327 AbstractIntroElement[] array = (AbstractIntroElement[])children.toArray(new AbstractIntroElement[children.size()]); 328 for (int i=0;i<array.length;++i) { 329 AbstractIntroElement child = array[i]; 330 if (UAContentFilter.isFiltered(UAElementFactory.newElement(child.getElement()), IntroEvaluationContext.getContext())) { 331 children.remove(child); 332 } 333 else if (child.getType() == AbstractIntroElement.INCLUDE) { 334 resolveInclude((IntroInclude) child); 335 } 336 } 337 resolved = true; 338 } 339 340 348 private void resolveInclude(IntroInclude include) { 349 AbstractIntroElement target = findIncludeTarget(include); 350 if (target == null) 351 return; 353 if (target.isOfType(AbstractIntroElement.GROUP 354 | AbstractIntroElement.ABSTRACT_TEXT 355 | AbstractIntroElement.IMAGE | AbstractIntroElement.TEXT 356 | AbstractIntroElement.PAGE_TITLE)) 357 insertTarget(include, target); 360 } 361 362 370 private Vector filterChildren(Vector unfiltered) { 371 Vector filtered = new Vector (); 372 Iterator iter = unfiltered.iterator(); 373 while (iter.hasNext()) { 374 Object element = iter.next(); 375 if (!UAContentFilter.isFiltered(element, IntroEvaluationContext.getContext())) { 376 filtered.add(element); 377 } 378 } 379 return filtered; 380 } 381 382 391 private AbstractIntroElement findIncludeTarget(IntroInclude include) { 392 String path = include.getPath(); 393 IntroModelRoot targetModelRoot = (IntroModelRoot) getParentPage() 394 .getParent(); 395 String targetConfigID = include.getConfigId(); 396 if (targetConfigID != null) 397 targetModelRoot = ExtensionPointManager.getInst().getModel( 398 targetConfigID); 399 if (targetModelRoot == null) 400 return null; 402 AbstractIntroElement target = findTarget(targetModelRoot, path); 403 return target; 404 } 405 406 416 public AbstractIntroElement findTarget(AbstractIntroContainer container, 417 String path) { 418 String [] pathSegments = StringUtil.split(path, "/"); if (container == null) 421 return null; 422 423 AbstractIntroElement target = container.findChild(pathSegments[0]); 424 if (target == null) 425 return null; 427 428 for (int i = 1; i < pathSegments.length; i++) { 430 if (!(target instanceof AbstractIntroContainer)) { 431 return null; 433 } 434 String pathSegment = pathSegments[i]; 435 target = ((AbstractIntroContainer) target).findChild(pathSegment); 436 if (target == null) 437 return null; 439 } 440 return target; 441 } 442 443 public AbstractIntroElement findTarget(AbstractIntroContainer container, 444 String path, String extensionId) { 445 if (path.indexOf("@")!= -1) { IntroModelRoot root = getModelRoot(); 449 if (root!=null) { 450 path = root.resolvePath(extensionId, path); 451 if (path==null) 452 return null; 453 } 454 455 } 456 return this.findTarget(container, path); 457 } 458 459 460 public AbstractIntroElement findTarget(String path) { 461 return findTarget(this, path); 462 } 463 464 465 466 473 public AbstractIntroElement findChild(String elementId) { 474 return findChild(elementId, ID_ELEMENT); 475 } 476 477 485 public AbstractIntroElement findChild(String elementId, int elementMask) { 486 if (!loaded) 487 loadChildren(); 488 489 for (int i = 0; i < children.size(); i++) { 490 AbstractIntroElement aChild = (AbstractIntroElement) children 491 .elementAt(i); 492 if (!aChild.isOfType(ID_ELEMENT)) 493 continue; 499 AbstractIntroIdElement child = (AbstractIntroIdElement) aChild; 500 if (child.getId() != null && child.getId().equals(elementId) 501 && child.isOfType(elementMask)) 502 return child; 503 } 504 return null; 506 } 507 508 509 510 private void insertTarget(IntroInclude include, AbstractIntroElement target) { 511 int includeLocation = children.indexOf(include); 512 if (includeLocation == -1) 513 return; 515 children.remove(includeLocation); 516 handleIncludeStyleInheritence(include, target); 519 AbstractIntroElement clonedTarget = null; 522 try { 523 clonedTarget = (AbstractIntroElement) target.clone(); 524 } catch (CloneNotSupportedException ex) { 525 Log.error("Failed to clone Intro model node.", ex); return; 528 } 529 clonedTarget.setParent(this); 531 children.insertElementAt(clonedTarget, includeLocation); 532 } 533 534 546 private void handleIncludeStyleInheritence(IntroInclude include, 547 AbstractIntroElement target) { 548 549 if (include.getMergeStyle() == false) 550 return; 552 553 if (target.getParent().getType() == AbstractIntroElement.MODEL_ROOT 554 || target.getParentPage().equals(include.getParentPage())) 555 return; 559 560 String style = target.getParentPage().getStyle(); 564 if (style != null) 565 getParentPage().addStyle(style); 566 567 style = target.getParentPage().getAltStyle(); 569 if (style != null) { 570 Bundle bundle = target.getBundle(); 571 getParentPage().addAltStyle(style, bundle); 572 } 573 574 getParentPage().addStyles(target.getParentPage().getStyles()); 577 getParentPage().addAltStyles(target.getParentPage().getAltStyles()); 578 579 } 580 581 592 protected AbstractIntroElement cloneTarget(AbstractIntroElement target) { 593 return null; 594 } 595 596 597 602 public int getType() { 603 return AbstractIntroElement.ABSTRACT_CONTAINER; 604 } 605 606 607 608 612 public Object clone() throws CloneNotSupportedException { 613 AbstractIntroContainer clone = (AbstractIntroContainer) super.clone(); 614 clone.children = new Vector (); 615 if (children != null) { 616 for (int i = 0; i < children.size(); i++) { 617 AbstractIntroElement cloneChild = (AbstractIntroElement) ((AbstractIntroElement) children 618 .elementAt(i)).clone(); 619 cloneChild.setParent(clone); 620 clone.children.add(i, cloneChild); 621 } 622 } 623 return clone; 624 } 625 626 631 public Element getElement() { 632 return this.element; 633 } 634 635 public String getBase() { 636 return base; 637 } 638 639 640 644 public void clearChildren() { 645 this.children.clear(); 646 } 647 648 649 655 public void addChild(AbstractIntroElement child) { 656 children.add(child); 657 } 658 659 public void removeChild(AbstractIntroElement child) { 660 children.remove(child); 661 } 662 663 public String getBackgroundImage() { 664 return getAttribute(element, ATT_BG_IMAGE); 665 } 666 667 668 } | Popular Tags |