/*******************************************************************************
* Copyright (c) 2012 VMware, Inc.
* 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:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.quickfix.jdt.computers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.internal.core.SourceField;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceRefElement;
import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal;
import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.source.SourceViewer;
import org.springframework.ide.eclipse.beans.ui.BeansUIImages;
import org.springframework.ide.eclipse.quickfix.jdt.util.ProposalCalculatorUtil;
/**
* @author Terry Denney
* @author Martin Lippert
* @since 2.6
*/
public class QualifierArgumentProposalComputer extends AnnotationProposalComputer {
// TODO: clean up code
@Override
protected List<ICompletionProposal> computeCompletionProposals(SourceMethod method, String value, IAnnotation a,
JavaContentAssistInvocationContext javaContext) throws JavaModelException {
// @Override
// protected List<ICompletionProposal>
// computeCompletionProposals(SourceMethod method,
// LocationInformation locationInfo, Annotation annotation,
// JavaContentAssistInvocationContext javaContext)
// throws JavaModelException {
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
ITextViewer viewer = javaContext.getViewer();
if (viewer instanceof SourceViewer) {
ICompilationUnit cu = javaContext.getCompilationUnit();
SourceViewer sourceViewer = (SourceViewer) javaContext.getViewer();
int invocationOffset = javaContext.getInvocationOffset();
AssistContext assistContext = new AssistContext(cu, sourceViewer, invocationOffset, 0);
ASTNode node = ((SourceRefElement) a).findNode(assistContext.getASTRoot());
if (node == null) {
node = assistContext.getCoveredNode();
}
if (!(a instanceof Annotation)) {
return Collections.emptyList();
}
Annotation annotation = (Annotation) a;
LocationInformation locationInfo = null;
if (node instanceof NormalAnnotation) {
NormalAnnotation normalAnnotation = (NormalAnnotation) node;
@SuppressWarnings("unchecked")
List<MemberValuePair> pairs = normalAnnotation.values();
for (MemberValuePair pair : pairs) {
Expression expression = pair.getValue();
if (expression instanceof StringLiteral) {
locationInfo = getLocationInformation((StringLiteral) expression, javaContext);
}
}
}
else if (node instanceof SingleMemberAnnotation) {
SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) node;
Expression expression = singleMemberAnnotation.getValue();
locationInfo = getLocationInformation((StringLiteral) expression, javaContext);
}
if (locationInfo == null) {
return Collections.emptyList();
}
// if (viewer instanceof SourceViewer) {
//
// // check for annotation to avoid performance overhead in all
// other
// // cases
// if (ProposalCalculatorUtil.hasAnnotationInParameters(method,
// "Qualifier")) {
ISourceRange methodSourceRange = method.getSourceRange();
assistContext = new AssistContext(javaContext.getCompilationUnit(), sourceViewer,
methodSourceRange.getOffset(), methodSourceRange.getLength());
node = assistContext.getCoveringNode();
if (node instanceof MethodDeclaration) {
MethodDeclaration methodDecl = (MethodDeclaration) node;
@SuppressWarnings("unchecked")
List<SingleVariableDeclaration> parameters = methodDecl.parameters();
for (SingleVariableDeclaration parameter : parameters) {
Set<Annotation> annotations = ProposalCalculatorUtil.findAnnotations("Qualifier", invocationOffset,
parameter);
for (Annotation an : annotations) {
if (an.equals(annotation)) {
// LocationInformation info =
// getLocationSourceRange(a,
// javaContext.getViewer(),
// invocationOffset);
// int locationOffset = info.getOffset();
// int locationLength = info.getLength();
// if (invocationOffset >= locationOffset
// && invocationOffset <= locationOffset +
// locationLength) {
ITypeBinding typeBinding = parameter.getType().resolveBinding();
proposals.addAll(getMatchingBeansProposal(locationInfo.getFilter(), typeBinding,
methodDecl, javaContext, locationInfo));
}
}
}
}
}
return proposals;
}
@Override
protected List<ICompletionProposal> computeCompletionProposals(SourceField field, String value, IAnnotation a,
JavaContentAssistInvocationContext javaContext) throws JavaModelException {
// @Override
// protected List<ICompletionProposal>
// computeCompletionProposals(SourceField field, LocationInformation
// locationInfo,
// Annotation annotation, JavaContentAssistInvocationContext
// javaContext) throws JavaModelException {
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
ITextViewer viewer = javaContext.getViewer();
if (viewer instanceof SourceViewer) {
ICompilationUnit cu = javaContext.getCompilationUnit();
SourceViewer sourceViewer = (SourceViewer) javaContext.getViewer();
int invocationOffset = javaContext.getInvocationOffset();
AssistContext assistContext = new AssistContext(cu, sourceViewer, invocationOffset, 0);
ASTNode node = ((SourceRefElement) a).findNode(assistContext.getASTRoot());
if (node == null) {
node = assistContext.getCoveredNode();
}
LocationInformation locationInfo = null;
if (node instanceof NormalAnnotation) {
NormalAnnotation normalAnnotation = (NormalAnnotation) node;
@SuppressWarnings("unchecked")
List<MemberValuePair> pairs = normalAnnotation.values();
for (MemberValuePair pair : pairs) {
Expression expression = pair.getValue();
if (expression instanceof StringLiteral) {
locationInfo = getLocationInformation((StringLiteral) expression, javaContext);
}
}
}
else if (node instanceof SingleMemberAnnotation) {
SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) node;
Expression expression = singleMemberAnnotation.getValue();
locationInfo = getLocationInformation((StringLiteral) expression, javaContext);
}
if (locationInfo == null) {
return Collections.emptyList();
}
ISourceRange fieldSourceRange = field.getSourceRange();
assistContext = new AssistContext(javaContext.getCompilationUnit(), sourceViewer,
fieldSourceRange.getOffset(), fieldSourceRange.getLength());
node = assistContext.getCoveringNode();
if (node instanceof FieldDeclaration) {
// int invocationOffset = javaContext.getInvocationOffset();
FieldDeclaration fieldDecl = (FieldDeclaration) node;
// Set<Annotation> annotations =
// ProposalCalculatorUtil.findAnnotations("Qualifier",
// invocationOffset,
// fieldDecl);
// for (Annotation a : annotations) {
// LocationInformation info = getLocationSourceRange(a,
// javaContext.getViewer(), invocationOffset);
// int locationOffset = info.getOffset();
// int locationLength = info.getLength();
// if (invocationOffset >= locationOffset && invocationOffset <=
// locationOffset + locationLength) {
ITypeBinding typeBinding = fieldDecl.getType().resolveBinding();
proposals.addAll(getMatchingBeansProposal(locationInfo.getFilter(), typeBinding, fieldDecl,
javaContext, locationInfo));
}
}
return proposals;
}
private List<JavaCompletionProposal> getMatchingBeansProposal(String filter, ITypeBinding typeBinding,
BodyDeclaration decl, JavaContentAssistInvocationContext javaContext, LocationInformation info) {
int locationOffset = info.getOffset();
int locationLength = info.getLength();
boolean isQuoted = info.isQuoted();
List<JavaCompletionProposal> proposals = new ArrayList<JavaCompletionProposal>();
if (typeBinding != null) {
Set<String> matchingBeans = ProposalCalculatorUtil.getMatchingBeans(javaContext, typeBinding);
for (String matchingBean : matchingBeans) {
if (matchingBean.startsWith(filter)) {
if (isQuoted) {
proposals.add(new JavaCompletionProposal(matchingBean, locationOffset, locationLength,
BeansUIImages.getImage(BeansUIImages.IMG_OBJS_BEAN), matchingBean, 0));
}
else {
proposals.add(new JavaCompletionProposal("\"" + matchingBean + "\"", locationOffset,
locationLength, BeansUIImages.getImage(BeansUIImages.IMG_OBJS_BEAN), matchingBean, 0));
}
}
}
}
return proposals;
}
}