Package org.aspectj.org.eclipse.jdt.internal.core

Source Code of org.aspectj.org.eclipse.jdt.internal.core.JavaElement

/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.core;

import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.aspectj.org.eclipse.jdt.core.*;
import org.aspectj.org.eclipse.jdt.core.dom.ASTNode;
import org.aspectj.org.eclipse.jdt.core.dom.CompilationUnit;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.aspectj.org.eclipse.jdt.internal.core.util.MementoTokenizer;
import org.aspectj.org.eclipse.jdt.internal.core.util.Util;

/**
* Root of Java element handle hierarchy.
*
* @see IJavaElement
*/
public abstract class JavaElement extends PlatformObject implements IJavaElement {
//  private static final QualifiedName PROJECT_JAVADOC= new QualifiedName(JavaCore.PLUGIN_ID, "project_javadoc_location"); //$NON-NLS-1$

  private static final byte[] CLOSING_DOUBLE_QUOTE = new byte[] { 34 };
  private static final byte[] CHARSET = new byte[] {99, 104, 97, 114, 115, 101, 116, 61 };
  private static final byte[] CONTENT_TYPE = new byte[] { 34, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 34 };
  private static final byte[] CONTENT = new byte[] { 99, 111, 110, 116, 101, 110, 116, 61, 34 };
  public static final char JEM_ESCAPE = '\\';
  public static final char JEM_JAVAPROJECT = '=';
  public static final char JEM_PACKAGEFRAGMENTROOT = '/';
  public static final char JEM_PACKAGEFRAGMENT = '<';
  public static final char JEM_FIELD = '^';
  public static final char JEM_METHOD = '~';
  public static final char JEM_INITIALIZER = '|';
  public static final char JEM_COMPILATIONUNIT = '{';
  public static final char JEM_CLASSFILE = '(';
  public static final char JEM_TYPE = '[';
  public static final char JEM_PACKAGEDECLARATION = '%';
  public static final char JEM_IMPORTDECLARATION = '#';
  public static final char JEM_COUNT = '!';
  public static final char JEM_LOCALVARIABLE = '@';
  public static final char JEM_TYPE_PARAMETER = ']';

  /**
   * This element's parent, or <code>null</code> if this
   * element does not have a parent.
   */
  protected JavaElement parent;

  protected static final JavaElement[] NO_ELEMENTS = new JavaElement[0];
  protected static final Object NO_INFO = new Object();
 
  /**
   * Constructs a handle for a java element with
   * the given parent element.
   *
   * @param parent The parent of java element
   *
   * @exception IllegalArgumentException if the type is not one of the valid
   *    Java element type constants
   *
   */
  protected JavaElement(JavaElement parent) throws IllegalArgumentException {
    this.parent = parent;
  }
  /**
   * @see IOpenable
   */
  public void close() throws JavaModelException {
    JavaModelManager.getJavaModelManager().removeInfoAndChildren(this);
  }
  /**
   * This element is being closed.  Do any necessary cleanup.
   */
  protected abstract void closing(Object info) throws JavaModelException;
  /*
   * Returns a new element info for this element.
   */
  protected abstract Object createElementInfo();
  /**
   * Returns true if this handle represents the same Java element
   * as the given handle. By default, two handles represent the same
   * element if they are identical or if they represent the same type
   * of element, have equal names, parents, and occurrence counts.
   *
   * <p>If a subclass has other requirements for equality, this method
   * must be overridden.
   *
   * @see Object#equals
   */
  public boolean equals(Object o) {
   
    if (this == o) return true;
 
    // Java model parent is null
    if (this.parent == null) return super.equals(o);
 
    // assume instanceof check is done in subclass
    JavaElement other = (JavaElement) o;   
    return getElementName().equals(other.getElementName()) &&
        this.parent.equals(other.parent);
  }
  protected void escapeMementoName(StringBuffer buffer, String mementoName) {
    for (int i = 0, length = mementoName.length(); i < length; i++) {
      char character = mementoName.charAt(i);
      switch (character) {
        case JEM_ESCAPE:
        case JEM_COUNT:
        case JEM_JAVAPROJECT:
        case JEM_PACKAGEFRAGMENTROOT:
        case JEM_PACKAGEFRAGMENT:
        case JEM_FIELD:
        case JEM_METHOD:
        case JEM_INITIALIZER:
        case JEM_COMPILATIONUNIT:
        case JEM_CLASSFILE:
        case JEM_TYPE:
        case JEM_PACKAGEDECLARATION:
        case JEM_IMPORTDECLARATION:
        case JEM_LOCALVARIABLE:
        case JEM_TYPE_PARAMETER:
          buffer.append(JEM_ESCAPE);
      }
      buffer.append(character);
    }
  }
  /**
   * @see IJavaElement
   */
  public boolean exists() {
   
    try {
      getElementInfo();
      return true;
    } catch (JavaModelException e) {
      // element doesn't exist: return false
    }
    return false;
  }
 
  /**
   * Returns the <code>ASTNode</code> that corresponds to this <code>JavaElement</code>
   * or <code>null</code> if there is no corresponding node.
   */
  public ASTNode findNode(CompilationUnit ast) {
    return null; // works only inside a compilation unit
  }
  /**
   * Generates the element infos for this element, its ancestors (if they are not opened) and its children (if it is an Openable).
   * Puts the newly created element info in the given map.
   */
  protected abstract void generateInfos(Object info, HashMap newElements, IProgressMonitor pm) throws JavaModelException;
 
  /**
   * @see IJavaElement
   */
  public IJavaElement getAncestor(int ancestorType) {
   
    IJavaElement element = this;
    while (element != null) {
      if (element.getElementType() == ancestorTypereturn element;
      element= element.getParent();
    }
    return null;       
  }
  /**
   * @see IParent
   */
  public IJavaElement[] getChildren() throws JavaModelException {
    Object elementInfo = getElementInfo();
    if (elementInfo instanceof JavaElementInfo) {
      return ((JavaElementInfo)elementInfo).getChildren();
    } else {
      return NO_ELEMENTS;
    }
  }
  /**
   * Returns a collection of (immediate) children of this node of the
   * specified type.
   *
   * @param type - one of the JEM_* constants defined by JavaElement
   */
  public ArrayList getChildrenOfType(int type) throws JavaModelException {
    IJavaElement[] children = getChildren();
    int size = children.length;
    ArrayList list = new ArrayList(size);
    for (int i = 0; i < size; ++i) {
      JavaElement elt = (JavaElement)children[i];
      if (elt.getElementType() == type) {
        list.add(elt);
      }
    }
    return list;
  }
  /**
   * @see IMember
   */
  public IClassFile getClassFile() {
    return null;
  }
  /**
   * @see IMember
   */
  public ICompilationUnit getCompilationUnit() {
    return null;
  }
  /**
   * Returns the info for this handle. 
   * If this element is not already open, it and all of its parents are opened.
   * Does not return null.
   * NOTE: BinaryType infos are NOT rooted under JavaElementInfo.
   * @exception JavaModelException if the element is not present or not accessible
   */
  public Object getElementInfo() throws JavaModelException {
    return getElementInfo(null);
  }
  /**
   * Returns the info for this handle. 
   * If this element is not already open, it and all of its parents are opened.
   * Does not return null.
   * NOTE: BinaryType infos are NOT rooted under JavaElementInfo.
   * @exception JavaModelException if the element is not present or not accessible
   */
  public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {

    JavaModelManager manager = JavaModelManager.getJavaModelManager();
    Object info = manager.getInfo(this);
    if (info != null) return info;
    return openWhenClosed(createElementInfo(), monitor);
  }
  /**
   * @see IAdaptable
   */
  public String getElementName() {
    return ""; //$NON-NLS-1$
  }
  /*
   * Creates a Java element handle from the given memento.
   * The given token is the current delimiter indicating the type of the next token(s).
   * The given working copy owner is used only for compilation unit handles.
   */
  public abstract IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner);
  /*
   * Creates a Java element handle from the given memento.
   * The given working copy owner is used only for compilation unit handles.
   */
  public IJavaElement getHandleFromMemento(MementoTokenizer memento, WorkingCopyOwner owner) {
    if (!memento.hasMoreTokens()) return this;
    String token = memento.nextToken();
    return getHandleFromMemento(token, memento, owner);
  }
  /**
   * @see IJavaElement
   */
  public String getHandleIdentifier() {
    return getHandleMemento();
  }
  /**
   * @see JavaElement#getHandleMemento()
   */
  public String getHandleMemento(){
    StringBuffer buff = new StringBuffer();
    getHandleMemento(buff);
    return buff.toString();
  }
  protected void getHandleMemento(StringBuffer buff) {
    ((JavaElement)getParent()).getHandleMemento(buff);
    buff.append(getHandleMementoDelimiter());
    escapeMementoName(buff, getElementName());
  }
  /**
   * Returns the <code>char</code> that marks the start of this handles
   * contribution to a memento.
   */
  protected abstract char getHandleMementoDelimiter();
  /**
   * @see IJavaElement
   */
  public IJavaModel getJavaModel() {
    IJavaElement current = this;
    do {
      if (current instanceof IJavaModel) return (IJavaModel) current;
    } while ((current = current.getParent()) != null);
    return null;
  }

  /**
   * @see IJavaElement
   */
  public IJavaProject getJavaProject() {
    IJavaElement current = this;
    do {
      if (current instanceof IJavaProject) return (IJavaProject) current;
    } while ((current = current.getParent()) != null);
    return null;
  }
  /*
   * @see IJavaElement
   */
  public IOpenable getOpenable() {
    return this.getOpenableParent()
  }
  /**
   * Return the first instance of IOpenable in the parent
   * hierarchy of this element.
   *
   * <p>Subclasses that are not IOpenable's must override this method.
   */
  public IOpenable getOpenableParent() {
    return (IOpenable)this.parent;
  }
  /**
   * @see IJavaElement
   */
  public IJavaElement getParent() {
    return this.parent;
  }
  /*
   * @see IJavaElement#getPrimaryElement()
   */
  public IJavaElement getPrimaryElement() {
    return getPrimaryElement(true);
  }
  /*
   * Returns the primary element. If checkOwner, and the cu owner is primary,
   * return this element.
   */
  public IJavaElement getPrimaryElement(boolean checkOwner) {
    return this;
  }
  /**
   * Returns the element that is located at the given source position
   * in this element.  This is a helper method for <code>ICompilationUnit#getElementAt</code>,
   * and only works on compilation units and types. The position given is
   * known to be within this element's source range already, and if no finer
   * grained element is found at the position, this element is returned.
   */
  protected IJavaElement getSourceElementAt(int position) throws JavaModelException {
    if (this instanceof ISourceReference) {
      IJavaElement[] children = getChildren();
      for (int i = children.length-1; i >= 0; i--) {
        IJavaElement aChild = children[i];
        if (aChild instanceof SourceRefElement) {
          SourceRefElement child = (SourceRefElement) children[i];
          ISourceRange range = child.getSourceRange();
          int start = range.getOffset();
          int end = start + range.getLength();
          if (start <= position && position <= end) {
            if (child instanceof IField) {
              // check muti-declaration case (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=39943)
              int declarationStart = start;
              SourceRefElement candidate = null;
              do {
                // check name range
                range = ((IField)child).getNameRange();
                if (position <= range.getOffset() + range.getLength()) {
                  candidate = child;
                } else {
                  return candidate == null ? child.getSourceElementAt(position) : candidate.getSourceElementAt(position);
                }
                child = --i>=0 ? (SourceRefElement) children[i] : null;
              } while (child != null && child.getSourceRange().getOffset() == declarationStart);
              // position in field's type: use first field
              return candidate.getSourceElementAt(position);
            } else if (child instanceof IParent) {
              return child.getSourceElementAt(position);
            } else {
              return child;
            }
          }
        }
      }
    } else {
      // should not happen
      Assert.isTrue(false);
    }
    return this;
  }
  /**
   * Returns the SourceMapper facility for this element, or
   * <code>null</code> if this element does not have a
   * SourceMapper.
   */
  public SourceMapper getSourceMapper() {
    return ((JavaElement)getParent()).getSourceMapper();
  }
  /* (non-Javadoc)
   * @see org.aspectj.org.eclipse.jdt.core.IJavaElement#getSchedulingRule()
   */
  public ISchedulingRule getSchedulingRule() {
    IResource resource = getResource();
    if (resource == null) {
      class NoResourceSchedulingRule implements ISchedulingRule {
        public IPath path;
        public NoResourceSchedulingRule(IPath path) {
          this.path = path;
        }
        public boolean contains(ISchedulingRule rule) {
          if (rule instanceof NoResourceSchedulingRule) {
            return this.path.isPrefixOf(((NoResourceSchedulingRule)rule).path);
          } else {
            return false;
          }
        }
        public boolean isConflicting(ISchedulingRule rule) {
          if (rule instanceof NoResourceSchedulingRule) {
            IPath otherPath = ((NoResourceSchedulingRule)rule).path;
            return this.path.isPrefixOf(otherPath) || otherPath.isPrefixOf(this.path);
          } else {
            return false;
          }
        }
      }
      return new NoResourceSchedulingRule(getPath());
    } else {
      return resource;
    }
  }
  /**
   * @see IParent
   */
  public boolean hasChildren() throws JavaModelException {
    // if I am not open, return true to avoid opening (case of a Java project, a compilation unit or a class file).
    // also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52474
    Object elementInfo = JavaModelManager.getJavaModelManager().getInfo(this);
    if (elementInfo instanceof JavaElementInfo) {
      return ((JavaElementInfo)elementInfo).getChildren().length > 0;
    } else {
      return true;
    }
  }

  /**
   * Returns the hash code for this Java element. By default,
   * the hash code for an element is a combination of its name
   * and parent's hash code. Elements with other requirements must
   * override this method.
   */
  public int hashCode() {
    if (this.parent == null) return super.hashCode();
    return Util.combineHashCodes(getElementName().hashCode(), this.parent.hashCode());
  }
  /**
   * Returns true if this element is an ancestor of the given element,
   * otherwise false.
   */
  public boolean isAncestorOf(IJavaElement e) {
    IJavaElement parentElement= e.getParent();
    while (parentElement != null && !parentElement.equals(this)) {
      parentElement= parentElement.getParent();
    }
    return parentElement != null;
  }
 
  /**
   * @see IJavaElement
   */
  public boolean isReadOnly() {
    return false;
  }
  /**
   * Creates and returns a new not present exception for this element.
   */
  public JavaModelException newNotPresentException() {
    return new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this));
  }
  /**
   * Creates and returns a new Java model exception for this element with the given status.
   */
  public JavaModelException newJavaModelException(IStatus status) {
    if (status instanceof IJavaModelStatus)
      return new JavaModelException((IJavaModelStatus) status);
    else
      return new JavaModelException(new JavaModelStatus(status.getSeverity(), status.getCode(), status.getMessage()));
  }
  /*
   * Opens an <code>Openable</code> that is known to be closed (no check for <code>isOpen()</code>).
   * Returns the created element info.
   */
  protected Object openWhenClosed(Object info, IProgressMonitor monitor) throws JavaModelException {
    JavaModelManager manager = JavaModelManager.getJavaModelManager();
    boolean hadTemporaryCache = manager.hasTemporaryCache();
    try {
      HashMap newElements = manager.getTemporaryCache();
      generateInfos(info, newElements, monitor);
      if (info == null) {
        info = newElements.get(this);
      }
      if (info == null) { // a source ref element could not be opened
        // close the buffer that was opened for the openable parent
          // close only the openable's buffer (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=62854)
          Openable openable = (Openable) getOpenable();
          if (newElements.containsKey(openable)) {
              openable.closeBuffer();
          }
        throw newNotPresentException();
      }
      if (!hadTemporaryCache) {
        manager.putInfos(this, newElements);
      }
    } finally {
      if (!hadTemporaryCache) {
        manager.resetTemporaryCache();
      }
    }
    return info;
  }
  /**
   */
  public String readableName() {
    return this.getElementName();
  }
  public JavaElement resolved(Binding binding) {
    return this;
  }
  public JavaElement unresolved() {
    return this;
  }
  protected String tabString(int tab) {
    StringBuffer buffer = new StringBuffer();
    for (int i = tab; i > 0; i--)
      buffer.append("  "); //$NON-NLS-1$
    return buffer.toString();
  }
  /**
   * Debugging purposes
   */
  public String toDebugString() {
    StringBuffer buffer = new StringBuffer();
    this.toStringInfo(0, buffer, NO_INFO, true/*show resolved info*/);
    return buffer.toString();
  }
  /**
   *  Debugging purposes
   */
  public String toString() {
    StringBuffer buffer = new StringBuffer();
    toString(0, buffer);
    return buffer.toString();
  }
  /**
   *  Debugging purposes
   */
  protected void toString(int tab, StringBuffer buffer) {
    Object info = this.toStringInfo(tab, buffer);
    if (tab == 0) {
      this.toStringAncestors(buffer);
    }
    this.toStringChildren(tab, buffer, info);
  }
  /**
   *  Debugging purposes
   */
  public String toStringWithAncestors() {
    return toStringWithAncestors(true/*show resolved info*/);
  }
    /**
   *  Debugging purposes
   */
  public String toStringWithAncestors(boolean showResolvedInfo) {
    StringBuffer buffer = new StringBuffer();
    this.toStringInfo(0, buffer, NO_INFO, showResolvedInfo);
    this.toStringAncestors(buffer);
    return buffer.toString();
  }
  /**
   *  Debugging purposes
   */
  protected void toStringAncestors(StringBuffer buffer) {
    JavaElement parentElement = (JavaElement)this.getParent();
    if (parentElement != null && parentElement.getParent() != null) {
      buffer.append(" [in "); //$NON-NLS-1$
      parentElement.toStringInfo(0, buffer, NO_INFO, false/*don't show resolved info*/);
      parentElement.toStringAncestors(buffer);
      buffer.append("]"); //$NON-NLS-1$
    }
  }
  /**
   *  Debugging purposes
   */
  protected void toStringChildren(int tab, StringBuffer buffer, Object info) {
    if (info == null || !(info instanceof JavaElementInfo)) return;
    IJavaElement[] children = ((JavaElementInfo)info).getChildren();
    for (int i = 0; i < children.length; i++) {
      buffer.append("\n"); //$NON-NLS-1$
      ((JavaElement)children[i]).toString(tab + 1, buffer);
    }
  }
  /**
   *  Debugging purposes
   */
  public Object toStringInfo(int tab, StringBuffer buffer) {
    Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this);
    this.toStringInfo(tab, buffer, info, true/*show resolved info*/);
    return info;
  }
  /**
   *  Debugging purposes
   * @param showResolvedInfo TODO
   */
  protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
    buffer.append(this.tabString(tab));
    toStringName(buffer);
    if (info == null) {
      buffer.append(" (not open)"); //$NON-NLS-1$
    }
  }
  /**
   *  Debugging purposes
   */
  protected void toStringName(StringBuffer buffer) {
    buffer.append(getElementName());
  }
 
  protected URL getJavadocBaseLocation() throws JavaModelException {
    IPackageFragmentRoot root= (IPackageFragmentRoot) this.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
    if (root == null) {
      return null;
    }

    if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
      IClasspathEntry entry= root.getRawClasspathEntry();
      if (entry == null) {
        return null;
      }
      if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
        entry= getRealClasspathEntry(root.getJavaProject(), entry.getPath(), root.getPath());
        if (entry == null) {
          return null;
        }
      }
      return getLibraryJavadocLocation(entry);
    }
    return null;
  }
 
  private static IClasspathEntry getRealClasspathEntry(IJavaProject jproject, IPath containerPath, IPath libPath) throws JavaModelException {
    IClasspathContainer container= JavaCore.getClasspathContainer(containerPath, jproject);
    if (container != null) {
      IClasspathEntry[] entries= container.getClasspathEntries();
      for (int i= 0; i < entries.length; i++) {
        IClasspathEntry curr = entries[i];
        if (curr == null) {
          if (JavaModelManager.CP_RESOLVE_VERBOSE) {
            JavaModelManager.getJavaModelManager().verbose_missbehaving_container(jproject, containerPath, entries);
          }
          break;
        }
        IClasspathEntry resolved= JavaCore.getResolvedClasspathEntry(curr);
        if (resolved != null && libPath.equals(resolved.getPath())) {
          return curr; // return the real entry
        }
      }
    }
    return null; // not found
  }
 
  protected static URL getLibraryJavadocLocation(IClasspathEntry entry) throws JavaModelException {
    switch(entry.getEntryKind()) {
      case IClasspathEntry.CPE_LIBRARY :
      case IClasspathEntry.CPE_VARIABLE :
        break;
      default :
        throw new IllegalArgumentException("Entry must be of kind CPE_LIBRARY or CPE_VARIABLE"); //$NON-NLS-1$
    }
   
    IClasspathAttribute[] extraAttributes= entry.getExtraAttributes();
    for (int i= 0; i < extraAttributes.length; i++) {
      IClasspathAttribute attrib= extraAttributes[i];
      if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) {
        String value = attrib.getValue();
        try {
          return new URL(value);
        } catch (MalformedURLException e) {
          throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, value));
        }
      }
    }
    return null;
  }
 
  /*
   * @see IJavaElement#getAttachedJavadoc(IProgressMonitor)
   */
  public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
    return null;
  }
 
  int getIndexOf(byte[] array, byte[] toBeFound, int start) {
    if (array == null || toBeFound == null)
      return -1;
    final int toBeFoundLength = toBeFound.length;
    final int arrayLength = array.length;
    if (arrayLength < toBeFoundLength)
      return -1;
    loop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
      if (array[i] == toBeFound[0]) {
        for (int j = 1; j < toBeFoundLength; j++) {
          if (array[i + j] != toBeFound[j])
            continue loop;
        }
        return i;
      }
    }
    return -1;
 
  /*
   * We don't use getContentEncoding() on the URL connection, because it might leave open streams behind.
   * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=117890
   */
  protected String getURLContents(String docUrlValue) throws JavaModelException {
    InputStream stream = null;
    JarURLConnection connection2 = null;
    try {
      URL docUrl = new URL(docUrlValue);
      URLConnection connection = docUrl.openConnection();
      if (connection instanceof JarURLConnection) {
        connection2 = (JarURLConnection) connection;
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=156307
        connection.setUseCaches(false);
      }
      stream = new BufferedInputStream(connection.getInputStream());
      String encoding = connection.getContentEncoding();
      byte[] contents = org.aspectj.org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsByteArray(stream, connection.getContentLength());
      if (encoding == null) {
        int index = getIndexOf(contents, CONTENT_TYPE, 0);
        if (index != -1) {
          index = getIndexOf(contents, CONTENT, index);
          if (index != -1) {
            int offset = index + CONTENT.length;
            int index2 = getIndexOf(contents, CLOSING_DOUBLE_QUOTE, offset);
            if (index2 != -1) {
              final int charsetIndex = getIndexOf(contents, CHARSET, offset);
              if (charsetIndex != -1) {
                int start = charsetIndex + CHARSET.length;
                encoding = new String(contents, start, index2 - start, "UTF-8"); //$NON-NLS-1$
              }
            }
          }
        }
      }
      try {
        if (encoding == null) {
          encoding = this.getJavaProject().getProject().getDefaultCharset();
        }
      } catch (CoreException e) {
        // ignore
      }
      if (contents != null) {
        if (encoding != null) {
          return new String(contents, encoding);
        } else {
          // platform encoding is used
          return new String(contents);
        }
      }     
     } catch (MalformedURLException e) {
       throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, this));
    } catch (FileNotFoundException e) {
      // ignore. see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=120559
    } catch(IOException e) {
      StringWriter stringWriter = new StringWriter();
      PrintWriter writer = new PrintWriter(stringWriter);
      e.printStackTrace(writer);
      writer.flush();
      writer.close();
      throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, this, String.valueOf(stringWriter.getBuffer())));
    } finally {
      if (stream != null) {
        try {
          stream.close();
        } catch (IOException e) {
          // ignore
        }
      }
      if (connection2 != null) {
        try {
          connection2.getJarFile().close();
        } catch(IOException e) {
          // ignore
        } catch(IllegalStateException e) {
          /*
           * ignore. Can happen in case the stream.close() did close the jar file
           * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=140750
           */
        }
       }
    }
    return null;
  }
}
TOP

Related Classes of org.aspectj.org.eclipse.jdt.internal.core.JavaElement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.