/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.editor.codecompletion.revisited.javaintegration;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Method;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavadocContentAccess;
import org.eclipse.jdt.ui.text.java.CompletionProposalLabelProvider;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.codecompletion.revisited.modules.CompiledToken;
import com.aptana.shared_core.string.FastStringBuffer;
import com.aptana.shared_core.utils.Reflection;
/**
* This is the token that encapsulates a java element.
*
* @author Fabio
*/
public class JavaElementToken extends CompiledToken {
public IJavaElement javaElement;
private int completionProposalKind;
private int completionProposalFlags;
private int completionProposalAdditionalFlags;
private char[] completionPropsoalSignature;
/**
* If not null, this image is returned (otherwise, the image is calculated)
*/
private Image image;
/**
* Used for backward compatibility to eclipse 3.2
*/
static boolean HAS_ADDITIONAL_FLAGS = true;
static {
try {
Method m = Reflection.findMethod(CompletionProposal.class, "getAdditionalFlags");
if (m == null) {
HAS_ADDITIONAL_FLAGS = false;
}
} catch (Throwable e) {
HAS_ADDITIONAL_FLAGS = false;
}
}
protected JavaElementToken(String rep, String doc, String args, String parentPackage, int type,
IJavaElement javaElement, int completionProposalKind, int completionProposalFlags,
int completionProposalAdditionalFlags, char[] completionPropsoalSignature) {
super(rep, doc, args, parentPackage, type);
this.javaElement = javaElement;
this.completionProposalKind = completionProposalKind;
this.completionProposalFlags = completionProposalFlags;
this.completionProposalAdditionalFlags = completionProposalAdditionalFlags;
this.completionPropsoalSignature = completionPropsoalSignature;
}
public JavaElementToken(String rep, String doc, String args, String parentPackage, int type,
IJavaElement javaElement, CompletionProposal completionProposal) {
super(rep, doc, args, parentPackage, type);
this.javaElement = javaElement;
this.completionProposalKind = completionProposal.getKind();
this.completionProposalFlags = completionProposal.getFlags();
if (HAS_ADDITIONAL_FLAGS) {
this.completionProposalAdditionalFlags = completionProposal.getAdditionalFlags();
}
this.completionPropsoalSignature = completionProposal.getSignature();
}
public JavaElementToken(String rep, String doc, String args, String parentPackage, int type,
IJavaElement javaElement, Image image) {
super(rep, doc, args, parentPackage, type);
this.javaElement = javaElement;
this.image = image;
}
@Override
public Image getImage() {
if (this.image != null) {
return this.image;
}
CompletionProposalLabelProvider provider = new CompletionProposalLabelProvider();
CompletionProposal generatedProposal = CompletionProposal.create(completionProposalKind, 0);
generatedProposal.setFlags(completionProposalFlags);
if (HAS_ADDITIONAL_FLAGS) {
generatedProposal.setAdditionalFlags(completionProposalAdditionalFlags);
}
generatedProposal.setDeclarationSignature(completionPropsoalSignature);
generatedProposal.setSignature(completionPropsoalSignature);
//uses: kind, flags, signature to create an image.
ImageDescriptor descriptor = provider.createImageDescriptor(generatedProposal);
return descriptor.createImage();
}
@Override
public String getDocStr() {
if (javaElement instanceof IMember) {
IMember member = (IMember) javaElement;
try {
return StringUtils.extractTextFromHTML(extractJavadoc(member, new NullProgressMonitor()));
} catch (JavaModelException e) {
//just ignore it in this case (that may happen when no docstring is available)
} catch (Exception e) {
Log.log("Error getting completion for " + member, e);
}
}
return null;
}
//Helpers to get the docstring (adapted from org.eclipse.jdt.internal.ui.text.java.ProposalInfo)
/**
* Extracts the javadoc for the given <code>IMember</code> and returns it
* as HTML.
*
* @param member the member to get the documentation for
* @param monitor a progress monitor
* @return the javadoc for <code>member</code> or <code>null</code> if
* it is not available
* @throws JavaModelException if accessing the javadoc fails
* @throws IOException if reading the javadoc fails
*/
private String extractJavadoc(IMember member, IProgressMonitor monitor) throws JavaModelException, IOException {
if (member != null) {
Reader reader = getContentReader(member, monitor);
if (reader != null)
return getString(reader);
}
return null;
}
private Reader getContentReader(IMember member, IProgressMonitor monitor) throws JavaModelException {
Reader contentReader = JavadocContentAccess.getContentReader(member, true);
if (contentReader != null)
return contentReader;
if (member.getOpenable().getBuffer() == null) { // only if no source available
String s = member.getAttachedJavadoc(monitor);
if (s != null)
return new StringReader(s);
}
return null;
}
/**
* Gets the reader content as a String
*/
private static String getString(Reader reader) {
FastStringBuffer buf = new FastStringBuffer();
char[] buffer = new char[1024];
int count;
try {
while ((count = reader.read(buffer)) != -1)
buf.append(buffer, 0, count);
} catch (IOException e) {
return null;
}
return buf.toString();
}
}