1 11 12 package org.eclipse.pde.internal.ui.editor.contentassist; 13 14 import java.util.ArrayList ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.regex.Pattern ; 18 19 import org.eclipse.core.resources.IResource; 20 import org.eclipse.jdt.core.search.IJavaSearchConstants; 21 import org.eclipse.jface.text.BadLocationException; 22 import org.eclipse.jface.text.IDocument; 23 import org.eclipse.jface.text.ITextSelection; 24 import org.eclipse.jface.text.ITextViewer; 25 import org.eclipse.jface.text.contentassist.ContentAssistEvent; 26 import org.eclipse.jface.text.contentassist.ICompletionListener; 27 import org.eclipse.jface.text.contentassist.ICompletionProposal; 28 import org.eclipse.jface.text.contentassist.IContentAssistProcessor; 29 import org.eclipse.jface.viewers.ISelection; 30 import org.eclipse.pde.core.IBaseModel; 31 import org.eclipse.pde.core.IIdentifiable; 32 import org.eclipse.pde.core.plugin.IPluginBase; 33 import org.eclipse.pde.core.plugin.IPluginExtension; 34 import org.eclipse.pde.core.plugin.IPluginExtensionPoint; 35 import org.eclipse.pde.core.plugin.IPluginModelBase; 36 import org.eclipse.pde.core.plugin.IPluginObject; 37 import org.eclipse.pde.core.plugin.PluginRegistry; 38 import org.eclipse.pde.internal.core.ischema.IMetaAttribute; 39 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute; 40 import org.eclipse.pde.internal.core.ischema.ISchemaComplexType; 41 import org.eclipse.pde.internal.core.ischema.ISchemaCompositor; 42 import org.eclipse.pde.internal.core.ischema.ISchemaElement; 43 import org.eclipse.pde.internal.core.ischema.ISchemaObject; 44 import org.eclipse.pde.internal.core.ischema.ISchemaRestriction; 45 import org.eclipse.pde.internal.core.ischema.ISchemaSimpleType; 46 import org.eclipse.pde.internal.core.text.AbstractEditingModel; 47 import org.eclipse.pde.internal.core.text.IDocumentAttribute; 48 import org.eclipse.pde.internal.core.text.IDocumentNode; 49 import org.eclipse.pde.internal.core.text.IDocumentRange; 50 import org.eclipse.pde.internal.core.text.IDocumentTextNode; 51 import org.eclipse.pde.internal.core.text.IReconcilingParticipant; 52 import org.eclipse.pde.internal.core.text.plugin.PluginModelBase; 53 import org.eclipse.pde.internal.core.util.IdUtil; 54 import org.eclipse.pde.internal.ui.PDEPluginImages; 55 import org.eclipse.pde.internal.ui.PDEUIMessages; 56 import org.eclipse.pde.internal.ui.editor.PDEFormEditor; 57 import org.eclipse.pde.internal.ui.editor.PDESourcePage; 58 import org.eclipse.pde.internal.ui.editor.text.XMLUtil; 59 import org.eclipse.swt.graphics.Image; 60 import org.eclipse.ui.forms.editor.FormEditor; 61 62 public class XMLContentAssistProcessor extends TypePackageCompletionProcessor implements IContentAssistProcessor, ICompletionListener { 63 64 protected boolean fAssistSessionStarted; 65 66 68 protected static final int F_INFER_BY_OBJECT = -1; 69 70 protected static final int F_EXTENSION_POINT = 0; 71 72 protected static final int F_EXTENSION = 1; 73 74 protected static final int F_ELEMENT = 2; 75 76 protected static final int F_ATTRIBUTE = 3; 77 78 protected static final int F_CLOSE_TAG = 4; 79 80 protected static final int F_ATTRIBUTE_VALUE = 5; 81 82 protected static final int F_EXTENSION_ATTRIBUTE_POINT_VALUE = 6; 83 84 protected static final int F_EXTENSION_POINT_AND_VALUE = 7; 85 86 protected static final int F_TOTAL_TYPES = 8; 87 88 private static final int 90 F_NO_ASSIST = 0, 91 F_ADD_ATTRIB = 1, 92 F_ADD_CHILD = 2, 93 F_OPEN_TAG = 3; 94 95 private static final ArrayList F_V_BOOLS = new ArrayList (); 96 static { 97 F_V_BOOLS.add(new VirtualSchemaObject("true", null, F_ATTRIBUTE_VALUE)); F_V_BOOLS.add(new VirtualSchemaObject("false", null, F_ATTRIBUTE_VALUE)); } 100 101 private static final String F_STR_EXT_PT = "extension-point"; private static final String F_STR_EXT = "extension"; 104 private PDESourcePage fSourcePage; 105 private final Image[] fImages = new Image[F_TOTAL_TYPES]; 106 private IDocumentRange fRange; 108 private int fDocLen = -1; 109 110 111 private ArrayList fExternalExtPoints; 112 113 114 private ArrayList fInternalExtPoints; 115 116 117 private ArrayList fAllExtPoints; 118 119 public XMLContentAssistProcessor(PDESourcePage sourcePage) { 120 fSourcePage = sourcePage; 121 } 122 123 public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { 124 IDocument doc = viewer.getDocument(); 125 int docLen = doc.getLength(); 126 if (docLen == fDocLen) 127 return null; 129 fDocLen = docLen; 130 IBaseModel model = getModel(); 131 if (model instanceof AbstractEditingModel 132 && fSourcePage.isDirty() 133 && ((AbstractEditingModel)model).isStale() 134 && fRange == null) { 135 ((AbstractEditingModel)model).reconciled(doc); 136 } else if (fAssistSessionStarted) { 137 ((AbstractEditingModel)model).reconciled(doc); 140 fAssistSessionStarted = false; 141 } 142 143 if (fRange == null) { 144 assignRange(offset); 145 } else { 146 boolean resetAndReconcile = false; 150 if (!(fRange instanceof IDocumentAttribute)) 151 resetAndReconcile = true; 153 154 if (resetAndReconcile) { 155 fRange = null; 156 if (model instanceof IReconcilingParticipant) 157 ((IReconcilingParticipant)model).reconciled(doc); 158 } 159 } 160 XMLContentAssistText caText = XMLContentAssistText.parse(offset, doc); 162 163 if (caText != null) { 164 return computeCATextProposal(doc, offset, caText); 165 } else if (fRange instanceof IDocumentAttribute) { 166 return computeCompletionProposal((IDocumentAttribute)fRange, offset, doc); 167 } else if (fRange instanceof IDocumentNode) { 168 return computeCompletionProposal((IDocumentNode)fRange, offset, doc); 169 } else if (fRange instanceof IDocumentTextNode) { 170 return null; 171 } else if (model instanceof PluginModelBase) { 172 return computeBrokenModelProposal(((PluginModelBase)model).getLastErrorNode(), offset, doc); 174 } 175 return null; 176 } 177 178 184 protected ICompletionProposal[] debugPrintProposals(ICompletionProposal[] proposals, String id, boolean print) { 185 if (proposals == null) { 186 System.out.println("[0] " + id); return proposals; 188 } 189 System.out.println("[" + proposals.length + "] " + id); if (print == false) { 191 return proposals; 192 } 193 for (int i = 0; i < proposals.length; i++) { 194 System.out.println(proposals[i].getDisplayString()); 195 } 196 return proposals; 197 } 198 199 private void assignRange(int offset) { 200 fRange = fSourcePage.getRangeElement(offset, true); 201 if (fRange == null) 202 return; 203 if (fRange instanceof IDocumentAttribute) { 206 if (((IDocumentAttribute)fRange).getNameOffset() == offset) 207 fRange = ((IDocumentAttribute)fRange).getEnclosingElement(); 208 } else if (fRange instanceof IDocumentNode) { 209 if (((IDocumentNode)fRange).getOffset() == offset) 210 fRange = ((IDocumentNode)fRange).getParentNode(); 211 } else if (fRange instanceof IDocumentTextNode) { 212 if (((IDocumentTextNode)fRange).getOffset() == offset) 213 fRange = ((IDocumentTextNode)fRange).getEnclosingElement(); 214 } 215 } 216 217 private ICompletionProposal[] computeCATextProposal(IDocument doc, 218 int offset, XMLContentAssistText caText) { 219 fRange = fSourcePage.getRangeElement(offset, true); 220 if ((fRange != null) && 221 (fRange instanceof IDocumentTextNode)) { 222 fRange = ((IDocumentTextNode)fRange).getEnclosingElement(); 225 } 226 if ((fRange != null) && 227 (fRange instanceof IDocumentNode)) { 228 return computeAddChildProposal((IDocumentNode)fRange, 229 caText.getStartOffset(), doc, caText.getText()); 230 } 231 return null; 232 } 233 234 private ICompletionProposal[] computeCompletionProposal(IDocumentAttribute attr, int offset, IDocument doc) { 235 if (offset < attr.getValueOffset()) 236 return null; 237 int[] offests = new int[] {offset, offset, offset}; 238 String [] guess = guessContentRequest(offests, doc, false); 239 if (guess == null) 240 return null; 241 String attrValue = guess[2]; 244 245 IPluginObject obj = XMLUtil.getTopLevelParent((IDocumentNode)attr); 246 if (obj instanceof IPluginExtension) { 247 if (attr.getAttributeName().equals(IPluginExtension.P_POINT) && 248 offset >= attr.getValueOffset()) { 249 return computeExtPointAttrProposals(attr, offset, attrValue); 250 } 251 ISchemaAttribute sAttr = XMLUtil.getSchemaAttribute(attr, ((IPluginExtension)obj).getPoint()); 252 if (sAttr == null) 253 return null; 254 255 if (sAttr.getKind() == IMetaAttribute.JAVA) { 256 IResource resource = obj.getModel().getUnderlyingResource(); 257 if (resource == null) 258 return null; 259 ArrayList list = new ArrayList (); 261 ICompletionProposal[] proposals = null; 262 263 generateTypePackageProposals(attrValue, resource.getProject(), 264 list, offset - attrValue.length(), IJavaSearchConstants.CLASS_AND_INTERFACE); 265 266 if ((list != null) && (list.size() != 0)) { 267 proposals = (ICompletionProposal[]) list.toArray(new ICompletionProposal[list.size()]); 270 sortCompletions(proposals); 271 return proposals; 272 } 273 return null; 274 } else if (sAttr.getKind() == IMetaAttribute.RESOURCE) { 275 277 } else { if (sAttr.getType() == null) 279 return null; 280 ISchemaRestriction sRestr = (sAttr.getType()).getRestriction(); 281 ArrayList objs = new ArrayList (); 282 if (sRestr == null) { 283 ISchemaSimpleType type = sAttr.getType(); 284 if (type != null && type.getName().equals("boolean")) objs = F_V_BOOLS; 286 } else { 287 Object [] restrictions = sRestr.getChildren(); 288 for (int i = 0; i < restrictions.length; i++) 289 if (restrictions[i] instanceof ISchemaObject) 290 objs.add(new VirtualSchemaObject(((ISchemaObject)restrictions[i]).getName(), null, F_ATTRIBUTE_VALUE)); 291 } 292 return computeAttributeProposal(attr, offset, attrValue, objs); 293 } 294 } else if (obj instanceof IPluginExtensionPoint) { 295 if (attr.getAttributeValue().equals(IPluginExtensionPoint.P_SCHEMA)) { 296 298 } 299 } 300 return null; 301 } 302 303 309 private ICompletionProposal[] computeExtPointAttrProposals( 310 IDocumentAttribute attribute, int offset, String currentAttributeValue) { 311 ArrayList allExtensionPoints = 313 getAllExtensionPoints(F_EXTENSION_ATTRIBUTE_POINT_VALUE); 314 if ((allExtensionPoints == null) || 316 (allExtensionPoints.size() == 0)) { 317 return null; 318 } 319 if ((currentAttributeValue == null) || 322 (currentAttributeValue.length() == 0)) { 323 return convertListToProposal(allExtensionPoints, (IDocumentRange)attribute, offset); 324 } 325 ArrayList filteredProposalList = new ArrayList (); 327 filterExtPointAttrProposals(filteredProposalList, allExtensionPoints, currentAttributeValue); 330 return convertListToProposal(filteredProposalList, (IDocumentRange)attribute, offset); 332 } 333 334 340 private ICompletionProposal[] computeRootNodeProposals( 341 IDocumentNode node, int offset, String filter) { 342 ArrayList filteredProposalList = new ArrayList (); 344 addToList( 346 filteredProposalList, 347 filter, 348 new VirtualSchemaObject(F_STR_EXT, 349 PDEUIMessages.XMLContentAssistProcessor_extensions, 350 F_EXTENSION)); 351 addToList( 353 filteredProposalList, 354 filter, 355 new VirtualSchemaObject(F_STR_EXT_PT, 356 PDEUIMessages.XMLContentAssistProcessor_extensionPoints, 357 F_EXTENSION_POINT)); 358 ArrayList allExtensionPoints = 360 getAllExtensionPoints(F_EXTENSION_POINT_AND_VALUE); 361 if ((allExtensionPoints == null) || 363 (allExtensionPoints.size() == 0)) { 364 return convertListToProposal(filteredProposalList, node, offset); 366 } 367 if ((filter == null) || 371 (filter.length() == 0)) { 372 filteredProposalList.addAll(allExtensionPoints); 373 return convertListToProposal(filteredProposalList, node, offset); 374 } 375 filterExtPointAttrProposals(filteredProposalList, allExtensionPoints, filter); 377 return convertListToProposal(filteredProposalList, node, offset); 379 } 380 381 386 private void filterExtPointAttrProposals( 387 ArrayList filteredProposalList, ArrayList allExtensionPoints, 388 String filter) { 389 String patternString = "(?i)" + filter; Pattern pattern = Pattern.compile(patternString); 394 Iterator iterator = allExtensionPoints.iterator(); 397 while (iterator.hasNext()) { 398 ISchemaObject schemaObject = (ISchemaObject)iterator.next(); 400 if (schemaObject == null) { 402 continue; 403 } 404 String name = schemaObject.getName(); 406 if (pattern.matcher(name).find()) { 409 filteredProposalList.add(schemaObject); 410 } 411 } 412 } 413 414 private ICompletionProposal[] computeAttributeProposal(IDocumentAttribute attr, int offset, String currValue, ArrayList validValues) { 415 if (validValues == null) 416 return null; 417 ArrayList list = new ArrayList (); 418 for (int i = 0; i < validValues.size(); i++) 419 addToList(list, currValue, (ISchemaObject)validValues.get(i)); 420 421 return convertListToProposal(list, (IDocumentRange)attr, offset); 422 } 423 424 private ICompletionProposal[] computeCompletionProposal(IDocumentNode node, int offset, IDocument doc) { 425 int prop_type = determineAssistType(node, doc, offset); 426 switch (prop_type) { 427 case F_ADD_ATTRIB: 428 return computeAddAttributeProposal(F_INFER_BY_OBJECT, node, offset, doc, null, node.getXMLTagName()); 429 case F_OPEN_TAG: 430 return computeOpenTagProposal(node, offset, doc); 431 case F_ADD_CHILD: 432 return computeAddChildProposal(node, offset, doc, null); 433 } 434 return null; 435 } 436 437 private int determineAssistType(IDocumentNode node, IDocument doc, int offset) { 438 int len = node.getLength(); 439 int off = node.getOffset(); 440 if (len == -1 || off == -1) 441 return F_NO_ASSIST; 442 443 offset = offset - off; if (offset > node.getXMLTagName().length() + 1) { 445 try { 446 String eleValue = doc.get(off, len); 447 int ind = eleValue.indexOf('>'); 448 if (ind > 0 && eleValue.charAt(ind - 1) == '/') 449 ind -= 1; 450 if (offset <= ind) { 451 if (canInsertAttrib(eleValue, offset)) 452 return F_ADD_ATTRIB; 453 return F_NO_ASSIST; 454 } 455 ind = eleValue.lastIndexOf('<'); 456 if (ind == 0 && offset == len - 1) 457 return F_OPEN_TAG; if (ind + 1 < len && eleValue.charAt(ind + 1) == '/' && offset <= ind) 459 return F_ADD_CHILD; 460 } catch (BadLocationException e) { 461 } 462 } 463 return F_NO_ASSIST; 464 } 465 466 private boolean canInsertAttrib(String eleValue, int offset) { 467 char c = eleValue.charAt(offset); 470 return offset - 1 >= 0 && Character.isWhitespace(eleValue.charAt(offset - 1)) && 471 (Character.isWhitespace(c) || c == '/' || c == '>'); 472 } 473 474 private ICompletionProposal[] computeAddChildProposal(IDocumentNode node, int offset, IDocument doc, String filter) { 475 ArrayList propList = new ArrayList (); 476 if (node instanceof IPluginBase) { 477 return computeRootNodeProposals(node, offset, filter); 478 } else if (node instanceof IPluginExtensionPoint) { 479 return null; 480 } else { 481 IPluginObject obj = XMLUtil.getTopLevelParent(node); 482 if (obj instanceof IPluginExtension) { 483 ISchemaElement sElement = XMLUtil.getSchemaElement(node, 484 ((IPluginExtension)obj).getPoint()); 485 if ((sElement != null) && 486 (sElement.getType() instanceof ISchemaComplexType)) { 487 HashSet elementSet = XMLElementProposalComputer 491 .computeElementProposal(sElement, node); 492 Iterator iterator = elementSet.iterator(); 494 while (iterator.hasNext()) { 495 addToList(propList, filter, (ISchemaObject)iterator.next()); 496 } 497 } else { 498 return null; 499 } 500 } 501 } 502 return convertListToProposal(propList, node, offset); 503 } 504 505 private ICompletionProposal[] computeOpenTagProposal(IDocumentNode node, int offset, IDocument doc) { 506 IPluginObject obj = XMLUtil.getTopLevelParent(node); 507 if (obj instanceof IPluginExtension) { 508 ISchemaElement sElem = XMLUtil.getSchemaElement(node, ((IPluginExtension)obj).getPoint()); 509 if (sElem == null) 510 return null; 511 ISchemaCompositor comp = ((ISchemaComplexType)sElem.getType()).getCompositor(); 512 if (comp != null) 513 return new ICompletionProposal[] { new XMLCompletionProposal(node, null, offset, this) }; 514 } 515 return null; 516 } 517 518 private ICompletionProposal[] computeAddAttributeProposal(int type, IDocumentNode node, int offset, IDocument doc, String filter, String tag) { 519 String nodeName = tag; 520 if (nodeName == null && node != null) 521 nodeName = node.getXMLTagName(); 522 if (type == F_EXTENSION || node instanceof IPluginExtension) { 523 ISchemaElement sElem = XMLUtil.getSchemaElement(node, node != null ? 524 ((IPluginExtension)node).getPoint() : null); 525 ISchemaObject[] sAttrs = sElem != null ? 526 sElem.getAttributes() : 527 new ISchemaObject[] { 528 new VirtualSchemaObject(IIdentifiable.P_ID, PDEUIMessages.XMLContentAssistProcessor_extId, F_ATTRIBUTE), 529 new VirtualSchemaObject(IPluginObject.P_NAME, PDEUIMessages.XMLContentAssistProcessor_extName, F_ATTRIBUTE), 530 new VirtualSchemaObject(IPluginExtension.P_POINT, PDEUIMessages.XMLContentAssistProcessor_extPoint, F_ATTRIBUTE) 531 }; 532 return computeAttributeProposals(sAttrs, node, offset, filter, nodeName); 533 } else if (type == F_EXTENSION_POINT || node instanceof IPluginExtensionPoint) { 534 ISchemaObject[] sAttrs = new ISchemaObject[] { 535 new VirtualSchemaObject(IIdentifiable.P_ID, PDEUIMessages.XMLContentAssistProcessor_extPointId, F_ATTRIBUTE), 536 new VirtualSchemaObject(IPluginObject.P_NAME, PDEUIMessages.XMLContentAssistProcessor_extPointName, F_ATTRIBUTE), 537 new VirtualSchemaObject(IPluginExtensionPoint.P_SCHEMA, PDEUIMessages.XMLContentAssistProcessor_schemaLocation, F_ATTRIBUTE) 538 }; 539 return computeAttributeProposals(sAttrs, node, offset, filter, nodeName); 540 } else { 541 IPluginObject obj = XMLUtil.getTopLevelParent(node); 542 if (obj instanceof IPluginExtension) { 543 ISchemaElement sElem = XMLUtil.getSchemaElement(node, node != null ? 544 ((IPluginExtension)obj).getPoint() : null); 545 ISchemaObject[] sAttrs = sElem != null ? sElem.getAttributes() : null; 546 return computeAttributeProposals(sAttrs, node, offset, filter, nodeName); 547 } 548 } 549 return null; 550 } 551 552 private void addToList(ArrayList list, String filter, ISchemaObject object) { 553 if (object == null) 554 return; 555 if (filter == null || filter.length() == 0) 556 list.add(object); 557 else { 558 String name = object.getName(); 559 if (filter.regionMatches(true, 0, name, 0, filter.length())) 560 list.add(object); 561 } 562 } 563 564 private ICompletionProposal[] computeBrokenModelProposal(IDocumentNode parent, int offset, IDocument doc) { 565 if (parent == null) 566 return null; 567 568 int[] offArr = new int[] {offset, offset, offset}; 569 String [] guess = guessContentRequest(offArr, doc, true); 570 if (guess == null) 571 return null; 572 573 int elRepOffset = offArr[0]; 574 int atRepOffset = offArr[1]; 575 int atValRepOffest = offArr[2]; 576 String element = guess[0]; 577 String attr = guess[1]; 578 String attVal = guess[2]; 579 580 IPluginObject obj = XMLUtil.getTopLevelParent(parent); 581 if (obj instanceof IPluginExtension) { 582 String point = ((IPluginExtension)obj).getPoint(); 583 if (attr == null) 584 return computeAddChildProposal(parent, elRepOffset, doc, element); 586 587 ISchemaElement sEle = XMLUtil.getSchemaElement(parent, point); 588 if (sEle == null) 589 return null; 590 sEle = sEle.getSchema().findElement(element); 591 if (sEle == null) 592 return null; 593 594 if (attr.indexOf('=') != -1) 595 return computeBrokenModelAttributeContentProposal(parent, atValRepOffest, element, attr, attVal); 597 598 return computeAttributeProposals(sEle.getAttributes(), null, atRepOffset, attr, element); 600 } else if (parent instanceof IPluginBase) { 601 if (attr == null) 602 return computeAddChildProposal(parent, elRepOffset, doc, element); 603 if (element.equalsIgnoreCase(F_STR_EXT)) 604 return computeAddAttributeProposal(F_EXTENSION, null, atRepOffset, doc, attr, F_STR_EXT); 605 if (element.equalsIgnoreCase(F_STR_EXT_PT)) 606 return computeAddAttributeProposal(F_EXTENSION_POINT, null, atRepOffset, doc, attr, F_STR_EXT_PT); 607 } 608 return null; 609 } 610 611 private ICompletionProposal[] computeBrokenModelAttributeContentProposal(IDocumentNode parent, int offset, String element, String attr, String filter) { 612 return null; 616 } 617 618 private String [] guessContentRequest(int[] offset, IDocument doc, boolean brokenModel) { 619 StringBuffer nodeBuffer = new StringBuffer (); 620 StringBuffer attrBuffer = new StringBuffer (); 621 StringBuffer attrValBuffer = new StringBuffer (); 622 String node = null; 623 String attr = null; 624 String attVal = null; 625 int quoteCount = 0; 626 try { 627 while (--offset[0] >= 0) { 628 char c = doc.getChar(offset[0]); 629 if (c == '"') { 630 quoteCount += 1; 631 nodeBuffer.setLength(0); 632 attrBuffer.setLength(0); 633 if (attVal != null) continue; 635 offset[2] = offset[0]; 636 attVal = attrValBuffer.toString(); 637 } else if (Character.isWhitespace(c)) { 638 nodeBuffer.setLength(0); 639 if (attr == null) { 640 offset[1] = offset[0]; 641 int attBuffLen = attrBuffer.length(); 642 if (attBuffLen > 0 && attrBuffer.charAt(attBuffLen - 1) == '=') 643 attrBuffer.setLength(attBuffLen - 1); 644 attr = attrBuffer.toString(); 645 } 646 } else if (c == '<') { 647 node = nodeBuffer.toString(); 648 break; 649 } else if (c == '>') { 650 return null; 652 } else { 653 attrValBuffer.insert(0, c); 654 attrBuffer.insert(0, c); 655 nodeBuffer.insert(0, c); 656 } 657 } 658 } catch (BadLocationException e) {} 659 if (node == null) 660 return null; 661 662 if (quoteCount % 2 == 0) 663 attVal = null; 664 else if (brokenModel) 665 return null; 667 return new String [] {node, attr, attVal}; 668 } 669 670 protected IBaseModel getModel() 671 { return fSourcePage.getInputContext().getModel(); } 672 protected ITextSelection getCurrentSelection() { 673 ISelection sel = fSourcePage.getSelectionProvider().getSelection(); 674 if (sel instanceof ITextSelection) 675 return (ITextSelection)sel; 676 return null; 677 } 678 protected void flushDocument() { 679 fSourcePage.getInputContext().flushEditorInput(); 680 } 681 682 private ICompletionProposal[] computeAttributeProposals(ISchemaObject[] sAttrs, IDocumentNode node, int offset, String filter, String parentName) { 683 if (sAttrs == null || sAttrs.length == 0) 684 return null; 685 IDocumentAttribute[] attrs = node != null ? node.getNodeAttributes() : new IDocumentAttribute[0]; 686 687 ArrayList list = new ArrayList (); 688 for (int i = 0; i < sAttrs.length; i++) { 689 int k; for (k = 0; k < attrs.length; k++) 691 if (attrs[k].getAttributeName().equals(sAttrs[i].getName())) 692 break; 693 if (k == attrs.length) 694 addToList(list, filter, sAttrs[i]); 695 } 696 if (filter != null && filter.length() == 0) 697 list.add(0, new VirtualSchemaObject(parentName, null, F_CLOSE_TAG)); 698 return convertListToProposal(list, node, offset); 699 } 700 701 private ICompletionProposal[] convertListToProposal(ArrayList list, IDocumentRange range, int offset) { 702 ICompletionProposal[] proposals = new ICompletionProposal[list.size()]; 703 if (proposals.length == 0) 704 return null; 705 for (int i = 0; i < proposals.length; i++) 706 proposals[i] = new XMLCompletionProposal(range, (ISchemaObject)list.get(i), offset, this); 707 return proposals; 708 } 709 710 public void assistSessionEnded(ContentAssistEvent event) { 711 fRange = null; 712 713 fAllExtPoints = null; 715 fInternalExtPoints = null; 720 721 fDocLen = -1; 722 } 723 724 public void assistSessionStarted(ContentAssistEvent event) { 725 fAssistSessionStarted = true; 726 } 727 728 public void selectionChanged(ICompletionProposal proposal, boolean smartToggle) { 729 } 730 731 735 private ArrayList getAllExtensionPoints(int vSchemaType) { 736 if (fAllExtPoints != null) { 738 return fAllExtPoints; 739 } 740 IPluginModelBase model = getPluginModelBase(); 742 fAllExtPoints = 755 (ArrayList )getExternalExtensionPoints(model, vSchemaType).clone(); 756 fAllExtPoints.addAll(getInternalExtensionPoints(model, vSchemaType)); 758 759 return fAllExtPoints; 760 } 761 762 766 private ArrayList getExternalExtensionPoints(IPluginModelBase model, 767 int vSchemaType) { 768 if (fExternalExtPoints != null) { 770 updateExternalExtPointTypes(vSchemaType); 771 return fExternalExtPoints; 772 } 773 fExternalExtPoints = new ArrayList (); 775 IPluginModelBase[] plugins = PluginRegistry.getActiveModels(); 777 for (int i = 0; i < plugins.length; i++) { 779 if (plugins[i].getPluginBase().getId().equals( 784 model.getPluginBase().getId())) { 785 continue; 787 } 788 IPluginExtensionPoint[] points = 790 plugins[i].getPluginBase().getExtensionPoints(); 791 for (int j = 0; j < points.length; j++) { 793 VirtualSchemaObject vObject = new VirtualSchemaObject( 794 IdUtil.getFullId(points[j], model), 795 points[j], 796 vSchemaType); 797 fExternalExtPoints.add(vObject); 799 } 800 } 801 return fExternalExtPoints; 802 } 803 804 813 private void updateExternalExtPointTypes(int newVType) { 814 if (fExternalExtPoints.size() == 0) { 816 return; 817 } 818 VirtualSchemaObject vObject = 820 (VirtualSchemaObject)fExternalExtPoints.get(0); 821 if (vObject.getVType() == newVType) { 825 return; 826 } 827 Iterator iterator = fExternalExtPoints.iterator(); 829 while (iterator.hasNext()) { 830 ((VirtualSchemaObject)iterator.next()).setVType(newVType); 831 } 832 } 833 834 838 private ArrayList getInternalExtensionPoints(IPluginModelBase model, 839 int vSchemaType) { 840 if (fInternalExtPoints != null) { 842 return fInternalExtPoints; 844 } 845 fInternalExtPoints = new ArrayList (); 846 IPluginExtensionPoint[] points = 848 model.getPluginBase().getExtensionPoints(); 849 for (int j = 0; j < points.length; j++) { 851 VirtualSchemaObject vObject = new VirtualSchemaObject( 852 IdUtil.getFullId(points[j], model), 853 points[j], 854 vSchemaType); 855 fInternalExtPoints.add(vObject); 857 } 858 return fInternalExtPoints; 859 } 860 861 867 private IPluginModelBase getPluginModelBase() { 868 FormEditor formEditor = fSourcePage.getEditor(); 869 if ((formEditor instanceof PDEFormEditor) == false) { 870 return null; 871 } 872 IBaseModel bModel = ((PDEFormEditor)formEditor).getAggregateModel(); 873 if ((bModel instanceof IPluginModelBase) == false) { 874 return null; 875 } 876 return (IPluginModelBase)bModel; 877 } 878 879 public Image getImage(int type) { 880 if (fImages[type] == null) { 881 switch(type) { 882 case F_EXTENSION_POINT: 883 case F_EXTENSION_ATTRIBUTE_POINT_VALUE: 884 return fImages[type] = PDEPluginImages.DESC_EXT_POINT_OBJ.createImage(); 885 case F_EXTENSION_POINT_AND_VALUE: 886 case F_EXTENSION: 887 return fImages[type] = PDEPluginImages.DESC_EXTENSION_OBJ.createImage(); 888 case F_ELEMENT: 889 case F_CLOSE_TAG: 890 return fImages[type] = PDEPluginImages.DESC_XML_ELEMENT_OBJ.createImage(); 891 case F_ATTRIBUTE: 892 case F_ATTRIBUTE_VALUE: 893 return fImages[type] = PDEPluginImages.DESC_ATT_URI_OBJ.createImage(); 894 } 895 } 896 return fImages[type]; 897 } 898 899 public void dispose() { 900 for (int i = 0; i < fImages.length; i++) 901 if (fImages[i] != null && !fImages[i].isDisposed()) 902 fImages[i].dispose(); 903 } 904 905 908 public PDESourcePage getSourcePage() { 909 return fSourcePage; 910 } 911 912 } 913 | Popular Tags |