1 11 package org.eclipse.pde.internal.core.schema; 12 13 import java.io.FileNotFoundException ; 14 import java.io.IOException ; 15 import java.io.InputStream ; 16 import java.io.PrintWriter ; 17 import java.net.URL ; 18 import java.util.Iterator ; 19 import java.util.Locale ; 20 import java.util.Vector ; 21 22 import org.eclipse.core.runtime.PlatformObject; 23 import org.eclipse.pde.core.IModelChangedEvent; 24 import org.eclipse.pde.core.IModelChangedListener; 25 import org.eclipse.pde.core.ModelChangedEvent; 26 import org.eclipse.pde.internal.core.PDECore; 27 import org.eclipse.pde.internal.core.XMLDefaultHandler; 28 import org.eclipse.pde.internal.core.ischema.IDocumentSection; 29 import org.eclipse.pde.internal.core.ischema.IMetaAttribute; 30 import org.eclipse.pde.internal.core.ischema.ISchema; 31 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute; 32 import org.eclipse.pde.internal.core.ischema.ISchemaComplexType; 33 import org.eclipse.pde.internal.core.ischema.ISchemaCompositor; 34 import org.eclipse.pde.internal.core.ischema.ISchemaDescriptor; 35 import org.eclipse.pde.internal.core.ischema.ISchemaElement; 36 import org.eclipse.pde.internal.core.ischema.ISchemaEnumeration; 37 import org.eclipse.pde.internal.core.ischema.ISchemaInclude; 38 import org.eclipse.pde.internal.core.ischema.ISchemaObject; 39 import org.eclipse.pde.internal.core.ischema.ISchemaObjectReference; 40 import org.eclipse.pde.internal.core.ischema.ISchemaRootElement; 41 import org.eclipse.pde.internal.core.ischema.ISchemaSimpleType; 42 import org.eclipse.pde.internal.core.ischema.ISchemaType; 43 import org.eclipse.pde.internal.core.util.PDEXMLHelper; 44 import org.eclipse.pde.internal.core.util.SAXParserWrapper; 45 import org.eclipse.pde.internal.core.util.SchemaUtil; 46 import org.w3c.dom.NamedNodeMap ; 47 import org.w3c.dom.Node ; 48 import org.w3c.dom.NodeList ; 49 import org.xml.sax.SAXException ; 50 51 public class Schema extends PlatformObject implements ISchema { 52 53 private URL fURL; 54 55 private Vector fListeners = new Vector (); 56 57 private Vector fElements = new Vector (); 58 59 private Vector fDocSections = new Vector (); 60 61 private Vector fIncludes; 62 63 private String fPointID; 64 65 private String fPluginID; 66 67 private ISchemaDescriptor fSchemaDescriptor; 68 69 private boolean fLoaded; 70 71 private Vector fReferences; 72 73 private String fDescription; 74 75 private String fName = ""; 77 private boolean fNotificationEnabled; 78 79 public final static String INDENT = " "; 81 private boolean fDisposed; 82 83 private boolean fValid; 84 85 private boolean fAbbreviated; 86 87 public Schema(String pluginId, String pointId, String name, boolean abbreviated) { 88 fPluginID = pluginId; 89 fPointID = pointId; 90 fName = name; 91 fAbbreviated = abbreviated; 92 } 93 94 public Schema(ISchemaDescriptor schemaDescriptor, URL url, boolean abbreviated) { 95 fSchemaDescriptor = schemaDescriptor; 96 fURL = url; 97 fAbbreviated = abbreviated; 98 } 99 100 public void addDocumentSection(IDocumentSection docSection) { 101 fDocSections.addElement(docSection); 102 fireModelChanged(new ModelChangedEvent(this, IModelChangedEvent.INSERT, 103 new Object [] { docSection }, null)); 104 } 105 106 public void addElement(ISchemaElement element) { 107 addElement(element, null); 108 } 109 110 public void addElement(ISchemaElement element, ISchemaElement afterElement) { 111 int index = -1; 112 if (afterElement != null) { 113 index = fElements.indexOf(afterElement); 114 } 115 if (index != -1) 116 fElements.add(index + 1, element); 117 else 118 fElements.add(element); 119 fireModelChanged(new ModelChangedEvent(this, IModelChangedEvent.INSERT, 120 new Object [] { element }, null)); 121 } 122 123 public void addInclude(ISchemaInclude include) { 124 if (fIncludes == null) 125 fIncludes = new Vector (); 126 fIncludes.add(include); 127 fireModelChanged(new ModelChangedEvent(this, IModelChangedEvent.INSERT, 128 new Object [] { include }, null)); 129 } 130 131 public void removeInclude(ISchemaInclude include) { 132 if (fIncludes == null) 133 return; 134 fIncludes.remove(include); 135 fireModelChanged(new ModelChangedEvent(this, IModelChangedEvent.REMOVE, 136 new Object [] { include }, null)); 137 } 138 139 public void addModelChangedListener(IModelChangedListener listener) { 140 fListeners.addElement(listener); 141 } 142 143 private void collectElements(ISchemaCompositor compositor, Vector result) { 144 Object [] children = compositor.getChildren(); 145 for (int i = 0; i < children.length; i++) { 146 Object child = children[i]; 147 if (child instanceof ISchemaCompositor) 148 collectElements((ISchemaCompositor) child, result); 149 else if (child instanceof ISchemaObjectReference) { 150 ISchemaObjectReference ref = (ISchemaObjectReference) child; 151 Object referenced = ref.getReferencedObject(); 152 if (referenced instanceof ISchemaElement) 153 result.addElement(referenced); 154 } 155 } 156 } 157 158 public void dispose() { 159 if (fIncludes != null) { 160 for (int i = 0; i < fIncludes.size(); i++) { 161 ISchemaInclude include = (ISchemaInclude) fIncludes.get(i); 162 include.dispose(); 163 } 164 } 165 reset(); 166 fDisposed = true; 167 } 168 169 public ISchemaElement findElement(String name) { 170 if (!isLoaded()) 171 load(); 172 for (int i = 0; i < fElements.size(); i++) { 173 ISchemaElement element = (ISchemaElement) fElements.elementAt(i); 174 if (element.getName().equals(name)) 175 return element; 176 } 177 if (fIncludes != null) { 178 for (int i = 0; i < fIncludes.size(); i++) { 179 ISchemaInclude include = (ISchemaInclude) fIncludes.get(i); 180 ISchema ischema = include.getIncludedSchema(); 181 if (ischema == null) 182 continue; 183 ISchemaElement element = ischema.findElement(name); 184 if (element != null) 185 return element; 186 } 187 } 188 return null; 189 } 190 191 public void fireModelChanged(IModelChangedEvent event) { 192 if (!fNotificationEnabled) 193 return; 194 for (Iterator iter = fListeners.iterator(); iter.hasNext();) { 195 IModelChangedListener listener = (IModelChangedListener) iter 196 .next(); 197 listener.modelChanged(event); 198 } 199 } 200 201 public void fireModelObjectChanged(Object object, String property, 202 Object oldValue, Object newValue) { 203 fireModelChanged(new ModelChangedEvent(this, object, property, 204 oldValue, newValue)); 205 } 206 207 private String getAttribute(Node node, String name) { 208 NamedNodeMap map = node.getAttributes(); 209 Node attNode = map.getNamedItem(name); 210 if (attNode != null) { 211 String value = attNode.getNodeValue(); 212 if (value.length() > 0) 213 return value; 214 } 215 return null; 216 } 217 218 public ISchemaElement[] getCandidateChildren(ISchemaElement element) { 219 Vector candidates = new Vector (); 220 ISchemaType type = element.getType(); 221 if (type instanceof ISchemaComplexType) { 222 ISchemaCompositor compositor = ((ISchemaComplexType)type).getCompositor(); 223 if (compositor != null) 224 collectElements(compositor, candidates); 225 } 226 ISchemaElement[] result = new ISchemaElement[candidates.size()]; 227 candidates.copyInto(result); 228 return result; 229 } 230 231 public String getDescription() { 232 return fDescription; 233 } 234 235 public boolean isValid() { 236 return fValid; 237 } 238 239 public IDocumentSection[] getDocumentSections() { 240 IDocumentSection[] result = new IDocumentSection[fDocSections.size()]; 241 fDocSections.copyInto(result); 242 return result; 243 } 244 245 public int getElementCount() { 246 return fElements.size(); 247 } 248 249 public int getResolvedElementCount() { 250 int localCount = getElementCount(); 251 if (fIncludes == null) 252 return localCount; 253 int totalCount = localCount; 254 for (int i = 0; i < fIncludes.size(); i++) { 255 ISchemaInclude include = (ISchemaInclude) fIncludes.get(i); 256 ISchema schema = include.getIncludedSchema(); 257 if (schema == null) 258 continue; 259 totalCount += schema.getResolvedElementCount(); 260 } 261 return totalCount; 262 } 263 264 public ISchemaElement[] getElements() { 265 if (!isLoaded()) 266 load(); 267 ISchemaElement[] result = new ISchemaElement[fElements.size()]; 268 fElements.copyInto(result); 269 return result; 270 } 271 272 public ISchemaElement[] getResolvedElements() { 273 if (fIncludes == null) 274 return getElements(); 275 if (!isLoaded()) 276 load(); 277 Vector result = (Vector ) fElements.clone(); 278 for (int i = 0; i < fIncludes.size(); i++) { 279 ISchemaInclude include = (ISchemaInclude) fIncludes.get(i); 280 ISchema schema = include.getIncludedSchema(); 281 if (schema == null) 282 continue; 283 ISchemaElement[] ielements = schema.getElements(); 284 for (int j = 0; j < ielements.length; j++) 285 result.add(ielements[j]); 286 } 287 return (ISchemaElement[]) result.toArray(new ISchemaElement[result 288 .size()]); 289 } 290 291 public ISchemaInclude[] getIncludes() { 292 if (fIncludes == null) 293 return new ISchemaInclude[0]; 294 return (ISchemaInclude[]) fIncludes.toArray(new ISchemaInclude[fIncludes 295 .size()]); 296 } 297 298 public String getName() { 299 return fName; 300 } 301 302 private String getNormalizedText(String source) { 303 if (source == null) 304 return ""; 306 String result = source.replace('\t', ' '); 307 result = result.trim(); 308 return result; 309 } 310 311 public ISchemaObject getParent() { 312 return null; 313 } 314 315 public void setParent(ISchemaObject obj) { 316 } 317 318 public ISchemaElement getElementAt(int index) 319 { return (ISchemaElement)fElements.get(index); 320 } 321 322 public String getQualifiedPointId() { 323 return fPluginID + "." + fPointID; } 325 326 public String getPluginId() { 327 return fPluginID; 328 } 329 330 public String getPointId() { 331 return fPointID; 332 } 333 334 public ISchema getSchema() { 335 return this; 336 } 337 338 public ISchemaDescriptor getSchemaDescriptor() { 339 return fSchemaDescriptor; 340 } 341 342 public URL getURL() { 343 return fURL; 344 } 345 346 public int indexOf(Object obj) { 347 return fElements.indexOf(obj); 348 } 349 350 public boolean isDisposed() { 351 return fDisposed; 352 } 353 354 public boolean isEditable() { 355 return false; 356 } 357 358 public boolean isLoaded() { 359 return fLoaded; 360 } 361 362 public boolean isNotificationEnabled() { 363 return fNotificationEnabled; 364 } 365 366 public void load() { 367 InputStream input = null; 368 try { 369 input = SchemaUtil.getInputStream(fURL); 370 load(input); 371 } catch (FileNotFoundException e) { 372 fLoaded = false; 373 } catch (IOException e) { 374 PDECore.logException(e); 375 } finally { 376 try { 377 if (input != null) 378 input.close(); 379 } catch (IOException e1) { 380 } 381 } 382 } 383 384 public void load(InputStream stream) { 385 try { 386 SAXParserWrapper parser = new SAXParserWrapper(); 387 XMLDefaultHandler handler = new XMLDefaultHandler(fAbbreviated); 388 parser.parse(stream, handler); 389 traverseDocumentTree(handler.getDocumentElement()); 390 } catch (SAXException e) { 391 } catch (Exception e) { 393 PDECore.logException(e); 394 } 395 } 396 397 private ISchemaAttribute processAttribute(ISchemaElement element, 398 Node elementNode) { 399 String aname = getAttribute(elementNode, "name"); String atype = getAttribute(elementNode, "type"); String ause = getAttribute(elementNode, "use"); String avalue = getAttribute(elementNode, "value"); ISchemaSimpleType type = null; 404 if (atype != null) { 405 type = (ISchemaSimpleType) resolveTypeReference(atype); 406 } 407 SchemaAttribute attribute = new SchemaAttribute(element, aname); 408 if (ause != null) { 410 int use = ISchemaAttribute.OPTIONAL; 411 if (ause.equals("required")) use = ISchemaAttribute.REQUIRED; 413 else if (ause.equals("optional")) use = ISchemaAttribute.OPTIONAL; 415 else if (ause.equals("default")) use = ISchemaAttribute.DEFAULT; 417 attribute.setUse(use); 418 } 419 if (avalue != null) 420 attribute.setValue(avalue); 421 NodeList children = elementNode.getChildNodes(); 422 for (int i = 0; i < children.getLength(); i++) { 423 Node child = children.item(i); 424 if (child.getNodeType() == Node.ELEMENT_NODE) { 425 String tag = child.getNodeName(); 426 if (tag.equals("annotation")) { processAttributeAnnotation(attribute, child); 428 } else if (tag.equals("simpleType")) { processAttributeSimpleType(attribute, child); 430 } 431 } 432 } 433 if (type != null && attribute.getType() == null) 434 attribute.setType(type); 435 return attribute; 436 } 437 438 private void processAttributeAnnotation(SchemaAttribute element, Node node) { 439 NodeList children = node.getChildNodes(); 440 for (int i = 0; i < children.getLength(); i++) { 441 Node child = children.item(i); 442 if (child.getNodeType() == Node.ELEMENT_NODE) { 443 if (child.getNodeName().equals("documentation")) { Node doc = child.getFirstChild(); 445 if (doc != null) 446 element.setDescription(getNormalizedText(doc.getNodeValue())); 447 } else if (child.getNodeName().equals("appInfo")) { NodeList infos = child.getChildNodes(); 449 for (int j = 0; j < infos.getLength(); j++) { 450 Node meta = infos.item(j); 451 if (meta.getNodeType() == Node.ELEMENT_NODE) { 452 if (meta.getNodeName().equals("meta.attribute")) { element.setKind(processKind(getAttribute(meta, 454 "kind"))); element.setBasedOn( 456 getAttribute(meta,"basedOn")); element.setTranslatableProperty( 458 processTranslatable(getAttribute( 459 meta, "translatable"))); element.setDeprecatedProperty( 461 processDeprecated(getAttribute( 462 meta, "deprecated"))); } 464 } 465 } 466 } 467 } 468 } 469 } 470 471 private boolean processTranslatable(String value) { 472 return (value != null && "true".equals(value)); } 474 475 private boolean processDeprecated(String value) { 476 return value != null && "true".equals(value); } 478 479 private SchemaSimpleType processAttributeRestriction( 480 SchemaAttribute attribute, Node node) { 481 NodeList children = node.getChildNodes(); 482 if (children.getLength() == 0) 483 return null; 484 String baseName = getAttribute(node, "base"); if (baseName.equals("string") == false) { return new SchemaSimpleType(attribute.getSchema(), "string"); } 488 SchemaSimpleType type = new SchemaSimpleType(attribute.getSchema(), 489 baseName); 490 Vector items = new Vector (); 491 for (int i = 0; i < children.getLength(); i++) { 492 Node child = children.item(i); 493 if (child.getNodeType() == Node.ELEMENT_NODE) { 494 if (child.getNodeName().equals("enumeration")) { ISchemaEnumeration enumeration = processEnumeration( 496 attribute.getSchema(), child); 497 if (enumeration != null) 498 items.addElement(enumeration); 499 } 500 } 501 } 502 ChoiceRestriction restriction = new ChoiceRestriction(attribute 503 .getSchema()); 504 restriction.setChildren(items); 505 type.setRestriction(restriction); 506 return type; 507 } 508 509 private void processAttributeSimpleType(SchemaAttribute attribute, Node node) { 510 NodeList children = node.getChildNodes(); 511 if (children.getLength() == 0) 512 return; 513 SchemaSimpleType type = null; 514 for (int i = 0; i < children.getLength(); i++) { 515 Node child = children.item(i); 516 if (child.getNodeType() == Node.ELEMENT_NODE) { 517 if (child.getNodeName().equals("restriction")) { type = processAttributeRestriction(attribute, child); 519 } 520 } 521 } 522 if (type != null) 523 attribute.setType(type); 524 } 525 526 private SchemaComplexType processComplexType(ISchemaElement owner, 527 Node typeNode) { 528 String aname = getAttribute(typeNode, "name"); String amixed = getAttribute(typeNode, "mixed"); SchemaComplexType complexType = new SchemaComplexType(this, aname); 531 if (amixed != null && amixed.equals("true")) complexType.setMixed(true); 533 NodeList children = typeNode.getChildNodes(); 534 ISchemaCompositor compositor = null; 535 for (int i = 0; i < children.getLength(); i++) { 536 Node child = children.item(i); 537 if (child.getNodeType() == Node.ELEMENT_NODE) { 538 if (child.getNodeName().equals("attribute")) { complexType.addAttribute(processAttribute(owner, child)); 540 } else { 541 ISchemaObject object = processCompositorChild(owner, child, 542 ISchemaCompositor.ROOT); 543 if (object instanceof ISchemaCompositor 544 && compositor == null) { 545 compositor = (ISchemaCompositor) object; 546 } 547 } 548 } 549 } 550 complexType.setCompositor(compositor); 551 return complexType; 552 } 553 554 private ISchemaCompositor processCompositor(ISchemaObject parent, 555 Node node, int type) { 556 SchemaCompositor compositor = new SchemaCompositor(parent, type); 557 NodeList children = node.getChildNodes(); 558 int minOccurs = 1; 559 int maxOccurs = 1; 560 String aminOccurs = getAttribute(node, "minOccurs"); String amaxOccurs = getAttribute(node, "maxOccurs"); if (aminOccurs != null) 563 minOccurs = Integer.valueOf(aminOccurs).intValue(); 564 if (amaxOccurs != null) { 565 if (amaxOccurs.equals("unbounded")) maxOccurs = Integer.MAX_VALUE; 567 else { 568 maxOccurs = Integer.valueOf(amaxOccurs).intValue(); 569 } 570 } 571 compositor.setMinOccurs(minOccurs); 572 compositor.setMaxOccurs(maxOccurs); 573 for (int i = 0; i < children.getLength(); i++) { 574 Node child = children.item(i); 575 ISchemaObject object = processCompositorChild(compositor, child, 576 type); 577 if (object != null) 578 compositor.addChild(object); 579 } 580 return compositor; 581 } 582 583 private ISchemaObject processCompositorChild(ISchemaObject parent, 584 Node child, int parentKind) { 585 String tag = child.getNodeName(); 586 if (tag.equals("element") && parentKind != ISchemaCompositor.ROOT) { return processElement(parent, child); 588 } 589 if (tag.equals("sequence") && parentKind != ISchemaCompositor.ALL) { return processCompositor(parent, child, ISchemaCompositor.SEQUENCE); 592 } 593 if (tag.equals("choice") && parentKind != ISchemaCompositor.ALL) { return processCompositor(parent, child, ISchemaCompositor.CHOICE); 596 } 597 if (tag.equals("all") && (parentKind == ISchemaCompositor.ROOT || parentKind == ISchemaCompositor.GROUP)) { 600 return processCompositor(parent, child, ISchemaCompositor.SEQUENCE); 601 } 602 if (tag.equals("group") && (parentKind == ISchemaCompositor.CHOICE || parentKind == ISchemaCompositor.SEQUENCE)) { 605 return processCompositor(parent, child, ISchemaCompositor.SEQUENCE); 606 } 607 return null; 608 } 609 610 private ISchemaElement processElement(ISchemaObject parent, Node elementNode) { 611 String aname = getAttribute(elementNode, "name"); String atype = getAttribute(elementNode, "type"); String aref = getAttribute(elementNode, "ref"); 615 int minOccurs = 1; 616 int maxOccurs = 1; 617 String aminOccurs = getAttribute(elementNode, "minOccurs"); String amaxOccurs = getAttribute(elementNode, "maxOccurs"); if (aminOccurs != null) 620 minOccurs = Integer.valueOf(aminOccurs).intValue(); 621 if (amaxOccurs != null) { 622 if (amaxOccurs.equals("unbounded")) maxOccurs = Integer.MAX_VALUE; 624 else { 625 maxOccurs = Integer.valueOf(amaxOccurs).intValue(); 626 } 627 } 628 if (aref != null) { 629 SchemaElementReference reference = new SchemaElementReference( 631 (ISchemaCompositor) parent, aref); 632 reference.addComments(elementNode); 633 reference.setMinOccurs(minOccurs); 634 reference.setMaxOccurs(maxOccurs); 635 fReferences.addElement(reference); 636 return reference; 638 } 639 ISchemaType type = null; 640 if (atype != null) { 641 type = resolveTypeReference(atype); 642 } 643 SchemaElement element; 644 if (aname.equals("extension")) element = new SchemaRootElement(parent, aname); 646 else 647 element = new SchemaElement(parent, aname); 648 element.setMinOccurs(minOccurs); 650 element.setMaxOccurs(maxOccurs); 651 NodeList children = elementNode.getChildNodes(); 652 for (int i = 0; i < children.getLength(); i++) { 653 Node child = children.item(i); 654 if (child.getNodeType() == Node.ELEMENT_NODE) { 655 String tag = child.getNodeName(); 656 if (type == null && tag.equals("complexType")) { type = processComplexType(element, child); 658 } 659 if (tag.equals("annotation")) { processElementAnnotation(element, child); 661 } 662 } 663 } 664 element.setType(type); 665 return element; 666 } 667 668 private void processElementAnnotation(SchemaElement element, Node node) { 669 NodeList children = node.getChildNodes(); 670 for (int i = 0; i < children.getLength(); i++) { 671 Node child = children.item(i); 672 if (child.getNodeType() == Node.ELEMENT_NODE) { 673 if (child.getNodeName().equals("documentation") && !fAbbreviated) { element.setDescription(getNormalizedText(child 675 .getFirstChild().getNodeValue())); 676 } else if (child.getNodeName().equals("appInfo")) { NodeList infos = child.getChildNodes(); 678 for (int j = 0; j < infos.getLength(); j++) { 679 Node meta = infos.item(j); 680 if (meta.getNodeType() == Node.ELEMENT_NODE) { 681 if (meta.getNodeName().equals("meta.element")) { element.setLabelProperty(getAttribute(meta, 683 "labelAttribute")); element.setIconProperty(getAttribute(meta, 685 "icon")); if (element.getIconProperty() == null) 687 element.setIconProperty(getAttribute(meta, 688 "iconName")); element.setTranslatableProperty(processTranslatable(getAttribute( 690 meta, "translatable"))); element.setDeprecatedProperty(processDeprecated(getAttribute( 692 meta, "deprecated"))); if (element instanceof ISchemaRootElement) { 694 String depSug = getAttribute(meta, SchemaRootElement.P_DEP_REPLACEMENT); 695 ((ISchemaRootElement)element).setDeprecatedSuggestion(depSug); 696 } 697 } 698 } 699 } 700 } 701 } 702 } 703 } 704 705 private ISchemaEnumeration processEnumeration(ISchema schema, Node node) { 706 String name = getAttribute(node, "value"); return new SchemaEnumeration(schema, name); 708 } 709 710 private int processKind(String name) { 711 if (name != null) { 712 if (name.equals("java")) return IMetaAttribute.JAVA; 714 if (name.equals("resource")) return IMetaAttribute.RESOURCE; 716 } 717 return IMetaAttribute.STRING; 718 } 719 720 private void processSchemaAnnotation(Node node) { 721 NodeList children = node.getChildNodes(); 722 String section = "overview"; String sectionName = "Overview"; for (int i = 0; i < children.getLength(); i++) { 725 Node child = children.item(i); 726 if (child.getNodeType() == Node.ELEMENT_NODE) { 727 if (child.getNodeName().equals("documentation") && !fAbbreviated) { String text = getNormalizedText(child.getFirstChild() 729 .getNodeValue()); 730 if (section != null) { 731 if (section.equals("overview")) { setDescription(text); 733 } else { 734 DocumentSection sec = new DocumentSection(this, 735 section, sectionName); 736 sec.setDescription(text); 737 fDocSections.addElement(sec); 738 } 739 } 740 } else if (child.getNodeName().equals("appInfo")) { NodeList infos = child.getChildNodes(); 742 for (int j = 0; j < infos.getLength(); j++) { 743 Node meta = infos.item(j); 744 if (meta.getNodeType() == Node.ELEMENT_NODE) { 745 if (meta.getNodeName().equals("meta.schema")) { section = "overview"; setName(getAttribute(meta, "name")); fPluginID = getAttribute(meta, "plugin"); fPointID = getAttribute(meta, "id"); fValid = true; 751 } else if (meta.getNodeName() 752 .equals("meta.section")) { section = getAttribute(meta, "type"); sectionName = getAttribute(meta, "name"); if (sectionName == null) 756 sectionName = section; 757 } 758 } 759 } 760 } 761 } 762 } 763 } 764 765 private void processInclude(Node node) { 766 String location = getAttribute(node, "schemaLocation"); SchemaInclude include = new SchemaInclude(this, location, fAbbreviated); 768 if (fIncludes == null) 769 fIncludes = new Vector (); 770 fIncludes.add(include); 771 } 772 773 public void reload() { 774 reload(null); 775 } 776 777 public void reload(InputStream is) { 778 setNotificationEnabled(false); 779 reset(); 780 if (is != null) 781 load(is); 782 else 783 load(); 784 setNotificationEnabled(true); 785 if (isLoaded()) 786 fireModelChanged(new ModelChangedEvent(this, 787 IModelChangedEvent.WORLD_CHANGED, new Object [0], null)); 788 } 789 790 public void removeDocumentSection(IDocumentSection docSection) { 791 fDocSections.removeElement(docSection); 792 fireModelChanged(new ModelChangedEvent(this, IModelChangedEvent.REMOVE, 793 new Object [] { docSection }, null)); 794 } 795 796 public void moveElementToSibling(ISchemaElement element, ISchemaObject sibling) { 797 if (!isLoaded()) 798 load(); 799 int index = fElements.indexOf(element); 800 int newIndex; 801 if (sibling != null && fElements.contains(sibling)) 802 newIndex = fElements.indexOf(sibling); 803 else 804 newIndex = fElements.size() - 1; 805 806 if (index > newIndex) { 807 for (int i = index; i > newIndex; i--) { 808 fElements.set(i, fElements.elementAt(i - 1)); 809 } 810 } else if (index < newIndex) { 811 for (int i = index; i < newIndex; i++) { 812 fElements.set(i, fElements.elementAt(i + 1)); 813 } 814 } else return; 816 fElements.set(newIndex, element); 817 fireModelChanged(new ModelChangedEvent(this, IModelChangedEvent.CHANGE, 818 new Object [] { this }, null)); 819 } 820 821 public void removeElement(ISchemaElement element) { 822 fElements.removeElement(element); 823 fireModelChanged(new ModelChangedEvent(this, IModelChangedEvent.REMOVE, 824 new Object [] { element }, null)); 825 } 826 827 public void removeModelChangedListener(IModelChangedListener listener) { 828 fListeners.removeElement(listener); 829 } 830 831 private void reset() { 832 fElements = new Vector (); 833 fDocSections = new Vector (); 834 fIncludes = null; 835 fPointID = null; 836 fPluginID = null; 837 fReferences = null; 838 fDescription = null; 839 fName = null; 840 fValid = false; 841 fLoaded = false; 842 } 843 844 private void resolveElementReference(ISchemaObjectReference reference) { 845 ISchemaElement[] elementList = getResolvedElements(); 846 for (int i = 0; i < elementList.length; i++) { 847 ISchemaElement element = elementList[i]; 848 if (!(element instanceof ISchemaObjectReference) 849 && element.getName().equals(reference.getName())) { 850 reference.setReferencedObject(element); 852 break; 853 } 854 } 855 } 856 857 private void resolveReference(ISchemaObjectReference reference) { 858 Class clazz = reference.getReferencedObjectClass(); 859 if (clazz.equals(ISchemaElement.class)) { 860 resolveElementReference(reference); 861 } 862 } 863 864 private void resolveReferences(Vector references) { 865 for (int i = 0; i < references.size(); i++) { 866 ISchemaObjectReference reference = (ISchemaObjectReference) references 867 .elementAt(i); 868 resolveReference(reference); 869 } 870 } 871 872 private SchemaType resolveTypeReference(String typeName) { 873 return new SchemaSimpleType(this, typeName); 875 } 876 877 public void setDescription(String newDescription) { 878 String oldValue = fDescription; 879 fDescription = newDescription; 880 fireModelObjectChanged(this, P_DESCRIPTION, oldValue, fDescription); 881 } 882 883 public void setName(String newName) { 884 if (newName == null) 885 newName = ""; String oldValue = fName; 887 fName = newName; 888 fireModelObjectChanged(this, P_NAME, oldValue, fName); 889 } 890 891 public void setPluginId(String newId) { 892 String oldValue = fPluginID; 893 fPluginID = newId; 894 fireModelObjectChanged(this, P_PLUGIN, oldValue, newId); 895 } 896 897 public void setPointId(String newId) { 898 String oldValue = fPointID; 899 fPointID = newId; 900 fireModelObjectChanged(this, P_POINT, oldValue, newId); 901 } 902 903 public void setNotificationEnabled(boolean newNotificationEnabled) { 904 fNotificationEnabled = newNotificationEnabled; 905 } 906 907 public String toString() { 908 return fName; 909 } 910 911 public void traverseDocumentTree(Node root) { 912 if (root == null) 913 return; 914 NodeList children = root.getChildNodes(); 915 fReferences = new Vector (); 916 for (int i = 0; i < children.getLength(); i++) { 917 Node child = children.item(i); 918 if (child.getNodeType() == Node.ELEMENT_NODE) { 919 String nodeName = child.getNodeName().toLowerCase(Locale.ENGLISH); 920 if (nodeName.equals("element")) { ISchemaElement element = processElement(this, child); 922 fElements.addElement(element); 923 } else if (nodeName.equals("annotation")) { processSchemaAnnotation(child); 925 } else if (nodeName.equals("include")) { processInclude(child); 927 } 928 } 929 } 930 fLoaded = true; 931 if (fReferences.size() > 0) 932 resolveReferences(fReferences); 933 fReferences = null; 934 } 935 936 public void updateReferencesFor(ISchemaElement element) { 937 updateReferencesFor(element, ISchema.REFRESH_RENAME); 938 } 939 940 public void updateReferencesFor(ISchemaElement element, int kind) { 941 for (int i = 0; i < fElements.size(); i++) { 942 ISchemaElement el = (ISchemaElement) fElements.elementAt(i); 943 if (el.equals(element)) 944 continue; 945 ISchemaType type = el.getType(); 946 if (type instanceof ISchemaComplexType) { 947 SchemaCompositor compositor = (SchemaCompositor) ((ISchemaComplexType) type) 948 .getCompositor(); 949 if (compositor != null) 950 compositor.updateReferencesFor(element, kind); 951 } 952 } 953 } 954 955 public void write(String indent, PrintWriter writer) { 956 writer.println("<?xml version='1.0' encoding='UTF-8'?>"); writer.println("<!-- Schema file written by PDE -->"); writer.println("<schema targetNamespace=\"" + fPluginID + "\">"); String indent2 = INDENT + INDENT; 960 String indent3 = indent2 + INDENT; 961 writer.println(indent + "<annotation>"); writer.println(indent2 + "<appInfo>"); writer.print(indent3 + "<meta.schema plugin=\"" + fPluginID + "\""); writer.print(" id=\"" + fPointID + "\""); writer.println(" name=\"" + getName() + "\"/>"); writer.println(indent2 + "</appInfo>"); writer.println(indent2 + "<documentation>"); writer.println(indent3 969 + getWritableDescription()); 970 writer.println(indent2 + "</documentation>"); writer.println(INDENT + "</annotation>"); writer.println(); 973 if (fIncludes != null) { 975 for (int i = 0; i < fIncludes.size(); i++) { 976 ISchemaInclude include = (ISchemaInclude) fIncludes.get(i); 977 include.write(INDENT, writer); 978 writer.println(); 979 } 980 } 981 for (int i = 0; i < fElements.size(); i++) { 983 ISchemaElement element = (ISchemaElement) fElements.elementAt(i); 984 element.write(INDENT, writer); 985 writer.println(); 986 } 987 for (int i = 0; i < fDocSections.size(); i++) { 989 IDocumentSection section = (IDocumentSection) fDocSections.elementAt(i); 990 section.write(INDENT, writer); 991 writer.println(); 992 } 993 writer.println("</schema>"); } 995 996 private String getWritableDescription() { 997 String lineDelimiter = System.getProperty("line.separator"); String description = PDEXMLHelper.getWritableString(getDescription()); 999 String platformDescription = description.replaceAll( 1000 "\\r\\n|\\r|\\n", lineDelimiter); 1002 return platformDescription; 1003 } 1004 1005 public boolean isDeperecated() { 1006 Iterator it = fElements.iterator(); 1007 while (it.hasNext()) { 1008 Object next = it.next(); 1009 if (next instanceof SchemaRootElement) 1010 return ((SchemaRootElement)next).isDeprecated(); 1011 } 1012 return false; 1013 } 1014 1015 public String getDeprecatedSuggestion() { 1016 Iterator it = fElements.iterator(); 1017 while (it.hasNext()) { 1018 Object next = it.next(); 1019 if (next instanceof SchemaRootElement) 1020 return ((SchemaRootElement)next).getDeprecatedSuggestion(); 1021 } 1022 return null; 1023 } 1024 1025} 1026 | Popular Tags |