/******************************************************************************* * Copyright (c) 2013 Pivotal Software, 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: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package org.springsource.ide.eclipse.commons.completions.externaltype; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.CompletionProposal; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer; import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContextInformation; import org.springsource.ide.eclipse.commons.completions.CompletionsActivator; import org.springsource.ide.eclipse.commons.completions.externaltype.indexing.ExternalTypeIndexer; import org.springsource.ide.eclipse.commons.completions.util.Requestor; /** * Computes content assist proposals based on set of known types taken from a set of jars. * * @author Kris De Volder */ public class ExternalTypesProposalComputer implements IJavaCompletionProposalComputer { private static final boolean DEBUG = false;// (""+Platform.getLocation()).contains("kdvolder"); private void debug(String string) { if (DEBUG) { System.out.println(string); } } private static final List<IContextInformation> NO_CONTEXTS = Arrays.asList(new IContextInformation[0]); private static final List<ICompletionProposal> NO_PROPOSALS = Arrays.asList(new ICompletionProposal[0]); public ExternalTypesProposalComputer() { } @Override public void sessionStarted() { debug("sessionStarted"); } @Override public String getErrorMessage() { return null; } @Override public void sessionEnded() { debug("sessionEnded"); } @Override public List<ICompletionProposal> computeCompletionProposals(ContentAssistInvocationContext _context, IProgressMonitor monitor) { if (_context instanceof JavaContentAssistInvocationContext) { final JavaContentAssistInvocationContext context = (JavaContentAssistInvocationContext) _context; try { final String idPrefix = context.computeIdentifierPrefix().toString(); //System.out.println("IdPrefix = "+idPrefix); //Only compute proposals if we actually have something to look for. This avoids adding our suggestions // for completions like 'foo.^". if (idPrefix!=null && !"".equals(idPrefix)) { final ArrayList<ICompletionProposal> completions = new ArrayList<ICompletionProposal>(); final ExternalTypeIndexer index = ExternalTypeIndexManager.indexFor(context.getProject()); index.getByPrefix(idPrefix, new Requestor<ExternalType>() { public boolean receive(ExternalType type) { //TODO: limit number of results. If there's too many user can't look // at all of them anyway. try { if (type.getName().startsWith(idPrefix)) { IJavaProject project = context.getProject(); if (project.findType(type.getFullyQualifiedName())==null) { CompletionProposal proposal = CompletionProposal.create(CompletionProposal.TYPE_REF, context.getInvocationOffset()); proposal.setCompletion(type.getFullyQualifiedName().toCharArray()); proposal.setDeclarationSignature(type.getPackage().toCharArray()); proposal.setFlags(Flags.AccPublic); //TODO: This is some kind of bit mask and it should be derived from the type information. //proposal.setRelevance(relevance); proposal.setReplaceRange(context.getInvocationOffset()-idPrefix.length(), context.getInvocationOffset()); proposal.setSignature(Signature.createTypeSignature(type.getFullyQualifiedName(), true).toCharArray()); completions.add(new ExternalTypeCompletionProposal(proposal, context, type, index)); } } } catch (Exception e) { CompletionsActivator.log(e); } return true; } }); return completions; } } catch (Exception e) { CompletionsActivator.log(e); } } return NO_PROPOSALS; } @Override public List<IContextInformation> computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { //This doesn't seem to get called so it doesn't really matter what we put in here. return NO_CONTEXTS; } }