/*******************************************************************************
* Copyright (c) 2007 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.seam.ui.actions;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jdt.ui.text.java.IProblemLocation;
import org.eclipse.jdt.ui.text.java.IQuickAssistProcessor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.search.internal.ui.Messages;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.part.FileEditorInput;
import org.jboss.tools.common.el.core.model.ELInvocationExpression;
import org.jboss.tools.seam.core.ISeamProject;
import org.jboss.tools.seam.core.SeamCorePlugin;
import org.jboss.tools.seam.core.SeamCoreMessages;
import org.jboss.tools.seam.internal.core.el.SeamELCompletionEngine;
import org.jboss.tools.seam.ui.SeamGuiPlugin;
import org.jboss.tools.seam.ui.SeamUiImages;
import org.jboss.tools.seam.ui.handlers.FindSeamDeclarationsHandler;
import org.jboss.tools.seam.ui.handlers.FindSeamReferencesHandler;
/**
* Quick Assist processor. Allows invokation of Find Seam Actions from QuickFix pop-up
* @author Jeremy
*/
public class SeamFindQuickAssistProcessor implements IQuickAssistProcessor {
/**
* Constructs SeamFind
*/
public SeamFindQuickAssistProcessor() {
}
/**
* @Override
*/
public boolean hasAssists(IInvocationContext context) throws CoreException {
ISeamProject seamProject = getSeamProject(context);
if (seamProject==null)
return false;
IDocument document = getDocument( context.getCompilationUnit() );
//TODO compute region start and end
int start = 0;
int end = document.getLength();
ASTNode node = context.getCoveringNode();
System.out.println("Covering node=" + node);
String[] varNames = getVariableNames(seamProject, document, context.getSelectionOffset(), start, end);
return (varNames != null && varNames.length != 0);
}
private ISeamProject getSeamProject(IInvocationContext context) {
ICompilationUnit cu = context.getCompilationUnit();
if (cu == null)
return null;
IResource javaFile = cu.getResource();
if (javaFile == null)
return null;
return SeamCorePlugin.getSeamProject(javaFile.getProject(), true);
}
private String[] getVariableNames(ISeamProject seamProject, IDocument document, int offset,
int start, int end) {
SeamELCompletionEngine engine = new SeamELCompletionEngine();
ELInvocationExpression tokens = engine.findExpressionAtOffset(
document, offset, start, end);
if (tokens == null)
return null;
return FindSeamAction.findVariableNames(seamProject,
document, tokens);
}
/**
* @Override
*/
public IJavaCompletionProposal[] getAssists(IInvocationContext context,
IProblemLocation[] locations) throws CoreException {
IJavaCompletionProposal[] result = new IJavaCompletionProposal[0];
if(!hasAssists( context )) return result;
IDocument document = getDocument( context.getCompilationUnit() );
try {
String contents = document.get( context.getSelectionOffset(), context.getSelectionLength() );
String searchString = "";
ISeamProject seamProject = getSeamProject(context);
if (seamProject == null)
return result;
ELInvocationExpression tokens = SeamELCompletionEngine.findExpressionAtOffset(
document,
context.getSelectionOffset(),
0, //TODO compute region start
document.getLength() //TODO compute region end
);
if (tokens == null /*|| tokens.size() == 0*/)
return result;
searchString = tokens.getText();
result = new IJavaCompletionProposal[2];
result[0] = new ExternalActionQuickAssistProposal(
contents,
SeamUiImages.getImage("find_seam_declarations.gif"),
Messages.format(
SeamCoreMessages.SeamQuickFixFindDeclarations,
new Object[] {searchString}),
context) {
public void apply(IDocument target) {
try {
new FindSeamDeclarationsHandler().execute(null);
} catch (ExecutionException e) {
SeamGuiPlugin.getPluginLog().logError(e);
}
}
};
result[1] = new ExternalActionQuickAssistProposal(
contents,
SeamUiImages.getImage("find_seam_references.gif"),
Messages.format(
SeamCoreMessages.SeamQuickFixFindReferences,
new Object[] {searchString}),
context) {
public void apply(IDocument target) {
try {
new FindSeamReferencesHandler().execute(null);
} catch (ExecutionException e) {
SeamGuiPlugin.getPluginLog().logError(e);
}
}
};
}
catch (BadLocationException e) {
SeamGuiPlugin.getPluginLog().logError( "Could not get document contents for Seam Find Quick Assist", e );
}
return result;
}
private IDocument getDocument(ICompilationUnit cu) throws JavaModelException {
IFile file= (IFile) cu.getResource();
IDocument document= JavaUI.getDocumentProvider().getDocument(new FileEditorInput(file));
if (document == null) {
return new Document(cu.getSource()); // only used by test cases
}
return document;
}
/**
* Custom Quick Assist Proposal
*/
public abstract class ExternalActionQuickAssistProposal implements
IJavaCompletionProposal {
private String contents;
private ICompletionProposal proposal;
public ExternalActionQuickAssistProposal(String contents, Image image, String description, IInvocationContext context) {
this.contents = contents;
proposal = new CompletionProposal("",context.getSelectionLength(),0,context.getSelectionOffset()+context.getSelectionLength(), image, description, null,null);
}
public String getContents() {
return contents;
}
public String getName() {
return null;
}
public int getRelevance() {
return 0;
}
abstract public void apply(IDocument document);
public String getAdditionalProposalInfo() {
return proposal.getAdditionalProposalInfo();
}
public IContextInformation getContextInformation() {
return proposal.getContextInformation();
}
public String getDisplayString() {
return proposal.getDisplayString();
}
public Image getImage() {
return proposal.getImage();
}
public Point getSelection(IDocument document) {
return proposal.getSelection( document );
}
}
}