1 11 package org.eclipse.jdt.internal.core; 12 13 import java.io.BufferedInputStream ; 14 import java.io.FileNotFoundException ; 15 import java.io.IOException ; 16 import java.io.InputStream ; 17 import java.io.PrintWriter ; 18 import java.io.StringWriter ; 19 import java.net.JarURLConnection ; 20 import java.net.MalformedURLException ; 21 import java.net.URL ; 22 import java.net.URLConnection ; 23 import java.util.ArrayList ; 24 import java.util.HashMap ; 25 26 import org.eclipse.core.resources.IResource; 27 import org.eclipse.core.runtime.*; 28 import org.eclipse.core.runtime.jobs.ISchedulingRule; 29 import org.eclipse.jdt.core.*; 30 import org.eclipse.jdt.core.dom.ASTNode; 31 import org.eclipse.jdt.core.dom.CompilationUnit; 32 import org.eclipse.jdt.internal.compiler.lookup.Binding; 33 import org.eclipse.jdt.internal.core.util.MementoTokenizer; 34 import org.eclipse.jdt.internal.core.util.Util; 35 36 41 public abstract class JavaElement extends PlatformObject implements IJavaElement { 42 44 private static final byte[] CLOSING_DOUBLE_QUOTE = new byte[] { 34 }; 45 private static final byte[] CHARSET = new byte[] {99, 104, 97, 114, 115, 101, 116, 61 }; 46 private static final byte[] CONTENT_TYPE = new byte[] { 34, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 34 }; 47 private static final byte[] CONTENT = new byte[] { 99, 111, 110, 116, 101, 110, 116, 61, 34 }; 48 public static final char JEM_ESCAPE = '\\'; 49 public static final char JEM_JAVAPROJECT = '='; 50 public static final char JEM_PACKAGEFRAGMENTROOT = '/'; 51 public static final char JEM_PACKAGEFRAGMENT = '<'; 52 public static final char JEM_FIELD = '^'; 53 public static final char JEM_METHOD = '~'; 54 public static final char JEM_INITIALIZER = '|'; 55 public static final char JEM_COMPILATIONUNIT = '{'; 56 public static final char JEM_CLASSFILE = '('; 57 public static final char JEM_TYPE = '['; 58 public static final char JEM_PACKAGEDECLARATION = '%'; 59 public static final char JEM_IMPORTDECLARATION = '#'; 60 public static final char JEM_COUNT = '!'; 61 public static final char JEM_LOCALVARIABLE = '@'; 62 public static final char JEM_TYPE_PARAMETER = ']'; 63 64 68 protected JavaElement parent; 69 70 protected static final JavaElement[] NO_ELEMENTS = new JavaElement[0]; 71 protected static final Object NO_INFO = new Object (); 72 73 83 protected JavaElement(JavaElement parent) throws IllegalArgumentException { 84 this.parent = parent; 85 } 86 89 public void close() throws JavaModelException { 90 JavaModelManager.getJavaModelManager().removeInfoAndChildren(this); 91 } 92 95 protected abstract void closing(Object info) throws JavaModelException; 96 99 protected abstract Object createElementInfo(); 100 111 public boolean equals(Object o) { 112 113 if (this == o) return true; 114 115 if (this.parent == null) return super.equals(o); 117 118 JavaElement other = (JavaElement) o; 120 return getElementName().equals(other.getElementName()) && 121 this.parent.equals(other.parent); 122 } 123 protected void escapeMementoName(StringBuffer buffer, String mementoName) { 124 for (int i = 0, length = mementoName.length(); i < length; i++) { 125 char character = mementoName.charAt(i); 126 switch (character) { 127 case JEM_ESCAPE: 128 case JEM_COUNT: 129 case JEM_JAVAPROJECT: 130 case JEM_PACKAGEFRAGMENTROOT: 131 case JEM_PACKAGEFRAGMENT: 132 case JEM_FIELD: 133 case JEM_METHOD: 134 case JEM_INITIALIZER: 135 case JEM_COMPILATIONUNIT: 136 case JEM_CLASSFILE: 137 case JEM_TYPE: 138 case JEM_PACKAGEDECLARATION: 139 case JEM_IMPORTDECLARATION: 140 case JEM_LOCALVARIABLE: 141 case JEM_TYPE_PARAMETER: 142 buffer.append(JEM_ESCAPE); 143 } 144 buffer.append(character); 145 } 146 } 147 150 public boolean exists() { 151 152 try { 153 getElementInfo(); 154 return true; 155 } catch (JavaModelException e) { 156 } 158 return false; 159 } 160 161 165 public ASTNode findNode(CompilationUnit ast) { 166 return null; } 168 172 protected abstract void generateInfos(Object info, HashMap newElements, IProgressMonitor pm) throws JavaModelException; 173 174 177 public IJavaElement getAncestor(int ancestorType) { 178 179 IJavaElement element = this; 180 while (element != null) { 181 if (element.getElementType() == ancestorType) return element; 182 element= element.getParent(); 183 } 184 return null; 185 } 186 189 public IJavaElement[] getChildren() throws JavaModelException { 190 Object elementInfo = getElementInfo(); 191 if (elementInfo instanceof JavaElementInfo) { 192 return ((JavaElementInfo)elementInfo).getChildren(); 193 } else { 194 return NO_ELEMENTS; 195 } 196 } 197 203 public ArrayList getChildrenOfType(int type) throws JavaModelException { 204 IJavaElement[] children = getChildren(); 205 int size = children.length; 206 ArrayList list = new ArrayList (size); 207 for (int i = 0; i < size; ++i) { 208 JavaElement elt = (JavaElement)children[i]; 209 if (elt.getElementType() == type) { 210 list.add(elt); 211 } 212 } 213 return list; 214 } 215 218 public IClassFile getClassFile() { 219 return null; 220 } 221 224 public ICompilationUnit getCompilationUnit() { 225 return null; 226 } 227 234 public Object getElementInfo() throws JavaModelException { 235 return getElementInfo(null); 236 } 237 244 public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException { 245 246 JavaModelManager manager = JavaModelManager.getJavaModelManager(); 247 Object info = manager.getInfo(this); 248 if (info != null) return info; 249 return openWhenClosed(createElementInfo(), monitor); 250 } 251 254 public String getElementName() { 255 return ""; } 257 262 public abstract IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner); 263 267 public IJavaElement getHandleFromMemento(MementoTokenizer memento, WorkingCopyOwner owner) { 268 if (!memento.hasMoreTokens()) return this; 269 String token = memento.nextToken(); 270 return getHandleFromMemento(token, memento, owner); 271 } 272 275 public String getHandleIdentifier() { 276 return getHandleMemento(); 277 } 278 281 public String getHandleMemento(){ 282 StringBuffer buff = new StringBuffer (); 283 getHandleMemento(buff); 284 return buff.toString(); 285 } 286 protected void getHandleMemento(StringBuffer buff) { 287 ((JavaElement)getParent()).getHandleMemento(buff); 288 buff.append(getHandleMementoDelimiter()); 289 escapeMementoName(buff, getElementName()); 290 } 291 295 protected abstract char getHandleMementoDelimiter(); 296 299 public IJavaModel getJavaModel() { 300 IJavaElement current = this; 301 do { 302 if (current instanceof IJavaModel) return (IJavaModel) current; 303 } while ((current = current.getParent()) != null); 304 return null; 305 } 306 307 310 public IJavaProject getJavaProject() { 311 IJavaElement current = this; 312 do { 313 if (current instanceof IJavaProject) return (IJavaProject) current; 314 } while ((current = current.getParent()) != null); 315 return null; 316 } 317 320 public IOpenable getOpenable() { 321 return this.getOpenableParent(); 322 } 323 329 public IOpenable getOpenableParent() { 330 return (IOpenable)this.parent; 331 } 332 335 public IJavaElement getParent() { 336 return this.parent; 337 } 338 341 public IJavaElement getPrimaryElement() { 342 return getPrimaryElement(true); 343 } 344 348 public IJavaElement getPrimaryElement(boolean checkOwner) { 349 return this; 350 } 351 358 protected IJavaElement getSourceElementAt(int position) throws JavaModelException { 359 if (this instanceof ISourceReference) { 360 IJavaElement[] children = getChildren(); 361 for (int i = children.length-1; i >= 0; i--) { 362 IJavaElement aChild = children[i]; 363 if (aChild instanceof SourceRefElement) { 364 SourceRefElement child = (SourceRefElement) children[i]; 365 ISourceRange range = child.getSourceRange(); 366 int start = range.getOffset(); 367 int end = start + range.getLength(); 368 if (start <= position && position <= end) { 369 if (child instanceof IField) { 370 int declarationStart = start; 372 SourceRefElement candidate = null; 373 do { 374 range = ((IField)child).getNameRange(); 376 if (position <= range.getOffset() + range.getLength()) { 377 candidate = child; 378 } else { 379 return candidate == null ? child.getSourceElementAt(position) : candidate.getSourceElementAt(position); 380 } 381 child = --i>=0 ? (SourceRefElement) children[i] : null; 382 } while (child != null && child.getSourceRange().getOffset() == declarationStart); 383 return candidate.getSourceElementAt(position); 385 } else if (child instanceof IParent) { 386 return child.getSourceElementAt(position); 387 } else { 388 return child; 389 } 390 } 391 } 392 } 393 } else { 394 Assert.isTrue(false); 396 } 397 return this; 398 } 399 404 public SourceMapper getSourceMapper() { 405 return ((JavaElement)getParent()).getSourceMapper(); 406 } 407 410 public ISchedulingRule getSchedulingRule() { 411 IResource resource = getResource(); 412 if (resource == null) { 413 class NoResourceSchedulingRule implements ISchedulingRule { 414 public IPath path; 415 public NoResourceSchedulingRule(IPath path) { 416 this.path = path; 417 } 418 public boolean contains(ISchedulingRule rule) { 419 if (rule instanceof NoResourceSchedulingRule) { 420 return this.path.isPrefixOf(((NoResourceSchedulingRule)rule).path); 421 } else { 422 return false; 423 } 424 } 425 public boolean isConflicting(ISchedulingRule rule) { 426 if (rule instanceof NoResourceSchedulingRule) { 427 IPath otherPath = ((NoResourceSchedulingRule)rule).path; 428 return this.path.isPrefixOf(otherPath) || otherPath.isPrefixOf(this.path); 429 } else { 430 return false; 431 } 432 } 433 } 434 return new NoResourceSchedulingRule(getPath()); 435 } else { 436 return resource; 437 } 438 } 439 442 public boolean hasChildren() throws JavaModelException { 443 Object elementInfo = JavaModelManager.getJavaModelManager().getInfo(this); 446 if (elementInfo instanceof JavaElementInfo) { 447 return ((JavaElementInfo)elementInfo).getChildren().length > 0; 448 } else { 449 return true; 450 } 451 } 452 453 459 public int hashCode() { 460 if (this.parent == null) return super.hashCode(); 461 return Util.combineHashCodes(getElementName().hashCode(), this.parent.hashCode()); 462 } 463 467 public boolean isAncestorOf(IJavaElement e) { 468 IJavaElement parentElement= e.getParent(); 469 while (parentElement != null && !parentElement.equals(this)) { 470 parentElement= parentElement.getParent(); 471 } 472 return parentElement != null; 473 } 474 475 478 public boolean isReadOnly() { 479 return false; 480 } 481 484 public JavaModelException newNotPresentException() { 485 return new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this)); 486 } 487 490 public JavaModelException newJavaModelException(IStatus status) { 491 if (status instanceof IJavaModelStatus) 492 return new JavaModelException((IJavaModelStatus) status); 493 else 494 return new JavaModelException(new JavaModelStatus(status.getSeverity(), status.getCode(), status.getMessage())); 495 } 496 500 protected Object openWhenClosed(Object info, IProgressMonitor monitor) throws JavaModelException { 501 JavaModelManager manager = JavaModelManager.getJavaModelManager(); 502 boolean hadTemporaryCache = manager.hasTemporaryCache(); 503 try { 504 HashMap newElements = manager.getTemporaryCache(); 505 generateInfos(info, newElements, monitor); 506 if (info == null) { 507 info = newElements.get(this); 508 } 509 if (info == null) { Openable openable = (Openable) getOpenable(); 513 if (newElements.containsKey(openable)) { 514 openable.closeBuffer(); 515 } 516 throw newNotPresentException(); 517 } 518 if (!hadTemporaryCache) { 519 manager.putInfos(this, newElements); 520 } 521 } finally { 522 if (!hadTemporaryCache) { 523 manager.resetTemporaryCache(); 524 } 525 } 526 return info; 527 } 528 530 public String readableName() { 531 return this.getElementName(); 532 } 533 public JavaElement resolved(Binding binding) { 534 return this; 535 } 536 public JavaElement unresolved() { 537 return this; 538 } 539 protected String tabString(int tab) { 540 StringBuffer buffer = new StringBuffer (); 541 for (int i = tab; i > 0; i--) 542 buffer.append(" "); return buffer.toString(); 544 } 545 548 public String toDebugString() { 549 StringBuffer buffer = new StringBuffer (); 550 this.toStringInfo(0, buffer, NO_INFO, true); 551 return buffer.toString(); 552 } 553 556 public String toString() { 557 StringBuffer buffer = new StringBuffer (); 558 toString(0, buffer); 559 return buffer.toString(); 560 } 561 564 protected void toString(int tab, StringBuffer buffer) { 565 Object info = this.toStringInfo(tab, buffer); 566 if (tab == 0) { 567 this.toStringAncestors(buffer); 568 } 569 this.toStringChildren(tab, buffer, info); 570 } 571 574 public String toStringWithAncestors() { 575 return toStringWithAncestors(true); 576 } 577 580 public String toStringWithAncestors(boolean showResolvedInfo) { 581 StringBuffer buffer = new StringBuffer (); 582 this.toStringInfo(0, buffer, NO_INFO, showResolvedInfo); 583 this.toStringAncestors(buffer); 584 return buffer.toString(); 585 } 586 589 protected void toStringAncestors(StringBuffer buffer) { 590 JavaElement parentElement = (JavaElement)this.getParent(); 591 if (parentElement != null && parentElement.getParent() != null) { 592 buffer.append(" [in "); parentElement.toStringInfo(0, buffer, NO_INFO, false); 594 parentElement.toStringAncestors(buffer); 595 buffer.append("]"); } 597 } 598 601 protected void toStringChildren(int tab, StringBuffer buffer, Object info) { 602 if (info == null || !(info instanceof JavaElementInfo)) return; 603 IJavaElement[] children = ((JavaElementInfo)info).getChildren(); 604 for (int i = 0; i < children.length; i++) { 605 buffer.append("\n"); ((JavaElement)children[i]).toString(tab + 1, buffer); 607 } 608 } 609 612 public Object toStringInfo(int tab, StringBuffer buffer) { 613 Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this); 614 this.toStringInfo(tab, buffer, info, true); 615 return info; 616 } 617 621 protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) { 622 buffer.append(this.tabString(tab)); 623 toStringName(buffer); 624 if (info == null) { 625 buffer.append(" (not open)"); } 627 } 628 631 protected void toStringName(StringBuffer buffer) { 632 buffer.append(getElementName()); 633 } 634 635 protected URL getJavadocBaseLocation() throws JavaModelException { 636 IPackageFragmentRoot root= (IPackageFragmentRoot) this.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); 637 if (root == null) { 638 return null; 639 } 640 641 if (root.getKind() == IPackageFragmentRoot.K_BINARY) { 642 IClasspathEntry entry= root.getRawClasspathEntry(); 643 if (entry == null) { 644 return null; 645 } 646 if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { 647 entry= getRealClasspathEntry(root.getJavaProject(), entry.getPath(), root.getPath()); 648 if (entry == null) { 649 return null; 650 } 651 } 652 return getLibraryJavadocLocation(entry); 653 } 654 return null; 655 } 656 657 private static IClasspathEntry getRealClasspathEntry(IJavaProject jproject, IPath containerPath, IPath libPath) throws JavaModelException { 658 IClasspathContainer container= JavaCore.getClasspathContainer(containerPath, jproject); 659 if (container != null) { 660 IClasspathEntry[] entries= container.getClasspathEntries(); 661 for (int i= 0; i < entries.length; i++) { 662 IClasspathEntry curr = entries[i]; 663 if (curr == null) { 664 if (JavaModelManager.CP_RESOLVE_VERBOSE) { 665 JavaModelManager.getJavaModelManager().verbose_missbehaving_container(jproject, containerPath, entries); 666 } 667 break; 668 } 669 IClasspathEntry resolved= JavaCore.getResolvedClasspathEntry(curr); 670 if (resolved != null && libPath.equals(resolved.getPath())) { 671 return curr; } 673 } 674 } 675 return null; } 677 678 protected static URL getLibraryJavadocLocation(IClasspathEntry entry) throws JavaModelException { 679 switch(entry.getEntryKind()) { 680 case IClasspathEntry.CPE_LIBRARY : 681 case IClasspathEntry.CPE_VARIABLE : 682 break; 683 default : 684 throw new IllegalArgumentException ("Entry must be of kind CPE_LIBRARY or CPE_VARIABLE"); } 686 687 IClasspathAttribute[] extraAttributes= entry.getExtraAttributes(); 688 for (int i= 0; i < extraAttributes.length; i++) { 689 IClasspathAttribute attrib= extraAttributes[i]; 690 if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) { 691 String value = attrib.getValue(); 692 try { 693 return new URL (value); 694 } catch (MalformedURLException e) { 695 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, value)); 696 } 697 } 698 } 699 return null; 700 } 701 702 705 public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException { 706 return null; 707 } 708 709 int getIndexOf(byte[] array, byte[] toBeFound, int start) { 710 if (array == null || toBeFound == null) 711 return -1; 712 final int toBeFoundLength = toBeFound.length; 713 final int arrayLength = array.length; 714 if (arrayLength < toBeFoundLength) 715 return -1; 716 loop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) { 717 if (array[i] == toBeFound[0]) { 718 for (int j = 1; j < toBeFoundLength; j++) { 719 if (array[i + j] != toBeFound[j]) 720 continue loop; 721 } 722 return i; 723 } 724 } 725 return -1; 726 } 727 731 protected String getURLContents(String docUrlValue) throws JavaModelException { 732 InputStream stream = null; 733 JarURLConnection connection2 = null; 734 try { 735 URL docUrl = new URL (docUrlValue); 736 URLConnection connection = docUrl.openConnection(); 737 if (connection instanceof JarURLConnection ) { 738 connection2 = (JarURLConnection ) connection; 739 connection.setUseCaches(false); 741 } 742 stream = new BufferedInputStream (connection.getInputStream()); 743 String encoding = connection.getContentEncoding(); 744 byte[] contents = org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsByteArray(stream, connection.getContentLength()); 745 if (encoding == null) { 746 int index = getIndexOf(contents, CONTENT_TYPE, 0); 747 if (index != -1) { 748 index = getIndexOf(contents, CONTENT, index); 749 if (index != -1) { 750 int offset = index + CONTENT.length; 751 int index2 = getIndexOf(contents, CLOSING_DOUBLE_QUOTE, offset); 752 if (index2 != -1) { 753 final int charsetIndex = getIndexOf(contents, CHARSET, offset); 754 if (charsetIndex != -1) { 755 int start = charsetIndex + CHARSET.length; 756 encoding = new String (contents, start, index2 - start, "UTF-8"); } 758 } 759 } 760 } 761 } 762 try { 763 if (encoding == null) { 764 encoding = this.getJavaProject().getProject().getDefaultCharset(); 765 } 766 } catch (CoreException e) { 767 } 769 if (contents != null) { 770 if (encoding != null) { 771 return new String (contents, encoding); 772 } else { 773 return new String (contents); 775 } 776 } 777 } catch (MalformedURLException e) { 778 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, this)); 779 } catch (FileNotFoundException e) { 780 } catch(IOException e) { 782 StringWriter stringWriter = new StringWriter (); 783 PrintWriter writer = new PrintWriter (stringWriter); 784 e.printStackTrace(writer); 785 writer.flush(); 786 writer.close(); 787 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, this, String.valueOf(stringWriter.getBuffer()))); 788 } finally { 789 if (stream != null) { 790 try { 791 stream.close(); 792 } catch (IOException e) { 793 } 795 } 796 if (connection2 != null) { 797 try { 798 connection2.getJarFile().close(); 799 } catch(IOException e) { 800 } catch(IllegalStateException e) { 802 806 } 807 } 808 } 809 return null; 810 } 811 } 812 | Popular Tags |