/******************************************************************************* * Copyright (c) 2008-2010 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 * * Contributors: * Sonatype, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.m2e.core.ui.internal.dialogs; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.Parent; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginManagement; import org.apache.maven.project.MavenProject; import org.eclipse.m2e.core.embedder.ArtifactKey; import org.eclipse.m2e.core.internal.index.IIndex; import org.eclipse.m2e.core.internal.index.IndexedArtifact; import org.eclipse.m2e.core.internal.index.IndexedArtifactFile; import org.eclipse.m2e.core.ui.internal.M2EUIPluginActivator; import org.eclipse.m2e.core.ui.internal.Messages; import org.eclipse.m2e.core.ui.internal.search.util.Packaging; import org.eclipse.m2e.core.ui.internal.util.M2EUIUtils; import org.eclipse.m2e.core.ui.internal.util.ProposalUtil; import org.eclipse.m2e.core.ui.internal.wizards.MavenPomSelectionComponent; /** * Maven POM Search dialog * * @author Eugene Kuleshov */ public class MavenRepositorySearchDialog extends AbstractMavenDialog { private static final String DIALOG_SETTINGS = MavenRepositorySearchDialog.class.getName(); public static final String[] SCOPES = new String[] {"compile", "provided", "runtime", "test", "system"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ /* * dependencies under dependencyManagement are permitted to use an the extra "import" scope */ public static final String[] DEP_MANAGEMENT_SCOPES = new String[] {"compile", "provided", "runtime", "test", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "system", "import"}; //$NON-NLS-1$ //$NON-NLS-2$ /** * @param parent * @param title * @return */ public static MavenRepositorySearchDialog createOpenPomDialog(Shell parent, String title) { return new MavenRepositorySearchDialog(parent, title, IIndex.SEARCH_ARTIFACT, Collections.<ArtifactKey> emptySet(), Collections.<ArtifactKey, String> emptyMap(), false, null, null, false); } /** * @param parent * @param title * @param mp * @param p * @param inManagedSection true when the result will be added to the dependencyManagement section of the pom. * @return */ public static MavenRepositorySearchDialog createSearchDependencyDialog(Shell parent, String title, MavenProject mp, IProject p, boolean inManagedSection) { Set<ArtifactKey> artifacts = new HashSet<ArtifactKey>(); Map<ArtifactKey, String> managed = new HashMap<ArtifactKey, String>(); if(mp != null) { DependencyManagement dm = mp.getDependencyManagement(); if(dm != null && dm.getDependencies() != null) { for(Dependency dep : dm.getDependencies()) { ArtifactKey artifactKey = new ArtifactKey(dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), dep.getClassifier()); if(inManagedSection) { artifacts.add(artifactKey); } else { managed.put(artifactKey, dep.getType()); } } } if(!inManagedSection) { for(Dependency dep : mp.getModel().getDependencies()) { artifacts.add(new ArtifactKey(dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), dep.getClassifier())); } } } return new MavenRepositorySearchDialog(parent, title, IIndex.SEARCH_ARTIFACT, artifacts, managed, true, mp, p, true); } /** * @param parent * @param title * @param mp * @param p * @return */ public static MavenRepositorySearchDialog createSearchParentDialog(Shell parent, String title, MavenProject mp, IProject p) { Set<ArtifactKey> artifacts = new HashSet<ArtifactKey>(); Map<ArtifactKey, String> managed = new HashMap<ArtifactKey, String>(); if(mp != null && mp.getModel().getParent() != null) { Parent par = mp.getModel().getParent(); artifacts.add(new ArtifactKey(par.getGroupId(), par.getArtifactId(), par.getVersion(), null)); } return new MavenRepositorySearchDialog(parent, title, IIndex.SEARCH_PARENTS, artifacts, managed, false, mp, p, true); } /** * @param parent * @param title * @param mp * @param p * @param inManagedSection true when the result will be added to the dependencyManagement section of the pom. * @return */ public static MavenRepositorySearchDialog createSearchPluginDialog(Shell parent, String title, MavenProject mp, IProject p, boolean inManagedSection) { Set<ArtifactKey> artifacts = new HashSet<ArtifactKey>(); Map<ArtifactKey, String> managed = new HashMap<ArtifactKey, String>(); if(mp != null && mp.getBuild() != null) { PluginManagement pm = mp.getBuild().getPluginManagement(); if(pm != null && pm.getPlugins() != null) { for(Plugin plug : pm.getPlugins()) { ArtifactKey artifactKey = new ArtifactKey(plug.getGroupId(), plug.getArtifactId(), plug.getVersion(), null); if(inManagedSection) { artifacts.add(artifactKey); } else { managed.put(artifactKey, ""); //$NON-NLS-1$ } } } if(!inManagedSection && mp.getModel().getBuild() != null) { for(Plugin plug : mp.getModel().getBuild().getPlugins()) { artifacts.add(new ArtifactKey(plug.getGroupId(), plug.getArtifactId(), plug.getVersion(), null)); } } } return new MavenRepositorySearchDialog(parent, title, IIndex.SEARCH_PLUGIN, artifacts, managed, false, mp, p, true); } private final boolean showScope; private final Set<ArtifactKey> artifacts; /** * keys = artifact keys, values = type */ private final Map<ArtifactKey, String> managed; /** * One of {@link IIndex#SEARCH_ARTIFACT}, {@link IIndex#SEARCH_CLASS_NAME}, */ private final String queryType; private String queryText; MavenPomSelectionComponent pomSelectionComponent; private IndexedArtifact selectedIndexedArtifact; private IndexedArtifactFile selectedIndexedArtifactFile; private String selectedScope; private Combo comScope; private Text txtGroupId; private Text txtArtifactId; private Text txtVersion; private boolean ignoreTextChange = false; private IProject project; private MavenProject mavenproject; private final boolean showCoords; private MavenRepositorySearchDialog(Shell parent, String title, String queryType, Set<ArtifactKey> artifacts, Map<ArtifactKey, String> managed, boolean showScope, MavenProject mp, IProject p, boolean showCoordinates) { super(parent, DIALOG_SETTINGS); this.artifacts = artifacts; this.managed = managed; this.queryType = queryType; this.showScope = showScope; this.project = p; this.mavenproject = mp; this.showCoords = showCoordinates; setShellStyle(getShellStyle() | SWT.RESIZE); setStatusLineAboveButtons(true); setTitle(title); } public void setQuery(String query) { this.queryText = query; } protected Control createDialogArea(Composite parent) { readSettings(); Composite composite = (Composite) super.createDialogArea(parent); if(showCoords) { createGAVControls(composite); Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); } pomSelectionComponent = new MavenPomSelectionComponent(composite, SWT.NONE); pomSelectionComponent.init(queryText, queryType, project, artifacts, managed.keySet()); pomSelectionComponent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); pomSelectionComponent.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { if(!pomSelectionComponent.getStatus().matches(IStatus.ERROR)) { okPressedDelegate(); } } }); pomSelectionComponent.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateStatusDelegate(pomSelectionComponent.getStatus()); computeResultFromTree(); } }); pomSelectionComponent.setFocus(); return composite; } /** * Sets the up group-artifact-version controls */ private Composite createGAVControls(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); GridLayout gridLayout = new GridLayout(showScope ? 4 : 2, false); gridLayout.marginWidth = 0; gridLayout.horizontalSpacing = 10; composite.setLayout(gridLayout); Label groupIDlabel = new Label(composite, SWT.NONE); groupIDlabel.setText(Messages.AddDependencyDialog_groupId_label); txtGroupId = new Text(composite, SWT.BORDER); txtGroupId.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); M2EUIUtils.addRequiredDecoration(txtGroupId); if(showScope) { new Label(composite, SWT.NONE); new Label(composite, SWT.NONE); } Label artifactIDlabel = new Label(composite, SWT.NONE); artifactIDlabel.setText(Messages.AddDependencyDialog_artifactId_label); txtArtifactId = new Text(composite, SWT.BORDER); txtArtifactId.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); M2EUIUtils.addRequiredDecoration(txtArtifactId); if(showScope) { new Label(composite, SWT.NONE); new Label(composite, SWT.NONE); } Label versionLabel = new Label(composite, SWT.NONE); versionLabel.setText(Messages.AddDependencyDialog_version_label); txtVersion = new Text(composite, SWT.BORDER); txtVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); if(showScope) { Label scopeLabel = new Label(composite, SWT.NONE); scopeLabel.setText(Messages.AddDependencyDialog_scope_label); comScope = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY); comScope.setItems(SCOPES); GridData scopeListData = new GridData(SWT.LEFT, SWT.CENTER, false, false); comScope.setLayoutData(scopeListData); comScope.setText(SCOPES[0]); } if(showScope) { /* * Fix the tab order (group -> artifact -> version -> scope) */ composite.setTabList(new Control[] {txtGroupId, txtArtifactId, txtVersion, comScope}); } else { composite.setTabList(new Control[] {txtGroupId, txtArtifactId, txtVersion}); } Packaging pack; if(queryType.equals(IIndex.SEARCH_PARENTS)) { pack = Packaging.POM; } else if(queryType.equals(IIndex.SEARCH_PLUGIN)) { pack = Packaging.PLUGIN; } else { pack = Packaging.ALL; } ProposalUtil.addGroupIdProposal(project, txtGroupId, pack); ProposalUtil.addArtifactIdProposal(project, txtGroupId, txtArtifactId, pack); ProposalUtil.addVersionProposal(project, mavenproject, txtGroupId, txtArtifactId, txtVersion, pack); txtArtifactId.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { updateStatus(validateArtifactEntries()); if(!ignoreTextChange && !hasDisposedTextField()) { computeResultFromField(valueOrNull(txtGroupId.getText()), valueOrNull(txtArtifactId.getText()), valueOrNull(txtVersion.getText())); } } }); txtGroupId.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { updateStatus(validateArtifactEntries()); if(!ignoreTextChange && !hasDisposedTextField()) { computeResultFromField(valueOrNull(txtGroupId.getText()), valueOrNull(txtArtifactId.getText()), valueOrNull(txtVersion.getText())); } } }); txtVersion.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { if(!ignoreTextChange && !hasDisposedTextField()) { computeResultFromField(valueOrNull(txtGroupId.getText()), valueOrNull(txtArtifactId.getText()), valueOrNull(txtVersion.getText())); } } }); updateStatus(validateArtifactEntries()); return composite; } protected boolean hasDisposedTextField() { return txtGroupId.isDisposed() || txtArtifactId.isDisposed() || txtVersion.isDisposed(); } IStatus validateArtifactEntries() { if(!txtArtifactId.isDisposed() && txtArtifactId.getText().isEmpty()) return new Status(IStatus.ERROR, M2EUIPluginActivator.PLUGIN_ID, Messages.AddDependencyDialog_artifactId_error); if(!txtGroupId.isDisposed() && txtGroupId.getText().isEmpty()) return new Status(IStatus.ERROR, M2EUIPluginActivator.PLUGIN_ID, Messages.AddDependencyDialog_groupId_error); return new Status(IStatus.OK, M2EUIPluginActivator.PLUGIN_ID, "");//$NON-NLS-1$; } void okPressedDelegate() { okPressed(); } void updateStatusDelegate(IStatus status) { IStatus validationStatus = validateArtifactEntries(); if(validationStatus.isOK()) updateStatus(status); else updateStatus(validationStatus); } private String valueOrNull(String text) { return text.trim().length() == 0 ? null : text; } /* (non-Javadoc) * @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult() */ protected void computeResult() { if(showCoords) { computeResultFromField(valueOrNull(txtGroupId.getText()), valueOrNull(txtArtifactId.getText()), valueOrNull(txtVersion.getText())); } else { computeResultFromTree(); } } private void computeResultFromField(String groupId, String artifactId, String version) { selectedIndexedArtifact = cloneIndexedArtifact(selectedIndexedArtifact, groupId, artifactId); selectedIndexedArtifactFile = cloneIndexedArtifactFile(selectedIndexedArtifactFile, groupId, artifactId, version); selectedScope = comScope == null ? null : comScope.getText(); setResult(Collections.singletonList(selectedIndexedArtifactFile)); } private void computeResultFromTree() { if(pomSelectionComponent.isDisposed()) { return; } selectedIndexedArtifact = pomSelectionComponent.getIndexedArtifact(); selectedIndexedArtifactFile = pomSelectionComponent.getIndexedArtifactFile(); selectedScope = comScope == null ? null : comScope.getText(); setResult(Collections.singletonList(selectedIndexedArtifactFile)); if(selectedIndexedArtifactFile != null && showCoords) { ignoreTextChange = true; try { txtGroupId.setText(selectedIndexedArtifactFile.group); txtArtifactId.setText(selectedIndexedArtifactFile.artifact); String type = managed.get(new ArtifactKey(selectedIndexedArtifactFile.group, selectedIndexedArtifactFile.artifact, selectedIndexedArtifactFile.version, selectedIndexedArtifactFile.classifier)); if(type != null) { txtVersion.setText(""); //$NON-NLS-1$ // fix type (take from depMgmt instead of from pom), compare with https://bugs.eclipse.org/bugs/show_bug.cgi?id=473998 if(type.length() > 0) { selectedIndexedArtifactFile = cloneIndexedArtifactFile(selectedIndexedArtifactFile, type); } } else { txtVersion.setText(selectedIndexedArtifactFile.version); } } finally { ignoreTextChange = false; } } } public IndexedArtifact getSelectedIndexedArtifact() { return this.selectedIndexedArtifact; } public IndexedArtifactFile getSelectedIndexedArtifactFile() { return this.selectedIndexedArtifactFile; } public String getSelectedScope() { return this.selectedScope; } private IndexedArtifact cloneIndexedArtifact(IndexedArtifact old, String groupId, String artifactId) { if(old == null) { return new IndexedArtifact(groupId, artifactId, null, null, null); } return new IndexedArtifact(groupId != null ? groupId : old.getGroupId(), artifactId != null ? artifactId : old.getArtifactId(), old.getPackageName(), old.getClassname(), old.getPackaging()); } private IndexedArtifactFile cloneIndexedArtifactFile(IndexedArtifactFile old, String groupId, String artifactId, String version) { if(old == null) { return new IndexedArtifactFile(null, groupId, artifactId, version, null, null, null, 0L, null, 0, 0, null, null); } return new IndexedArtifactFile(old.repository, groupId, artifactId, version, old.type, old.classifier, old.fname, old.size, old.date, old.sourcesExists, old.javadocExists, old.prefix, old.goals); } private IndexedArtifactFile cloneIndexedArtifactFile(IndexedArtifactFile old, String type) { if(old == null) { throw new IllegalArgumentException("Must call with argument type != null"); //$NON-NLS-1$ } return new IndexedArtifactFile(old.repository, old.group, old.artifact, old.version, type, old.classifier, old.fname, old.size, old.date, old.sourcesExists, old.javadocExists, old.prefix, old.goals); } }