diff options
| author | Matthew Piggott | 2011-03-02 22:29:27 +0000 |
|---|---|---|
| committer | Pascal Rapicault | 2011-03-03 21:35:21 +0000 |
| commit | d72dde2c91da6d04a18455e291adc804b87dbdee (patch) | |
| tree | 8be728149105ed3f8d0dfd4de688a2d97bf78e84 | |
| parent | 98b50bf774feaad18250c77c2f8ab904e048ff2e (diff) | |
| download | m2e-core-d72dde2c91da6d04a18455e291adc804b87dbdee.tar.gz m2e-core-d72dde2c91da6d04a18455e291adc804b87dbdee.tar.xz m2e-core-d72dde2c91da6d04a18455e291adc804b87dbdee.zip | |
bug 337565 - Exclude Refactoring Issues
9 files changed, 730 insertions, 169 deletions
diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/editing/AddDependencyOperation.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/editing/AddDependencyOperation.java new file mode 100644 index 00000000..f6d003b4 --- /dev/null +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/editing/AddDependencyOperation.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2011 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.editing; + +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.ARTIFACT_ID; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCIES; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.GROUP_ID; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.VERSION; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.createElementWithText; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.format; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getChild; + +import org.apache.maven.model.Dependency; +import org.eclipse.m2e.core.ui.internal.editing.PomEdits.Operation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class AddDependencyOperation implements Operation { + + private Dependency dependency; + + public AddDependencyOperation(Dependency dependency) { + this.dependency = dependency; + } + + /* (non-Javadoc) + * @see org.eclipse.m2e.core.ui.internal.editing.PomEdits.Operation#process(org.w3c.dom.Document) + */ + public void process(Document document) { + Element dependencyElement = PomHelper.findDependency(document, dependency); + if(dependencyElement == null) { + Element dependencies = getChild(document.getDocumentElement(), DEPENDENCIES); + + // TODO Handle managed dependencies? + dependencyElement = PomEdits.createElement(dependencies, DEPENDENCY); + createElementWithText(dependencyElement, ARTIFACT_ID, dependency.getArtifactId()); + createElementWithText(dependencyElement, GROUP_ID, dependency.getGroupId()); + createElementWithText(dependencyElement, VERSION, dependency.getVersion()); + format(dependencyElement); + } + // find existing + } +} diff --git a/org.eclipse.m2e.editor/src/org/eclipse/m2e/editor/composites/PomHierarchyComposite.java b/org.eclipse.m2e.editor/src/org/eclipse/m2e/editor/composites/PomHierarchyComposite.java new file mode 100644 index 00000000..ef88813e --- /dev/null +++ b/org.eclipse.m2e.editor/src/org/eclipse/m2e/editor/composites/PomHierarchyComposite.java @@ -0,0 +1,233 @@ + +package org.eclipse.m2e.editor.composites; + +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +import org.apache.maven.project.MavenProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IInputSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class PomHierarchyComposite extends Composite implements IInputSelectionProvider { + private static final Logger LOG = LoggerFactory.getLogger(PomHierarchyComposite.class); + + private TreeViewer pomsViewer; + + private List<MavenProject> hierarchy; + + public PomHierarchyComposite(Composite parent, int style) { + super(parent, style); + build(); + } + + private void build() { + setLayout(new FillLayout(SWT.HORIZONTAL)); + pomsViewer = new TreeViewer(this, SWT.NULL); + pomsViewer.setLabelProvider(new DepLabelProvider()); + pomsViewer.setContentProvider(new PomHeirarchyContentProvider()); + } + + public void setEnabled(boolean bool) { + pomsViewer.getTree().setEnabled(bool); + super.setEnabled(bool); + } + + public void computeHeirarchy(final IMavenProjectFacade project, IRunnableContext context) { + try { + if(context != null) { + context.run(false, true, new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try { + computeHeirarchy(project, monitor); + } catch(CoreException e) { + throw new InvocationTargetException(e); + } + } + }); + } else { + computeHeirarchy(project, new NullProgressMonitor()); + } + } catch(Exception e) { + LOG.error("An error occurred building pom heirarchy", e); + } + } + + private void computeHeirarchy(IMavenProjectFacade projectFacade, IProgressMonitor monitor) throws CoreException { + LinkedList<MavenProject> hierarchy = new LinkedList<MavenProject>(); + hierarchy.addAll(new ParentGatherer(projectFacade.getMavenProject(), projectFacade).getParentHierarchy(monitor)); + setHierarchy(hierarchy); + } + + public void setHierarchy(LinkedList<MavenProject> hierarchy) { + this.hierarchy = hierarchy; + pomsViewer.setInput(hierarchy); + pomsViewer.expandAll(); + } + + public static class DepLabelProvider extends LabelProvider implements IColorProvider { + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + MavenProject project = null; + if(element instanceof MavenProject) { + project = (MavenProject) element; + } else if(element instanceof Object[]) { + project = (MavenProject) ((Object[]) element)[0]; + } else { + return ""; //$NON-NLS-1$ + } + StringBuffer buffer = new StringBuffer(); + buffer.append(project.getGroupId() + " : " + project.getArtifactId() + " : " + project.getVersion()); //$NON-NLS-1$ //$NON-NLS-2$ + return buffer.toString(); + } + + public Color getForeground(Object element) { + if(element instanceof MavenProject) { + MavenProject project = (MavenProject) element; + IMavenProjectFacade search = MavenPlugin.getDefault().getMavenProjectManager() + .getMavenProject(project.getGroupId(), project.getArtifactId(), project.getVersion()); + if(search == null) { + // This project is not in the workspace + return Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY); + } + } + return null; + } + + public Color getBackground(Object element) { + return null; + } + } + + public static class PomHeirarchyContentProvider implements ITreeContentProvider { + private LinkedList<MavenProject> projects; + + public PomHeirarchyContentProvider() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if(newInput instanceof LinkedList) { + this.projects = (LinkedList<MavenProject>) newInput; + } + } + + public void dispose() { + } + + public boolean hasChildren(Object element) { + Object[] children = getChildren(element); + + return children.length != 0; + } + + public Object getParent(Object element) { + if(element instanceof MavenProject) { + MavenProject project = (MavenProject) element; + return project.getParent(); + } + return null; + } + + /* + * Return root element (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang + * .Object) + */ + public Object[] getElements(Object inputElement) { + + if(inputElement instanceof LinkedList) { + LinkedList<MavenProject> projects = (LinkedList<MavenProject>) inputElement; + if(projects.isEmpty()) { + return new Object[0]; + } + return new Object[] {projects.getLast()}; + } + return new Object[0]; + } + + public Object[] getChildren(Object parentElement) { + if(parentElement instanceof MavenProject) { + /* + * Walk the hierarchy list until we find the parentElement and + * return the previous element, which is the child. + */ + MavenProject parent = (MavenProject) parentElement; + + if(projects.size() == 1) { + // No parent exists, only one element in the tree + return new Object[0]; + } + + if(projects.getFirst().equals(parent)) { + // We are the final child + return new Object[0]; + } + + ListIterator<MavenProject> iter = projects.listIterator(); + while(iter.hasNext()) { + MavenProject next = iter.next(); + if(next.equals(parent)) { + iter.previous(); + MavenProject previous = iter.previous(); + return new Object[] {previous}; + } + } + } + return new Object[0]; + } + } + + public void addSelectionChangedListener(ISelectionChangedListener listener) { + pomsViewer.addSelectionChangedListener(listener); + } + + public Object getInput() { + return pomsViewer.getInput(); + } + + public ISelection getSelection() { + return pomsViewer.getSelection(); + } + + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + pomsViewer.removeSelectionChangedListener(listener); + } + + public void setSelection(ISelection selection) { + pomsViewer.setSelection(selection); + } + + public List<MavenProject> getHierarchy() { + return hierarchy; + } +} diff --git a/org.eclipse.m2e.editor/src/org/eclipse/m2e/editor/dialogs/ManageDependenciesDialog.java b/org.eclipse.m2e.editor/src/org/eclipse/m2e/editor/dialogs/ManageDependenciesDialog.java index 2d192f90..e9e3a4b4 100644 --- a/org.eclipse.m2e.editor/src/org/eclipse/m2e/editor/dialogs/ManageDependenciesDialog.java +++ b/org.eclipse.m2e.editor/src/org/eclipse/m2e/editor/dialogs/ManageDependenciesDialog.java @@ -8,7 +8,18 @@ package org.eclipse.m2e.editor.dialogs; -import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.*; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.ARTIFACT_ID; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCIES; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY_MANAGEMENT; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.GROUP_ID; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.VERSION; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChild; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChilds; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getChild; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getTextValue; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.performOnDOMDocument; +import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.removeChild; import java.util.ArrayList; import java.util.Iterator; @@ -31,7 +42,6 @@ import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.project.IMavenProjectFacade; @@ -43,6 +53,7 @@ import org.eclipse.m2e.core.ui.internal.editing.PomHelper; import org.eclipse.m2e.editor.MavenEditorPlugin; import org.eclipse.m2e.editor.composites.DependencyLabelProvider; import org.eclipse.m2e.editor.composites.ListEditorContentProvider; +import org.eclipse.m2e.editor.composites.PomHierarchyComposite; import org.eclipse.m2e.model.edit.pom.Dependency; import org.eclipse.m2e.model.edit.pom.Model; import org.eclipse.osgi.util.NLS; @@ -60,7 +71,6 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Tree; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -79,12 +89,11 @@ public class ManageDependenciesDialog extends AbstractMavenDialog { private TableViewer dependenciesViewer; - private TreeViewer pomsViewer; - private final Model model; private final LinkedList<MavenProject> projectHierarchy; + private PomHierarchyComposite pomHierarchy; private IStatus status; @@ -145,7 +154,9 @@ public class ManageDependenciesDialog extends AbstractMavenDialog { Label selectPomLabel = new Label(pomComposite, SWT.NONE); selectPomLabel.setText(Messages.ManageDependenciesDialog_selectPOMLabel); - Tree pomTree = new Tree(pomComposite, SWT.BORDER); + pomHierarchy = new PomHierarchyComposite(pomComposite, SWT.BORDER); + pomHierarchy.setHierarchy(getProjectHierarchy()); + // pomsViewer = new TreeViewer(pomComposite, SWT.BORDER); /* * Configure layouts @@ -186,7 +197,8 @@ public class ManageDependenciesDialog extends AbstractMavenDialog { selectPomLabel.setLayoutData(gridData); gridData = new GridData(SWT.FILL, SWT.FILL, true, true); - pomTree.setLayoutData(gridData); + pomHierarchy.setLayoutData(gridData); + //pomsViewer.getTree().setLayoutData(gridData); /* * Set up list/tree viewers @@ -208,16 +220,9 @@ public class ManageDependenciesDialog extends AbstractMavenDialog { dependenciesViewer.setInput(nonManaged); dependenciesViewer.addSelectionChangedListener(new DependenciesViewerSelectionListener()); - pomsViewer = new TreeViewer(pomTree); - - pomsViewer.setLabelProvider(new DepLabelProvider()); - - pomsViewer.setContentProvider(new ContentProvider()); - pomsViewer.setInput(getProjectHierarchy()); - pomsViewer.addSelectionChangedListener(new PomViewerSelectionChangedListener()); - pomsViewer.expandAll(); + pomHierarchy.addSelectionChangedListener(new PomViewerSelectionChangedListener()); if(getProjectHierarchy().size() > 0) { - pomsViewer.setSelection(new StructuredSelection(getProjectHierarchy().getLast())); + pomHierarchy.setSelection(new StructuredSelection(getProjectHierarchy().getLast())); } if(originalSelection != null && originalSelection.size() > 0) { @@ -341,7 +346,7 @@ public class ManageDependenciesDialog extends AbstractMavenDialog { } protected MavenProject getTargetPOM() { - IStructuredSelection selection = (IStructuredSelection) pomsViewer.getSelection(); + IStructuredSelection selection = (IStructuredSelection) pomHierarchy.getSelection(); return (MavenProject) selection.getFirstElement(); } diff --git a/org.eclipse.m2e.refactoring/META-INF/MANIFEST.MF b/org.eclipse.m2e.refactoring/META-INF/MANIFEST.MF index 707bb2cd..19079578 100644 --- a/org.eclipse.m2e.refactoring/META-INF/MANIFEST.MF +++ b/org.eclipse.m2e.refactoring/META-INF/MANIFEST.MF @@ -26,6 +26,7 @@ Eclipse-LazyStart: true Bundle-RequiredExecutionEnvironment: J2SE-1.5, JavaSE-1.6 Export-Package: org.eclipse.m2e.refactoring.exclude;x-internal="true" -Import-Package: org.eclipse.m2e.editor.pom, +Import-Package: org.eclipse.m2e.editor.composites, + org.eclipse.m2e.editor.pom, org.eclipse.search.ui.text, org.eclipse.ui.forms.editor diff --git a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/AbstractPomHeirarchyRefactoring.java b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/AbstractPomHeirarchyRefactoring.java index ff6e712c..0cad657c 100644 --- a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/AbstractPomHeirarchyRefactoring.java +++ b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/AbstractPomHeirarchyRefactoring.java @@ -49,6 +49,10 @@ public abstract class AbstractPomHeirarchyRefactoring extends Refactoring { this.file = file; } + public IMavenProjectFacade getProjectFacade() { + return getMavenProjectFacade(file); + } + /* * Called to notify checkInitialConditions has been called. Should be used to reset state not perform calculations */ diff --git a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/DependencyExcludeAction.java b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/DependencyExcludeAction.java index 490aabc5..fbbd5fa4 100644 --- a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/DependencyExcludeAction.java +++ b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/DependencyExcludeAction.java @@ -48,7 +48,7 @@ public class DependencyExcludeAction implements IActionDelegate { public void run(IAction action) { if(keys != null && file != null) { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); - ExcludeArtifactRefactoring r = new ExcludeArtifactRefactoring(keys, file); + ExcludeArtifactRefactoring r = new ExcludeArtifactRefactoring(file, keys); MavenExcludeWizard wizard = new MavenExcludeWizard(r); try { String titleForFailedChecks = ""; //$NON-NLS-1$ diff --git a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/ExcludeArtifactRefactoring.java b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/ExcludeArtifactRefactoring.java index c25cdfc8..0d61efd7 100644 --- a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/ExcludeArtifactRefactoring.java +++ b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/ExcludeArtifactRefactoring.java @@ -11,6 +11,7 @@ package org.eclipse.m2e.refactoring.exclude; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -21,25 +22,28 @@ import java.util.Set; import org.apache.maven.model.Dependency; import org.apache.maven.project.MavenProject; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.Refactoring; import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; import org.eclipse.m2e.core.MavenPlugin; -import org.eclipse.m2e.core.core.IMavenConstants; import org.eclipse.m2e.core.embedder.ArtifactKey; -import org.eclipse.m2e.core.embedder.MavenModelManager; import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.core.ui.internal.editing.AddDependencyOperation; import org.eclipse.m2e.core.ui.internal.editing.AddExclusionOperation; import org.eclipse.m2e.core.ui.internal.editing.PomEdits.CompoundOperation; import org.eclipse.m2e.core.ui.internal.editing.PomEdits.Operation; import org.eclipse.m2e.core.ui.internal.editing.PomHelper; import org.eclipse.m2e.core.ui.internal.editing.RemoveDependencyOperation; -import org.eclipse.m2e.refactoring.AbstractPomHeirarchyRefactoring; import org.eclipse.m2e.refactoring.Messages; import org.eclipse.osgi.util.NLS; import org.sonatype.aether.artifact.Artifact; @@ -48,203 +52,316 @@ import org.sonatype.aether.graph.DependencyVisitor; import org.sonatype.aether.util.artifact.JavaScopes; -public class ExcludeArtifactRefactoring extends AbstractPomHeirarchyRefactoring { +public class ExcludeArtifactRefactoring extends Refactoring { - private final ArtifactKey[] keys; + private ArtifactKey[] keys; - private Map<ArtifactKey, Boolean> locatedKeys; + private IFile pomFile; - private Map<IFile, Change> operationMap; + private MavenProject exclusionPoint; - public ExcludeArtifactRefactoring(ArtifactKey[] keys, IFile pom) { - super(pom); + private List<MavenProject> hierarchy; + + private Set<ArtifactKey> locatedKeys; + + public ExcludeArtifactRefactoring(IFile pomFile, ArtifactKey[] keys) { + this.pomFile = pomFile; this.keys = keys; } + public void setExclusionPoint(MavenProject exclusionPoint) { + this.exclusionPoint = exclusionPoint; + } + + public void setHierarchy(List<MavenProject> hierarchy) { + this.hierarchy = hierarchy; + } + + public IMavenProjectFacade getSource() { + return getMavenProjectFacade(pomFile); + } + + protected IMavenProjectFacade getMavenProjectFacade(IFile pom) { + return MavenPlugin.getDefault().getMavenProjectManager().create(pom, true, new NullProgressMonitor()); + } + + protected IMavenProjectFacade getMavenProjectFacade(MavenProject mavenProject) { + return MavenPlugin.getDefault().getMavenProjectManager() + .getMavenProject(mavenProject.getGroupId(), mavenProject.getArtifactId(), mavenProject.getVersion()); + } + /* (non-Javadoc) * @see org.eclipse.ltk.core.refactoring.Refactoring#getName() */ public String getName() { - StringBuilder builder = new StringBuilder(); + StringBuilder sb = new StringBuilder(); + sb.append("Exclude: "); for(ArtifactKey key : keys) { - builder.append(key.toString()).append(", "); + sb.append(key.toString()).append(','); + } + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor) + */ + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { + exclusionPoint = getMavenProjectFacade(pomFile).getMavenProject(pm); + if(exclusionPoint == null) { + return RefactoringStatus + .createFatalErrorStatus("MavenProject does not exist, try cleaning workspace & rebuilding"); } - builder.delete(builder.length() - 2, builder.length()); - return NLS.bind(Messages.ExcludeArtifactRefactoring_refactoringName, builder.toString()); + return new RefactoringStatus(); } + private List<Change> changes; + /* (non-Javadoc) - * @see org.eclipse.m2e.refactoring.exclude.AbstractRefactoring#isReady(org.eclipse.core.runtime.IProgressMonitor) + * @see org.eclipse.ltk.core.refactoring.Refactoring#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor) */ - protected RefactoringStatusEntry[] isReady(IProgressMonitor pm) { - if(keys == null || keys.length == 0) { - return new RefactoringStatusEntry[] {new RefactoringStatusEntry(RefactoringStatus.FATAL, - Messages.ExcludeArtifactRefactoring_noArtifactsSet)}; - } - if(locatedKeys.isEmpty()) { - return new RefactoringStatusEntry[] {new RefactoringStatusEntry(RefactoringStatus.FATAL, - Messages.ExcludeArtifactRefactoring_failedToLocateAnyArtifacts)}; - } - List<RefactoringStatusEntry> entries = new ArrayList<RefactoringStatusEntry>(); - for (ArtifactKey key : keys) { - if(!locatedKeys.containsKey(key)) { - entries.add(new RefactoringStatusEntry(RefactoringStatus.INFO, NLS.bind( - Messages.ExcludeArtifactRefactoring_failedToLocateArtifact, key.toString()))); + public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { + changes = new ArrayList<Change>(); + locatedKeys = new HashSet<ArtifactKey>(); + List<IStatus> statuses = new ArrayList<IStatus>(); + SubMonitor monitor = SubMonitor.convert(pm, getHierarchy().size()); + + List<Operation> exclusionOp = new ArrayList<Operation>(); + // Exclusion point + Visitor visitor = locate(exclusionPoint, monitor.newChild(1)); + for(Entry<Dependency, Set<ArtifactKey>> entry : visitor.getSourceMap().entrySet()) { + exclusionPoint.getOriginalModel().getDependencies(); + locatedKeys.addAll(entry.getValue()); + if(contains(entry.getValue(), entry.getKey())) { + exclusionOp.add(new RemoveDependencyOperation(entry.getKey())); + } else { + for(ArtifactKey key : entry.getValue()) { + exclusionOp.add(new AddExclusionOperation(entry.getKey(), key)); + } + } + } + + // Below exclusion point - pull up dependency to exclusion point + for(MavenProject project : getDescendants()) { + visitor = locate(project, monitor.newChild(1)); + for(Entry<Dependency, Set<ArtifactKey>> entry : visitor.getSourceMap().entrySet()) { + locatedKeys.addAll(entry.getValue()); + if(contains(entry.getValue(), entry.getKey())) { + changes.add(PomHelper.createChange(getFile(project), new RemoveDependencyOperation(entry.getKey()), + "Remove dependency {0}")); + } else { + CompositeChange change = new CompositeChange("Move dependency {0}"); + change.add(PomHelper.createChange(getFile(project), new RemoveDependencyOperation(entry.getKey()), + "Remove dependency {0}")); + exclusionOp.add(new AddDependencyOperation(entry.getKey())); + for(ArtifactKey key : entry.getValue()) { + exclusionOp.add(new AddExclusionOperation(entry.getKey(), key)); + } + } + } + if(!visitor.getStatus().isOK()) { + statuses.add(visitor.getStatus()); } } - for(Entry<ArtifactKey, Boolean> entry : locatedKeys.entrySet()) { - if(entry.getValue()) { - entries.add(new RefactoringStatusEntry(RefactoringStatus.INFO, NLS.bind( - Messages.ExcludeArtifactRefactoring_transitiveDependency, entry.getKey().toString()))); + + // Above exclusion - Add dep to exclusionPoint + for(MavenProject project : getAncestors()) { + visitor = locate(project, monitor.newChild(1)); + for(Entry<Dependency, Set<ArtifactKey>> entry : locate(project, monitor.newChild(1)).getSourceMap().entrySet()) { + locatedKeys.addAll(entry.getValue()); + if(contains(entry.getValue(), entry.getKey())) { + if(project.getFile() != null) { + changes.add(PomHelper.createChange(getFile(project), new RemoveDependencyOperation(entry.getKey()), + "Remove dependency {0}")); + } + } else { + exclusionOp.add(new AddDependencyOperation(entry.getKey())); + for(ArtifactKey key : entry.getValue()) { + exclusionOp.add(new AddExclusionOperation(entry.getKey(), key)); + } + } } + if(!visitor.getStatus().isOK()) { + statuses.add(visitor.getStatus()); + } + } + changes.add(PomHelper.createChange(getFile(exclusionPoint), + new CompoundOperation(exclusionOp.toArray(new Operation[exclusionOp.size()])), getName())); + + if(statuses.size() == 1) { + return RefactoringStatus.create(statuses.get(0)); + } else if(statuses.size() > 1) { + return RefactoringStatus.create(new MultiStatus("org.eclipse.m2e.refactoring", 0, statuses + .toArray(new IStatus[statuses.size()]), "Errors occurred creating refactoring", null)); + } else if(locatedKeys.isEmpty()) { + return RefactoringStatus.createFatalErrorStatus(Messages.AbstractPomHeirarchyRefactoring_noTargets); + } else if(locatedKeys.size() != keys.length) { + StringBuilder sb = new StringBuilder(); + for(ArtifactKey key : keys) { + if(!locatedKeys.contains(key)) { + sb.append(key.toString()).append(','); + } + } + sb.deleteCharAt(sb.length() - 1); + return RefactoringStatus.createErrorStatus(NLS.bind(Messages.ExcludeArtifactRefactoring_failedToLocateArtifact, + sb.toString())); } - return entries.toArray(new RefactoringStatusEntry[entries.size()]); + return new RefactoringStatus(); } - /* (non-Javadoc) - * @see org.eclipse.m2e.refactoring.AbstractRefactoring#getChange(org.apache.maven.project.MavenProject, org.eclipse.core.runtime.IProgressMonitor) - */ - protected Change getChange(IFile file, IProgressMonitor pm) { - return operationMap.get(file); + private Visitor locate(MavenProject project, IProgressMonitor monitor) throws CoreException { + DependencyNode root = MavenPlugin.getDefault().getMavenModelManager() + .readDependencyTree(project, JavaScopes.TEST, monitor); + Visitor visitor = new Visitor(project); + root.accept(visitor); + return visitor; } /* (non-Javadoc) - * @see org.eclipse.m2e.refactoring.AbstractPomHeirarchyRefactoring#checkInitial(org.eclipse.core.runtime.IProgressMonitor) + * @see org.eclipse.ltk.core.refactoring.Refactoring#createChange(org.eclipse.core.runtime.IProgressMonitor) */ - protected void checkInitial(IProgressMonitor pm) { - locatedKeys = new HashMap<ArtifactKey, Boolean>(keys.length); - operationMap = new HashMap<IFile, Change>(); + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + CompositeChange change = new CompositeChange(getName()); + change.addAll(changes.toArray(new Change[changes.size()])); + return change; } - /* (non-Javadoc) - * @see org.eclipse.m2e.refactoring.AbstractPomHeirarchyRefactoring#checkFinal(org.eclipse.core.runtime.IProgressMonitor) - */ - protected void checkFinal(IProgressMonitor pm) { - // Do nothing + private static boolean matches(Dependency d, ArtifactKey a) { + return d.getArtifactId().equals(a.getArtifactId()) && d.getGroupId().equals(a.getGroupId()); } - /* (non-Javadoc) - * @see org.eclipse.m2e.refactoring.AbstractPomHeirarchyRefactoring#isAffected(org.eclipse.m2e.core.project.IMavenProjectFacade, org.eclipse.core.runtime.IProgressMonitor) - */ - protected boolean isAffected(IFile pomFile, IProgressMonitor progressMonitor) throws CoreException { + private static boolean contains(Set<ArtifactKey> keys, Dependency d) { + for(ArtifactKey key : keys) { + if(matches(d, key)) { + return true; + } + } + return false; + } - final SubMonitor monitor = SubMonitor.convert(progressMonitor); - final IStatus[] status = new IStatus[1]; + private Collection<MavenProject> getHierarchy() { + return hierarchy; + } - final IMavenProjectFacade facade = MavenPlugin.getDefault().getMavenProjectManagerImpl() - .create(pomFile, true, monitor); - final MavenProject project = facade.getMavenProject(progressMonitor); - final org.apache.maven.model.Model m = project.getModel(); + private IFile getFile(MavenProject project) { + IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(project.getFile().toURI()); + if(files.length == 0) { + // TODO something + return null; + } else { + return files[0]; + } + } - final List<Operation> operations = new ArrayList<Operation>(); + private Collection<MavenProject> getDescendants() { + List<MavenProject> descendants = new ArrayList<MavenProject>(); + boolean add = true; + for(MavenProject project : getHierarchy()) { + if(project == exclusionPoint) { + add = !add; + } else if(add) { + descendants.add(project); + } + } + return descendants; + } - final StringBuilder msg = new StringBuilder(); - final List<org.apache.maven.model.Dependency> dependencies = m.getDependencies(); - final Map<Dependency, Set<ArtifactKey>> toAdd = new HashMap<Dependency, Set<ArtifactKey>>(); + private Collection<MavenProject> getAncestors() { + List<MavenProject> ancestors = new ArrayList<MavenProject>(); + boolean add = false; + for(MavenProject project : getHierarchy()) { + if(project == exclusionPoint) { + add = !add; + } else if(add) { + ancestors.add(project); + } + } + return ancestors; + } - MavenModelManager modelManager = MavenPlugin.getDefault().getMavenModelManager(); - DependencyNode root = modelManager.readDependencyTree(project, JavaScopes.TEST, monitor.newChild(1)); - root.accept(new DependencyVisitor() { + private class Visitor implements DependencyVisitor { + private List<IStatus> statuses = new ArrayList<IStatus>(); - private int depth; + private List<Dependency> dependencies; - private DependencyNode topLevel; + private Map<Dependency, Set<ArtifactKey>> sourceMap = new HashMap<Dependency, Set<ArtifactKey>>(); - private int exclusionDepth = -1; + Visitor(MavenProject project) { + dependencies = project.getOriginalModel().getDependencies(); + } - public boolean visitLeave(DependencyNode node) { - depth-- ; - if(depth <= exclusionDepth) { - exclusionDepth = -1; - } - return status[0] == null; + IStatus getStatus() { + if(statuses.isEmpty()) { + return Status.OK_STATUS; } + return new MultiStatus("org.eclipse.m2e.refactoring", 0, statuses.toArray(new IStatus[statuses.size()]), + "Errors occurred", null); + } - public boolean visitEnter(DependencyNode node) { - if(depth == 1) { - topLevel = node; - } - depth++ ; - - if(node.getDependency() != null) { - Artifact a = node.getDependency().getArtifact(); - for(ArtifactKey key : keys) { - if(a.getGroupId().equals(key.getGroupId()) && a.getArtifactId().equals(key.getArtifactId())) { - if(topLevel == null) { - // do not touch itself - } else if(node == topLevel) { - msg.append(key.toString()).append(','); - // need to remove top-level dependency - operations.add(new RemoveDependencyOperation(findDependency(topLevel))); - locatedKeys.put(key, Boolean.FALSE); - } else { - // need to add exclusion to top-level dependency - Dependency dependency = findDependency(topLevel); - if(dependency == null) { - status[0] = new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, NLS.bind( - Messages.ExcludeRefactoring_error_parent, topLevel.getDependency().getArtifact().getGroupId(), - topLevel.getDependency().getArtifact().getArtifactId())); - } else if(exclusionDepth == -1) { - // Used to avoid errors for transitive dependencies of excluded dependencies. - Set<ArtifactKey> keys = toAdd.get(dependency); - if(keys == null) { - keys = new HashSet<ArtifactKey>(); - toAdd.put(dependency, keys); - } - keys.add(key); - exclusionDepth = depth; - locatedKeys.put(key, Boolean.FALSE); - } else { - locatedKeys.put(key, Boolean.TRUE); - } - } - return true; - } - } - } + Map<Dependency, Set<ArtifactKey>> getSourceMap() { + return sourceMap; + } - return true; - } + private int depth; - private Dependency findDependency(String groupId, String artifactId) { - for(org.apache.maven.model.Dependency d : dependencies) { - if(d.getGroupId().equals(groupId) && d.getArtifactId().equals(artifactId)) { - return d; - } - } - return null; + private DependencyNode topLevel; + + public boolean visitLeave(DependencyNode node) { + depth-- ; + return true; + // TODO return status == null; + } + + public boolean visitEnter(DependencyNode node) { + if(depth == 1) { + topLevel = node; } + depth++ ; - private Dependency findDependency(DependencyNode node) { - Artifact artifact; - if(node.getRelocations().isEmpty()) { - artifact = node.getDependency().getArtifact(); - } else { - artifact = node.getRelocations().get(0); + if(node.getDependency() != null) { + Artifact a = node.getDependency().getArtifact(); + for(ArtifactKey key : keys) { + if(a.getGroupId().equals(key.getGroupId()) && a.getArtifactId().equals(key.getArtifactId())) { + if(topLevel != null) { + // need to add exclusion to top-level dependency + Dependency dependency = findDependency(topLevel); + if(dependency != null) { + put(dependency, key); + } + } + return true; + } } - return findDependency(artifact.getGroupId(), artifact.getArtifactId()); } - }); + return true; + } - for(Entry<Dependency, Set<ArtifactKey>> entry : toAdd.entrySet()) { - for(ArtifactKey key : entry.getValue()) { - operations.add(new AddExclusionOperation(entry.getKey(), key)); + private void put(Dependency dep, ArtifactKey key) { + Set<ArtifactKey> keys = sourceMap.get(dep); + if(keys == null) { + keys = new HashSet<ArtifactKey>(); + sourceMap.put(dep, keys); } + keys.add(key); } - if(operations.size() > 0) { - operationMap.put(pomFile, PomHelper.createChange(pomFile, - new CompoundOperation(operations.toArray(new Operation[operations.size()])), msg.toString())); + private Dependency findDependency(String groupId, String artifactId) { + for(Dependency d : dependencies) { + if(d.getGroupId().equals(groupId) && d.getArtifactId().equals(artifactId)) { + return d; + } + } + return null; } - return !operations.isEmpty(); - } - private void set(ArtifactKey key, Boolean bool) { - Boolean old = locatedKeys.get(key); - if(old == null) { - locatedKeys.put(key, bool); - } else { - locatedKeys.put(key, old & bool); + private Dependency findDependency(DependencyNode node) { + Artifact artifact; + if(node.getRelocations().isEmpty()) { + artifact = node.getDependency().getArtifact(); + } else { + artifact = node.getRelocations().get(0); + } + return findDependency(artifact.getGroupId(), artifact.getArtifactId()); } } }
\ No newline at end of file diff --git a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/ExcludeWizardPage.java b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/ExcludeWizardPage.java new file mode 100644 index 00000000..f4b7917f --- /dev/null +++ b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/ExcludeWizardPage.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 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.refactoring.exclude; + +import org.apache.maven.project.MavenProject; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.editor.composites.PomHierarchyComposite; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + + +public class ExcludeWizardPage extends UserInputWizardPage implements SelectionListener, ISelectionChangedListener { + + private PomHierarchyComposite pomHierarchy; + + private Button currentPom; + + private Button hierarchy; + + private IMavenProjectFacade facade; + + private CLabel label; + + protected ExcludeWizardPage(IMavenProjectFacade facade) { + super("Place to exclude"); + this.facade = facade; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NULL); + setControl(composite); + composite.setLayout(new GridLayout(1, false)); + + currentPom = new Button(composite, SWT.RADIO); + currentPom.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + currentPom.setText("Selected pom"); + currentPom.setSelection(true); + currentPom.addSelectionListener(this); + + hierarchy = new Button(composite, SWT.RADIO); + hierarchy.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); + hierarchy.setText("Choose from project hierarchy"); + hierarchy.addSelectionListener(this); + + pomHierarchy = new PomHierarchyComposite(composite, SWT.BORDER); + GridData gd_pomHierarchy = new GridData(SWT.FILL, SWT.FILL, true, true); + gd_pomHierarchy.horizontalIndent = 15; + pomHierarchy.setLayoutData(gd_pomHierarchy); + pomHierarchy.setEnabled(false); + pomHierarchy.addSelectionChangedListener(this); + + label = new CLabel(composite, SWT.NONE); + label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); + + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + pomHierarchy.computeHeirarchy(facade, getContainer()); + ((ExcludeArtifactRefactoring) getRefactoring()).setHierarchy(pomHierarchy.getHierarchy()); + } + }); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + if(e.getSource() == currentPom) { + pomHierarchy.setEnabled(false); + } else if(e.getSource() == hierarchy) { + pomHierarchy.setEnabled(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + + } + + private void setStatus(String msg) { + if(msg == null) { + label.setImage(null); + label.setText(""); + } else { + label.setText(msg); + label.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_ERROR_TSK)); + } + } + + private void updateState() { + ExcludeArtifactRefactoring refactoring = (ExcludeArtifactRefactoring) getRefactoring(); + if(pomHierarchy.isEnabled()) { + MavenProject project = fromSelection(pomHierarchy.getSelection()); + setPageComplete(project != null && project.getFile() != null); + if(project != null && project.getFile() == null) { + setStatus("Changes must occur within the workspace"); + } else { + setStatus(null); + refactoring.setExclusionPoint(fromSelection(pomHierarchy.getSelection())); + } + } else { + setStatus(null); + refactoring.setExclusionPoint(facade.getMavenProject()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + updateState(); + } + + private MavenProject fromSelection(ISelection selection) { + if(selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if(obj instanceof MavenProject) { + return (MavenProject) obj; + } + } + return null; + } +} diff --git a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/MavenExcludeWizard.java b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/MavenExcludeWizard.java index f707929f..803be06e 100644 --- a/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/MavenExcludeWizard.java +++ b/org.eclipse.m2e.refactoring/src/org/eclipse/m2e/refactoring/exclude/MavenExcludeWizard.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008-2010 Sonatype, Inc. + * Copyright (c) 2008-2011 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 @@ -13,12 +13,13 @@ package org.eclipse.m2e.refactoring.exclude; import org.eclipse.ltk.ui.refactoring.RefactoringWizard; - /** * @author Anton Kraev */ public class MavenExcludeWizard extends RefactoringWizard { + private ExcludeWizardPage excludePage; + public MavenExcludeWizard(ExcludeArtifactRefactoring refactoring) { super(refactoring, DIALOG_BASED_USER_INTERFACE); } @@ -26,6 +27,7 @@ public class MavenExcludeWizard extends RefactoringWizard { @Override protected void addUserInputPages() { setDefaultPageTitle(getRefactoring().getName()); + excludePage = new ExcludeWizardPage(((ExcludeArtifactRefactoring) getRefactoring()).getSource()); + addPage(excludePage); } - } |
