blob: 3a014d751965b1a9373ce73e1a5664649f5f8de3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Sonatype, 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
*******************************************************************************/
package org.eclipse.m2e.core.ui.internal.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.maven.project.MavenProject;
import org.eclipse.m2e.core.ui.internal.M2EUIPluginActivator;
import org.eclipse.m2e.core.ui.internal.search.util.CComboContentAdapter;
import org.eclipse.m2e.core.ui.internal.search.util.ControlDecoration;
import org.eclipse.m2e.core.ui.internal.search.util.Packaging;
import org.eclipse.m2e.core.ui.internal.search.util.SearchEngine;
/**
* Holds the proposal utility code, previously in the editor.xml plug-in. Provides proposal suggestions for text and
* combo widgets for various metadata (group, artifact, etc.)
*
* @author rgould
*/
public class ProposalUtil {
private static final Logger log = LoggerFactory.getLogger(ProposalUtil.class);
public static abstract class Searcher {
public abstract Collection<String> search() throws CoreException;
}
public static final class TextProposal implements IContentProposal {
private final String text;
public TextProposal(String text) {
this.text = text;
}
public int getCursorPosition() {
return text.length();
}
public String getContent() {
return text;
}
public String getLabel() {
return text;
}
public String getDescription() {
return null;
}
}
public static void addCompletionProposal(final Control control, final Searcher searcher) {
FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration(
FieldDecorationRegistry.DEC_CONTENT_PROPOSAL);
ControlDecoration decoration = new ControlDecoration(control, SWT.LEFT | SWT.TOP);
decoration.setShowOnlyOnFocus(true);
decoration.setDescriptionText(fieldDecoration.getDescription());
decoration.setImage(fieldDecoration.getImage());
IContentProposalProvider proposalProvider = (contents, position) -> {
final String start = contents.length() > position ? contents.substring(0, position) : contents;
ArrayList<IContentProposal> proposals = new ArrayList<IContentProposal>();
try {
for(final String text : searcher.search()) {
if(text.startsWith(start)) {
proposals.add(new TextProposal(text));
}
}
} catch(CoreException e) {
log.error(e.getMessage(), e);
}
return proposals.toArray(new IContentProposal[proposals.size()]);
};
IControlContentAdapter contentAdapter;
if(control instanceof Text) {
contentAdapter = new TextContentAdapter();
} else {
contentAdapter = new CComboContentAdapter();
}
ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter( //
control, contentAdapter, proposalProvider, //
IWorkbenchCommandConstants.EDIT_CONTENT_ASSIST, null);
// ContentProposalAdapter adapter = new ContentProposalAdapter(control, contentAdapter, //
// proposalProvider, KeyStroke.getInstance(SWT.MOD1, ' '), null);
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
adapter.setPopupSize(new Point(250, 120));
adapter.setPopupSize(new Point(250, 120));
}
public static void addClassifierProposal(final IProject project, final Text groupIdText, final Text artifactIdText,
final Text versionText, final Text classifierText, final Packaging packaging) {
addCompletionProposal(classifierText, new Searcher() {
public Collection<String> search() throws CoreException {
return getSearchEngine(project).findClassifiers(
escapeQuerySpecialCharacters(groupIdText.getText()), //
escapeQuerySpecialCharacters(artifactIdText.getText()),
escapeQuerySpecialCharacters(versionText.getText()), "", packaging);
}
});
}
public static void addVersionProposal(final IProject project, final MavenProject mp, final Text groupIdText,
final Text artifactIdText, final Text versionText, final Packaging packaging) {
addCompletionProposal(versionText, new Searcher() {
public Collection<String> search() throws CoreException {
Collection<String> toRet = new ArrayList<String>();
toRet.addAll(getSearchEngine(project).findVersions(escapeQuerySpecialCharacters(groupIdText.getText()), //
escapeQuerySpecialCharacters(artifactIdText.getText()), "", packaging));
if(mp != null) {
//add version props now..
Properties props = mp.getProperties();
ArrayList<String> list = new ArrayList<String>();
if(props != null) {
for(Object prop : props.keySet()) {
String propString = prop.toString();
if(propString.endsWith("Version") || propString.endsWith(".version")) { //$NON-NLS-1$//$NON-NLS-2$
list.add("${" + propString + "}"); //$NON-NLS-1$//$NON-NLS-2$
}
}
}
Collections.sort(list);
toRet.addAll(list);
}
return toRet;
}
});
}
public static void addArtifactIdProposal(final IProject project, final Text groupIdText, final Text artifactIdText,
final Packaging packaging) {
addCompletionProposal(artifactIdText, new Searcher() {
public Collection<String> search() throws CoreException {
// TODO handle artifact info
return getSearchEngine(project).findArtifactIds(escapeQuerySpecialCharacters(groupIdText.getText()), "",
packaging, null);
}
});
}
public static void addGroupIdProposal(final IProject project, final Text groupIdText, final Packaging packaging) {
addCompletionProposal(groupIdText, new Searcher() {
public Collection<String> search() throws CoreException {
// TODO handle artifact info
return getSearchEngine(project).findGroupIds(escapeQuerySpecialCharacters(groupIdText.getText()), packaging,
null);
}
});
}
//issue 350271
//http://lucene.apache.org/java/3_2_0/queryparsersyntax.html#Escaping Special Characters
//for proposal queries, any special chars shall be escaped
// + - && || ! ( ) { } [ ] ^ " ~ * ? : \
private static String escapeQuerySpecialCharacters(String raw) {
return QueryParser.escape(raw);
}
public static SearchEngine getSearchEngine(final IProject project) throws CoreException {
return M2EUIPluginActivator.getDefault().getSearchEngine(project);
}
}