Index: plugin.xml
===================================================================
--- plugin.xml (revision 822319)
+++ plugin.xml (working copy)
@@ -233,6 +251,14 @@
name="Reverse Dependency Explorer"
restorable="true">
+
+
Index: META-INF/MANIFEST.MF
===================================================================
--- META-INF/MANIFEST.MF (revision 822319)
+++ META-INF/MANIFEST.MF (working copy)
@@ -31,10 +31,12 @@
org.eclipse.jdt.core,
org.eclipse.jdt.ui,
org.eclipse.ui.console,
+ org.eclipse.wst.xml.core,
org.apache.ivy,
org.eclipse.help,
- org.eclipse.wst.xml.core,
org.eclipse.debug.core,
- org.eclipse.jdt.launching
+ org.eclipse.jdt.launching,
+ org.eclipse.zest.core;bundle-version="1.0.0",
+ org.eclipse.zest.layouts;bundle-version="1.0.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.4
Index: icons/evicted.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: icons\evicted.gif
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: icons/focus.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: icons\focus.gif
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: icons/screenshot.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: icons\screenshot.gif
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: src/java/org/apache/ivyde/eclipse/cpcontainer/IvyClasspathContainerState.java
===================================================================
--- src/java/org/apache/ivyde/eclipse/cpcontainer/IvyClasspathContainerState.java (revision 822319)
+++ src/java/org/apache/ivyde/eclipse/cpcontainer/IvyClasspathContainerState.java (working copy)
@@ -32,6 +32,7 @@
import org.apache.ivy.Ivy;
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.util.Message;
@@ -66,6 +67,8 @@
private long ivySettingsLastModified = -1;
private ModuleDescriptor md;
+
+ private ResolveReport resolveReport;
private IvyClasspathContainerConfiguration conf;
@@ -414,9 +417,16 @@
throw ex;
}
}
-
+
public String toString() {
return conf.toString();
}
+ public ResolveReport getResolveReport() {
+ return resolveReport;
+ }
+
+ public void setResolveReport(ResolveReport resolveReport) {
+ this.resolveReport = resolveReport;
+ }
}
Index: src/java/org/apache/ivyde/eclipse/cpcontainer/IvyResolveJob.java
===================================================================
--- src/java/org/apache/ivyde/eclipse/cpcontainer/IvyResolveJob.java (revision 822319)
+++ src/java/org/apache/ivyde/eclipse/cpcontainer/IvyResolveJob.java (working copy)
@@ -102,6 +102,7 @@
}
if (resolver.getStatus() == Status.OK_STATUS) {
container.updateClasspathEntries(resolver.getClasspathEntries());
+ container.getState().setResolveReport(resolver.getResolveReport());
}
setResolveStatus(resolver.getStatus());
return resolver.getStatus();
Index: src/java/org/apache/ivyde/eclipse/cpcontainer/IvyResolveJobThread.java
===================================================================
--- src/java/org/apache/ivyde/eclipse/cpcontainer/IvyResolveJobThread.java (revision 822319)
+++ src/java/org/apache/ivyde/eclipse/cpcontainer/IvyResolveJobThread.java (working copy)
@@ -47,7 +47,6 @@
import org.apache.ivy.util.filter.ArtifactTypeFilter;
import org.apache.ivyde.eclipse.FakeProjectManager;
import org.apache.ivyde.eclipse.IvyPlugin;
-import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
@@ -82,6 +81,8 @@
private String[] confs;
private Map artifactsByDependency = new HashMap();
+
+ private ResolveReport report;
public IvyResolveJobThread(IvyClasspathContainerConfiguration conf, Ivy ivy,
ModuleDescriptor md, boolean usePreviousResolveIfExist, IProgressMonitor monitor) {
@@ -99,6 +100,10 @@
public IClasspathEntry[] getClasspathEntries() {
return classpathEntries;
}
+
+ public ResolveReport getResolveReport() {
+ return report;
+ }
public void run() {
try {
@@ -221,7 +226,7 @@
private boolean resolve() throws ParseException, IOException {
ResolveOptions resolveOption = new ResolveOptions().setConfs(confs);
resolveOption.setValidate(ivy.getSettings().doValidate());
- ResolveReport report = ivy.resolve(md, resolveOption);
+ report = ivy.resolve(md, resolveOption);
problemMessages = report.getAllProblemMessages();
all = new LinkedHashSet(Arrays.asList(report.getArtifactsReports(null, false)));
confs = report.getConfigurations();
Index: src/java/org/apache/ivyde/eclipse/ui/views/ResolveVisualizerView.java
===================================================================
--- src/java/org/apache/ivyde/eclipse/ui/views/ResolveVisualizerView.java (revision 0)
+++ src/java/org/apache/ivyde/eclipse/ui/views/ResolveVisualizerView.java (revision 0)
@@ -0,0 +1,491 @@
+package org.apache.ivyde.eclipse.ui.views;
+
+import java.awt.Dimension;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Stack;
+
+import org.apache.ivy.core.report.ResolveReport;
+import org.apache.ivyde.eclipse.IvyPlugin;
+import org.apache.ivyde.eclipse.cpcontainer.IvyClasspathContainer;
+import org.apache.ivyde.resolvevisualizer.ClasspathContainerSelectionDialog;
+import org.apache.ivyde.resolvevisualizer.IvyNodeLabelProvider;
+import org.apache.ivyde.resolvevisualizer.MessageContentProvider;
+import org.apache.ivyde.resolvevisualizer.ResolveVisualizerContentProvider;
+import org.apache.ivyde.resolvevisualizer.ResolveVisualizerForm;
+import org.apache.ivyde.resolvevisualizer.label.ILabelDecoratorAlgorithm;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElementAdapter;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElementFilterAdapter;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.zest.core.viewers.AbstractZoomableViewer;
+import org.eclipse.zest.core.viewers.EntityConnectionData;
+import org.eclipse.zest.core.viewers.GraphViewer;
+import org.eclipse.zest.core.viewers.IZoomableWorkbenchPart;
+import org.eclipse.zest.core.viewers.ZoomContributionViewItem;
+import org.eclipse.zest.core.widgets.Graph;
+import org.eclipse.zest.core.widgets.GraphItem;
+import org.eclipse.zest.core.widgets.GraphNode;
+import org.eclipse.zest.core.widgets.ZestStyles;
+import org.eclipse.zest.layouts.LayoutAlgorithm;
+import org.eclipse.zest.layouts.LayoutStyles;
+import org.eclipse.zest.layouts.algorithms.CompositeLayoutAlgorithm;
+import org.eclipse.zest.layouts.algorithms.DirectedGraphLayoutAlgorithm;
+import org.eclipse.zest.layouts.algorithms.HorizontalShift;
+
+public class ResolveVisualizerView extends ViewPart implements IZoomableWorkbenchPart {
+ private GraphViewer viewer;
+ private FormToolkit toolKit;
+
+ private Action focusDialogAction;
+ private Action focusDialogActionToolbar;
+ private Action focusOnSelectionAction;
+ private Action hideSelectionAction;
+ private Action showHiddenAction;
+ private Action applyDefaultLayoutAction;
+ private Action historyAction;
+ private Action forwardAction;
+ private Action refreshAction;
+
+ private ZoomContributionViewItem contextZoomContributionViewItem;
+ private ZoomContributionViewItem toolbarZoomContributionViewItem;
+
+ private Stack/**/ historyStack;
+ private Stack/**/ forwardStack;
+
+ private IvyNodeElement currentRoot;
+ private IvyNodeElement currentSelection;
+ private IvyClasspathContainer currentContainer;
+
+ private ResolveVisualizerContentProvider contentProvider = new ResolveVisualizerContentProvider();
+ private MessageContentProvider messageContentProvider = new MessageContentProvider();
+ private IvyNodeLabelProvider labelProvider;
+ private ResolveVisualizerForm visualizationForm;
+
+ private ForceHiddenFilter forceHiddenFilter;
+
+ public ResolveVisualizerView() {
+ historyStack = new Stack/**/();
+ forwardStack = new Stack/**/();
+
+ forceHiddenFilter = new ForceHiddenFilter();
+ forceHiddenFilter.setEnabled(true);
+ contentProvider.addFilter(forceHiddenFilter);
+ }
+
+ /**
+ * This is a callback that will allow us
+ * to create the viewer and initialize it.
+ */
+ public void createPartControl(Composite parent) {
+ toolKit = new FormToolkit(parent.getDisplay());
+
+ visualizationForm = new ResolveVisualizerForm(parent, toolKit, this);
+ viewer = visualizationForm.getGraphViewer();
+
+ this.labelProvider = new IvyNodeLabelProvider(this.viewer);
+ viewer.setLabelProvider(labelProvider);
+ viewer.setContentProvider(contentProvider);
+ viewer.setInput(null);
+ viewer.setConnectionStyle(ZestStyles.CONNECTIONS_DIRECTED);
+ viewer.setLayoutAlgorithm(
+ new CompositeLayoutAlgorithm(
+ LayoutStyles.NO_LAYOUT_NODE_RESIZING,
+ new LayoutAlgorithm[] { new DirectedGraphLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING),
+ new HorizontalShift(LayoutStyles.NO_LAYOUT_NODE_RESIZING) })
+ );
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ Object selectedElement = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ if (selectedElement instanceof EntityConnectionData) {
+ return;
+ }
+ ResolveVisualizerView.this.selectionChanged((IvyNodeElement) selectedElement);
+ }
+ });
+
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ focusOnSelectionAction.run();
+ }
+ });
+
+ visualizationForm.getSearchBox().addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String textString = visualizationForm.getSearchBox().getText();
+
+ HashMap figureListing = new HashMap();
+ ArrayList list = new ArrayList();
+ Iterator iterator = viewer.getGraphControl().getNodes().iterator();
+ while (iterator.hasNext()) {
+ GraphItem item = (GraphItem) iterator.next();
+ figureListing.put(item.getText(), item);
+ }
+ iterator = figureListing.keySet().iterator();
+ if (textString.length() > 0) {
+ while (iterator.hasNext()) {
+ String string = (String) iterator.next();
+ if (string.toLowerCase().indexOf(textString.toLowerCase()) >= 0) {
+ list.add(figureListing.get(string));
+ }
+ }
+ }
+ viewer.getGraphControl().setSelection((GraphItem[]) list.toArray(new GraphItem[list.size()]));
+ }
+ });
+
+ messageContentProvider.setMessageManager(visualizationForm.getManagedForm().getMessageManager());
+ contextZoomContributionViewItem = new ZoomContributionViewItem(this);
+ toolbarZoomContributionViewItem = new ZoomContributionViewItem(this);
+
+ // Create the help context id for the viewer's control
+ makeActions();
+ hookContextMenu();
+ contributeToActionBars();
+ }
+
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ ResolveVisualizerView.this.fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ private void contributeToActionBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ bars.getMenuManager().add(toolbarZoomContributionViewItem);
+ fillLocalPullDown(bars.getMenuManager());
+ fillLocalToolBar(bars.getToolBarManager());
+ }
+
+ private void fillLocalPullDown(IMenuManager manager) {
+ }
+
+ private void fillContextMenu(IMenuManager manager) {
+ manager.add(new Separator());
+ manager.add(focusDialogAction);
+ manager.add(focusOnSelectionAction);
+ manager.add(new Separator());
+ manager.add(historyAction);
+ manager.add(forwardAction);
+ manager.add(new Separator());
+ manager.add(hideSelectionAction);
+ manager.add(showHiddenAction);
+ manager.add(new Separator());
+ manager.add(refreshAction);
+ manager.add(applyDefaultLayoutAction);
+ manager.add(new Separator());
+ manager.add(contextZoomContributionViewItem);
+ }
+
+ private void fillLocalToolBar(IToolBarManager toolBarManager) {
+ toolBarManager.add(refreshAction);
+ toolBarManager.add(focusDialogActionToolbar);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(historyAction);
+ toolBarManager.add(forwardAction);
+ }
+
+ private void makeActions() {
+ refreshAction = new Action() {
+ public void run() {
+ final IvyClasspathContainer container = currentContainer;
+
+ ResolveReport report = container.getState().getResolveReport();
+ if(report == null) {
+ // TODO Employing this resolve job is a temporary technique for taking our best shot at
+ // guaranteeing a ResolveReport is available to the view. There is still a decision
+ // to be made on whether we should use the ResolveReport or some other Ivy api construct
+ // to build the view.
+ Job resolveJob = new Job("Preparing report for view") {
+
+ protected IStatus run(IProgressMonitor monitor) {
+ container.launchResolve(false, false, monitor);
+ return Status.OK_STATUS;
+ }
+ };
+
+ resolveJob.addJobChangeListener(new JobChangeAdapter() {
+ public void done(IJobChangeEvent event) {
+ super.done(event);
+ getViewSite().getShell().getDisplay().syncExec(new Runnable() {
+ public void run() {
+ focusOnContainer(container);
+ }
+ });
+ }
+ });
+ resolveJob.setUser(true);
+ resolveJob.schedule();
+ }
+ else {
+ // a resolve report is already saved on the container's state, we will use it
+ focusOnContainer(container);
+ }
+
+ // When a new container is selected, disable the forward action
+ // The forward action only stores history when the back button was used (much like a browser)
+ forwardStack.clear();
+ forwardAction.setEnabled(false);
+ }
+ };
+ refreshAction.setText("Resolve");
+ refreshAction.setEnabled(true);
+ refreshAction.setImageDescriptor(IvyPlugin.getImageDescriptor("icons/refresh.gif"));
+
+ focusDialogAction = new Action() {
+ public void run() {
+ ClasspathContainerSelectionDialog dialog = new ClasspathContainerSelectionDialog(viewer.getControl().getShell());
+ dialog.create();
+ int dialogStatus = dialog.open();
+ if (dialogStatus == Window.OK) {
+ currentContainer = (IvyClasspathContainer) dialog.getFirstResult();
+ refreshAction.run();
+ }
+ }
+ };
+ focusDialogAction.setText("Focus on ivy file...");
+
+ focusDialogActionToolbar = new Action() {
+ public void run() {
+ focusDialogAction.run();
+ }
+ };
+ focusDialogActionToolbar.setToolTipText("Focus on ivy file...");
+ focusDialogActionToolbar.setImageDescriptor(IvyPlugin.getImageDescriptor("icons/focus.gif"));
+
+ focusOnSelectionAction = new Action() {
+ public void run() {
+ if(currentSelection != null) {
+ if (currentRoot != currentSelection) {
+ if(currentRoot != null) {
+ historyStack.push(currentRoot);
+ historyAction.setEnabled(true);
+ }
+ focusOn(currentSelection);
+ }
+ }
+ }
+ };
+ focusOnSelectionAction.setText("Focus on selection");
+ focusOnSelectionAction.setEnabled(false);
+
+ historyAction = new Action() {
+ public void run() {
+ if (historyStack.size() > 0) {
+ IvyNodeElement element = (IvyNodeElement) historyStack.pop();
+ forwardStack.push(currentRoot);
+ forwardAction.setEnabled(true);
+ focusOn(element);
+ if (historyStack.size() <= 0) {
+ historyAction.setEnabled(false);
+ }
+ }
+ }
+ };
+ historyAction.setText("Back");
+ historyAction.setToolTipText("Back");
+ historyAction.setEnabled(false);
+ historyAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_BACK));
+
+ forwardAction = new Action() {
+ public void run() {
+ if (forwardStack.size() > 0) {
+ IvyNodeElement element = (IvyNodeElement) forwardStack.pop();
+
+ historyStack.push(currentRoot);
+ historyAction.setEnabled(true);
+
+ focusOn(element);
+ if (forwardStack.size() <= 0) {
+ forwardAction.setEnabled(false);
+ }
+ }
+ }
+ };
+
+ forwardAction.setText("Forward");
+ forwardAction.setToolTipText("Forward");
+ forwardAction.setEnabled(false);
+ forwardAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD));
+
+ hideSelectionAction = new Action() {
+ public void run() {
+ forceHiddenFilter.addHidden(currentSelection);
+ refresh();
+ }
+ };
+ hideSelectionAction.setText("Hide");
+
+ showHiddenAction = new Action() {
+ public void run() {
+ forceHiddenFilter.clearHidden();
+ refresh();
+ }
+ };
+ showHiddenAction.setText("Show hidden");
+
+ applyDefaultLayoutAction = new Action() {
+ public void run() {
+ viewer.applyLayout();
+ }
+ };
+ applyDefaultLayoutAction.setText("Apply default layout");
+ }
+
+ /**
+ * Passing the focus request to the viewer's control.
+ */
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ }
+
+ private final void focusOnContainer(IvyClasspathContainer container) {
+ ResolveReport report = container.getState().getResolveReport();
+
+ if(report != null) {
+ forceHiddenFilter.clearHidden();
+ visualizationForm.getForm().setText(ResolveVisualizerForm.HeaderText + " - " + container.getConf().getIvyXmlPath() + " in \"" + container.getConf()
+ .getJavaProject().getProject().getName() + "\"");
+
+ IvyNodeElement nextRoot = IvyNodeElementAdapter.adapt(report);
+ if (currentRoot != nextRoot) {
+ if(currentRoot != null) {
+ historyStack.push(currentRoot);
+ historyAction.setEnabled(true);
+ }
+ focusOn(nextRoot);
+ }
+ }
+ }
+
+ /**
+ * Update the view to focus on a particular bundle. If record history is set
+ * to true, and bundle does not equal the current bundle, then the current
+ * bundle will be saved on the history stack
+ *
+ * @param focus
+ * @param recordHistory
+ */
+ public void focusOn(IvyNodeElement focus) {
+ viewer.setSelection(new StructuredSelection(focus));
+ viewer.setFilters(new ViewerFilter[] {});
+ viewer.setInput(focus);
+
+ Iterator nodes = viewer.getGraphControl().getNodes().iterator();
+ Graph graph = viewer.getGraphControl();
+ Dimension centre = new Dimension(graph.getBounds().width / 2, graph.getBounds().height / 2);
+ while (nodes.hasNext()) {
+ GraphNode graphNode = (GraphNode) nodes.next();
+ if (graphNode.getLocation().x <= 1 && graphNode.getLocation().y <= 1) {
+ graphNode.setLocation(centre.width, centre.height);
+ }
+ }
+
+ currentRoot = focus;
+
+ if (viewer.getGraphControl().getNodes().size() > 0) {
+ visualizationForm.enableSearchBox(true);
+ } else {
+ visualizationForm.enableSearchBox(false);
+ }
+ visualizationForm.enableSearchBox(true);
+ focusOnSelectionAction.setEnabled(true);
+
+ selectionChanged(focus);
+ }
+
+ /**
+ * Handle the select changed. This will update the view whenever a selection
+ * occurs.
+ *
+ * @param selectedItem
+ */
+ private void selectionChanged(IvyNodeElement selectedItem) {
+ currentSelection = selectedItem;
+ labelProvider.setCurrentSelection(currentRoot, selectedItem);
+ messageContentProvider.selectionChanged(currentRoot);
+ viewer.update(contentProvider.getElements(currentRoot), null);
+ }
+
+ public AbstractZoomableViewer getZoomableViewer() {
+ return viewer;
+ }
+
+ public void setAutoSelectDecorator(ILabelDecoratorAlgorithm algorithm) {
+ labelProvider.setAutoSelectDecorator(algorithm);
+
+ if (viewer.getSelection() != null) {
+ Object selected = ((IStructuredSelection) viewer.getSelection()).getFirstElement();
+ this.selectionChanged((IvyNodeElement) selected);
+ }
+ }
+
+ public ResolveVisualizerContentProvider getContentProvider() {
+ return contentProvider;
+ }
+
+ public void refresh() {
+ viewer.refresh();
+ viewer.applyLayout();
+ }
+
+ public IvyNodeElement getCurrentRoot() {
+ return currentRoot;
+ }
+
+ private class ForceHiddenFilter extends IvyNodeElementFilterAdapter {
+ private Collection/**/ forceHidden = new HashSet/**/();
+
+ public boolean accept(IvyNodeElement unfiltered) {
+ return !forceHidden.contains(unfiltered);
+ }
+
+ public void addHidden(IvyNodeElement hide) {
+ forceHidden.addAll(Arrays.asList(hide.getDeepDependencies()));
+ }
+
+ public void clearHidden() {
+ forceHidden.clear();
+ }
+ }
+}
\ No newline at end of file
Index: src/java/org/apache/ivyde/resolvevisualizer/ClasspathContainerSelectionDialog.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/ClasspathContainerSelectionDialog.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/ClasspathContainerSelectionDialog.java (revision 0)
@@ -0,0 +1,37 @@
+package org.apache.ivyde.resolvevisualizer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ivyde.eclipse.cpcontainer.IvyClasspathContainer;
+import org.apache.ivyde.eclipse.cpcontainer.IvyClasspathUtil;
+import org.apache.ivyde.eclipse.revdepexplorer.IvyUtil;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+public class ClasspathContainerSelectionDialog extends ElementListSelectionDialog {
+ public ClasspathContainerSelectionDialog(Shell parentShell) {
+ super(parentShell, new LabelProvider() {
+ public String getText(Object element) {
+ IvyClasspathContainer container = (IvyClasspathContainer) element;
+ return container.getConf().getJavaProject().getProject().getName() + " -> "
+ + container.getDescription();
+ }
+ });
+ setTitle("Ivy Classpath Containers");
+ setMessage("Select a container to view in the resolve visualizer.");
+
+ // TODO refactor IvyUtil out of the revdepexplorer package as it is
+ // a more general purpose utility
+ List/**/ classpathContainers = new ArrayList/**/();
+ IProject[] ivyProjects = IvyUtil.getIvyProjectsInWorkspace();
+ for(int i = 0; i < ivyProjects.length; i++) {
+ classpathContainers.addAll(IvyClasspathUtil.getIvyClasspathContainers(ivyProjects[i]));
+ }
+
+ setElements(classpathContainers.toArray());
+ setMultipleSelection(false);
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/IvyNodeLabelProvider.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/IvyNodeLabelProvider.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/IvyNodeLabelProvider.java (revision 0)
@@ -0,0 +1,295 @@
+package org.apache.ivyde.resolvevisualizer;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.ivyde.eclipse.IvyPlugin;
+import org.apache.ivyde.resolvevisualizer.label.ConfigurationConflictAlgorithm;
+import org.apache.ivyde.resolvevisualizer.label.ConnectionStyle;
+import org.apache.ivyde.resolvevisualizer.label.DirectDependenciesAlgorithm;
+import org.apache.ivyde.resolvevisualizer.label.ILabelDecoratorAlgorithm;
+import org.apache.ivyde.resolvevisualizer.label.ShortestRootPathAlgorithm;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Label;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.zest.core.viewers.EntityConnectionData;
+import org.eclipse.zest.core.viewers.GraphViewer;
+import org.eclipse.zest.core.viewers.IConnectionStyleProvider;
+import org.eclipse.zest.core.viewers.IEntityStyleProvider;
+import org.eclipse.zest.core.widgets.ZestStyles;
+
+/**
+ * Alters the color of the labels and connections based on the selected analysis algorithm.
+ */
+public class IvyNodeLabelProvider implements ILabelProvider, IConnectionStyleProvider, IEntityStyleProvider {
+ public Color GRAY = new Color(Display.getDefault(), 128, 128, 128);
+ public Color LIGHT_GRAY = new Color(Display.getDefault(), 220, 220, 220);
+ public Color BLACK = new Color(Display.getDefault(), 0, 0, 0);
+ public Color RED = new Color(Display.getDefault(), 255, 0, 0);
+ public Color LIGHT_GREEN = new Color(Display.getDefault(), 96, 255, 96);
+
+ private IvyNodeElement selected = null;
+ private IvyNodeElement rootNode = null;
+ private Map/**/ highlightedRelationships = new HashMap/**/();
+ private Map/**/ highlightedDependencies = new HashMap/**/();
+ private Color disabledColor = null;
+ private IvyNodeElement pinnedNode = null;
+ private GraphViewer viewer;
+
+ private ILabelDecoratorAlgorithm autoSelectDecorator = new ShortestRootPathAlgorithm();
+ private DirectDependenciesAlgorithm rootDirectDependenciesDecorator = new DirectDependenciesAlgorithm();;
+ private ConfigurationConflictAlgorithm conflictDecorator = new ConfigurationConflictAlgorithm();
+
+ private Color rootColor;
+ private Color rootSelectedColor;
+
+ public IvyNodeLabelProvider(GraphViewer viewer) {
+ this.viewer = viewer;
+ this.rootDirectDependenciesDecorator.setStyles(
+ new Color(Display.getDefault(), 197, 237, 197),
+ new ConnectionStyle(ZestStyles.CONNECTIONS_SOLID,
+ new Color(Display.getDefault(), 175, 175, 175), 1, false));
+ }
+
+ public Image getImage(Object element) {
+ if (element instanceof IvyNodeElement) {
+ IvyNodeElement node = (IvyNodeElement) element;
+ if(node.isEvicted()) {
+ return IvyPlugin.getImageDescriptor("icons/evicted.gif").createImage();
+ }
+ }
+
+ return null;
+ }
+
+ public String getText(Object element) {
+ if (element instanceof IvyNodeElement) {
+ IvyNodeElement node = (IvyNodeElement) element;
+ String text = node.getOrganization() + "#" + node.getName() + ";";
+ if (node.getRevision().indexOf("working@") != -1)
+ text += "WORKSPACE";
+ else
+ text += node.getRevision();
+ return text;
+ }
+
+ return "";
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ /**
+ * Colors all connections regardless of their selection status.
+ */
+ public Color getColor(Object rel) {
+ if (highlightedRelationships.keySet().contains(rel)) {
+ ConnectionStyle style = (ConnectionStyle) highlightedRelationships.get(rel);
+ return style.getHighlightColor();
+ }
+ return LIGHT_GRAY;
+ }
+
+ public int getConnectionStyle(Object rel) {
+ return ZestStyles.CONNECTIONS_DIRECTED;
+ }
+
+ /**
+ * Colors "highlighted" relationships. We want to differentiate
+ * between those highlighted programatically by the auto-select
+ * mechanism, and those hand-selected by the user.
+ */
+ public Color getHighlightColor(Object rel) {
+ if (highlightedRelationships.keySet().contains(rel)) {
+ ConnectionStyle style = (ConnectionStyle) highlightedRelationships.get(rel);
+ return style.getHighlightColor();
+ }
+ return ColorConstants.blue;
+ }
+
+ public Color getNodeHighlightColor(Object entity) {
+ return null;
+ }
+
+ public int getLineWidth(Object rel) {
+ if(highlightedRelationships.keySet().contains(rel)) {
+ ConnectionStyle style = (ConnectionStyle) highlightedRelationships.get(rel);
+ if(style.isRevealOnHighlight()) {
+ return style.getLineWidth();
+ }
+ }
+ return 1;
+ }
+
+ public Color getAdjacentEntityHighlightColor(Object entity) {
+ return null;
+ }
+
+ public Color getBorderColor(Object entity) {
+ if (this.selected != null || this.pinnedNode != null) {
+ if (entity == this.selected || entity == this.pinnedNode) {
+ return BLACK;
+ } else if (highlightedDependencies.keySet().contains(entity)) {
+ // If this entity is directly connected to the selected entity
+ return BLACK;
+ } else {
+ return LIGHT_GRAY;
+ }
+
+ }
+
+ return BLACK;
+ }
+
+ public Color getBorderHighlightColor(Object entity) {
+ return null;
+ }
+
+ public int getBorderWidth(Object entity) {
+ return 0;
+ }
+
+ public Color getBackgroundColour(Object entity) {
+
+ if (entity == this.rootNode) {
+ if (rootColor == null) {
+ rootColor = LIGHT_GREEN;
+ }
+ return rootColor;
+ }
+ if (highlightedDependencies.keySet().contains(entity)) {
+ return (Color) highlightedDependencies.get(entity); //viewer.getGraphControl().HIGHLIGHT_ADJACENT_COLOR;
+ } else {
+ return viewer.getGraphControl().DEFAULT_NODE_COLOR;
+ }
+ }
+
+ public Color getForegroundColour(Object entity) {
+ if (this.selected != null || this.pinnedNode != null) {
+ if (entity == this.selected || this.pinnedNode == entity) {
+ return BLACK;
+ } else if (highlightedDependencies.keySet().contains(entity)) {
+ // If this entity is directly connected to the selected entity
+ return BLACK;
+ } else {
+ return GRAY;
+ }
+
+ }
+ return BLACK;
+ }
+
+ public void setPinnedNode(IvyNodeElement pinnedNode) {
+ this.pinnedNode = pinnedNode;
+ }
+
+ protected IvyNodeElement getSelected() {
+ if (pinnedNode != null) {
+ return pinnedNode;
+ }
+ return selected;
+ }
+
+ /**
+ * Sets the current selection
+ *
+ * @param root
+ * @param currentSelection
+ */
+ public void setCurrentSelection(IvyNodeElement root, IvyNodeElement currentSelection) {
+ for (Iterator iter = highlightedRelationships.keySet().iterator(); iter.hasNext();) {
+ EntityConnectionData entityConnectionData = (EntityConnectionData) iter.next();
+
+ ConnectionStyle style = (ConnectionStyle) highlightedRelationships.get(entityConnectionData);
+ if(style.isRevealOnHighlight()) {
+ viewer.unReveal(entityConnectionData);
+ }
+ }
+
+ this.rootNode = root;
+ this.selected = null;
+ this.selected = currentSelection;
+
+ highlightedRelationships = new HashMap/**/();
+ highlightedDependencies = new HashMap/**/();
+
+ rootDirectDependenciesDecorator.calculateHighlighted(root, root, highlightedRelationships,
+ highlightedDependencies);
+ conflictDecorator.calculateHighlighted(root, root, highlightedRelationships,
+ highlightedDependencies);
+
+ if (this.selected != null || this.pinnedNode != null) {
+ autoSelectDecorator.calculateHighlighted(
+ root, selected, highlightedRelationships,
+ highlightedDependencies);
+ }
+
+ Object[] connections = viewer.getConnectionElements();
+ for (Iterator iter = highlightedRelationships.keySet().iterator(); iter.hasNext();) {
+ Object entityConnectionData = iter.next();
+
+ ConnectionStyle style = (ConnectionStyle) highlightedRelationships.get(entityConnectionData);
+ if (style.isRevealOnHighlight()) {
+ viewer.reveal(entityConnectionData);
+ }
+ }
+
+ for (int i = 0; i < connections.length; i++) {
+ viewer.update(connections[i], null);
+ }
+ }
+
+ public void dispose() {
+ if (this.disabledColor != null) {
+ this.disabledColor.dispose();
+ this.disabledColor = null;
+ }
+ if ( this.rootColor != null) {
+ this.rootColor.dispose();
+ this.rootColor = null;
+ }
+ if ( this.rootSelectedColor != null) {
+ this.rootSelectedColor.dispose();
+ this.rootSelectedColor = null;
+ }
+ }
+
+ public IFigure getTooltip(Object entity) {
+ if(entity instanceof EntityConnectionData) {
+ EntityConnectionData connection = (EntityConnectionData) entity;
+ IvyNodeElement source = (IvyNodeElement) connection.source;
+ IvyNodeElement dest = (IvyNodeElement) connection.dest;
+
+ String[] confs = dest.getCallerConfigurations(source);
+ String tooltipText = "";
+ for(int i = 0; i < confs.length; i++) {
+ tooltipText += confs[i] + ", ";
+ }
+ return new Label(tooltipText.substring(0, tooltipText.length() - 2));
+ }
+
+ return null;
+ }
+
+ public boolean fisheyeNode(Object entity) {
+ return false;
+ }
+
+ public void setAutoSelectDecorator(ILabelDecoratorAlgorithm decoratorAlgorithm) {
+ this.autoSelectDecorator = decoratorAlgorithm;
+ }
+}
\ No newline at end of file
Index: src/java/org/apache/ivyde/resolvevisualizer/MessageContentProvider.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/MessageContentProvider.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/MessageContentProvider.java (revision 0)
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.ivy.core.module.id.ModuleId;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.ui.forms.IMessageManager;
+
+public class MessageContentProvider {
+ private IMessageManager manager;
+
+ /**
+ * Called when the view selection changes and the message list needs to be rebuilt.
+ */
+ public void selectionChanged(IvyNodeElement root) {
+ manager.removeAllMessages();
+
+ Map/*>*/ conflicts = new HashMap/*>*/();
+
+ IvyNodeElement[] deepDependencies = root.getDeepDependencies();
+ for(int i = 0; i < deepDependencies.length; i++) {
+ if(deepDependencies[i].getConflicts().length > 0) {
+ Collection/**/ conflictParticipants = (Collection) conflicts.get(
+ deepDependencies[i].getModuleRevisionId().getModuleId());
+ if(conflictParticipants == null)
+ conflictParticipants = new HashSet/**/();
+ conflictParticipants.add(deepDependencies[i]);
+ conflicts.put(deepDependencies[i].getModuleRevisionId().getModuleId(), conflictParticipants);
+ }
+ }
+
+ for(Iterator conflictIter = conflicts.keySet().iterator(); conflictIter.hasNext();) {
+ ModuleId conflictKey = (ModuleId) conflictIter.next();
+ manager.addMessage(conflictKey, "Conflict on module " + conflictKey.getOrganisation() + "#" + conflictKey.getName(),
+ conflicts.get(conflictKey), IMessageProvider.ERROR);
+ }
+ }
+
+ public void setMessageManager(IMessageManager manager) {
+ this.manager = manager;
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/ResolveVisualizerContentProvider.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/ResolveVisualizerContentProvider.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/ResolveVisualizerContentProvider.java (revision 0)
@@ -0,0 +1,71 @@
+package org.apache.ivyde.resolvevisualizer;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.ivyde.resolvevisualizer.model.IIvyNodeElementFilter;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.zest.core.viewers.IGraphEntityContentProvider;
+
+public class ResolveVisualizerContentProvider implements IGraphEntityContentProvider {
+ Collection/**/ filters = new HashSet/**/();
+
+ // Returns all entities that should be linked with the given entity
+ public Object[] getConnectedTo(Object entity) {
+ return filter(((IvyNodeElement) entity).getDependencies());
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if(inputElement == null) {
+ return new Object[] {};
+ }
+ else
+ {
+ IvyNodeElement inputNode = (IvyNodeElement) inputElement;
+ List elements = Arrays.asList(filter(inputNode.getDeepDependencies()));
+ Collections.sort(elements, new IvyNodeElementComparator());
+ return elements.toArray();
+ }
+ }
+
+ public IvyNodeElement[] filter(IvyNodeElement[] deepDependencies) {
+ IvyNodeElement[] filtered = deepDependencies;
+ for(Iterator iter = filters.iterator(); iter.hasNext();) {
+ IIvyNodeElementFilter filter = (IIvyNodeElementFilter) iter.next();
+ filtered = filter.filter(filtered); // I love this line
+ }
+
+ return filtered;
+ }
+
+ public void addFilter(IIvyNodeElementFilter filter) {
+ filters.add(filter);
+ }
+
+ public void dispose() {
+ // nothing to dispose
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ private class IvyNodeElementComparator implements Comparator {
+ public int compare(Object arg1, Object arg2) {
+ IvyNodeElement element1 = (IvyNodeElement) arg1;
+ IvyNodeElement element2 = (IvyNodeElement) arg2;
+
+ if(element1.getDepth() > element2.getDepth())
+ return -1;
+ else if(element1.getDepth() < element2.getDepth())
+ return 1;
+
+ return element1.getModuleRevisionId().toString().compareTo(element2.getModuleRevisionId().toString());
+ }
+ }
+}
\ No newline at end of file
Index: src/java/org/apache/ivyde/resolvevisualizer/ResolveVisualizerForm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/ResolveVisualizerForm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/ResolveVisualizerForm.java (revision 0)
@@ -0,0 +1,514 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Set;
+
+import org.apache.ivyde.eclipse.ui.views.ResolveVisualizerView;
+import org.apache.ivyde.resolvevisualizer.label.AllCallersAlgorithm;
+import org.apache.ivyde.resolvevisualizer.label.AllDependencyAlgorithm;
+import org.apache.ivyde.resolvevisualizer.label.AllRootPathsAlgorithm;
+import org.apache.ivyde.resolvevisualizer.label.SameModuleIdAlgorithm;
+import org.apache.ivyde.resolvevisualizer.label.ShortestRootPathAlgorithm;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElementFilterAdapter;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.parts.ScrollableThumbnail;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+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.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IMessage;
+import org.eclipse.ui.forms.ManagedForm;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+import org.eclipse.zest.core.viewers.GraphViewer;
+import org.eclipse.zest.core.widgets.Graph;
+
+public class ResolveVisualizerForm {
+ public static final String HeaderText = "Ivy Resolve Visualization";
+
+ private FormToolkit toolkit;
+ private GraphViewer viewer;
+ private ScrolledForm form;
+ private ManagedForm managedForm;
+ private ResolveVisualizerView view;
+
+ private Label searchLabel;
+ private Text searchBox;
+
+ private SashForm sash;
+
+ // various auto-select options
+ private Button showAllDependencies;
+ private Button showAllCallers;
+ private Button showShortestRootPath;
+ private Button showAllRootPaths;
+ private Button showSameModuleId;
+
+ private Button evictionFilterEnablement;
+ private Button depthLimitFilterEnablement;
+ private Spinner depthLimit;
+
+ private ThumbnailNavigator thumbnailNavigator;
+
+ private DepthFilter depthFilter = new DepthFilter();
+ private EvictionFilter evictionFilter = new EvictionFilter();
+
+ public ResolveVisualizerForm(Composite parent, FormToolkit toolkit, ResolveVisualizerView view) {
+ this.toolkit = toolkit;
+ this.view = view;
+ form = this.toolkit.createScrolledForm(parent);
+ managedForm = new ManagedForm(this.toolkit, this.form);
+ createHeaderRegion(form);
+ FillLayout layout = new FillLayout();
+ layout.marginHeight = 10;
+ layout.marginWidth = 4;
+ form.getBody().setLayout(layout);
+
+ this.toolkit.decorateFormHeading(this.form.getForm());
+ createSash(form.getBody());
+
+ view.getContentProvider().addFilter(depthFilter);
+ view.getContentProvider().addFilter(evictionFilter);
+ }
+
+ /**
+ * Creates the section of the form where the graph is drawn
+ *
+ * @param parent
+ */
+ private void createGraphSection(Composite parent) {
+ Section section = this.toolkit.createSection(parent, Section.TITLE_BAR);
+ thumbnailNavigator = new ThumbnailNavigator(section, SWT.NONE);
+ viewer = new InternalGraphViewer(thumbnailNavigator, SWT.NONE);
+ viewer.getGraphControl().setVerticalScrollBarVisibility(FigureCanvas.NEVER);
+ viewer.getGraphControl().setHorizontalScrollBarVisibility(FigureCanvas.NEVER);
+ thumbnailNavigator.setGraph((Graph)viewer.getControl());
+ thumbnailNavigator.setSize(100, 25);
+ section.setClient(thumbnailNavigator);
+ }
+
+ private void createHeaderRegion(ScrolledForm form) {
+ Composite headClient = new Composite(form.getForm().getHead(), SWT.NULL);
+ GridLayout glayout = new GridLayout();
+ glayout.marginWidth = glayout.marginHeight = 0;
+ glayout.numColumns = 3;
+ headClient.setLayout(glayout);
+ headClient.setBackgroundMode(SWT.INHERIT_DEFAULT);
+ searchLabel = new Label(headClient, SWT.NONE);
+ searchLabel.setText("Search:");
+ searchBox = toolkit.createText(headClient, "");
+ GridData data = new GridData();
+ data.widthHint = 300;
+ searchBox.setLayoutData(data);
+
+ toolkit.paintBordersFor(headClient);
+ form.setHeadClient(headClient);
+ form.setText(HeaderText);
+ enableSearchBox(false);
+
+ form.getForm().addMessageHyperlinkListener(new HyperlinkAdapter() {
+ public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+ String title = e.getLabel();
+ Object href = e.getHref();
+ if (href instanceof IMessage[] && ((IMessage[]) href).length > 1) {
+ Point hl = ((Control) e.widget).toDisplay(0, 0);
+ hl.x += 10;
+ hl.y += 10;
+ final Shell shell = new Shell(ResolveVisualizerForm.this.form.getShell(), SWT.ON_TOP | SWT.TOOL);
+ shell.setImage(getImage(ResolveVisualizerForm.this.form.getMessageType()));
+ shell.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ layout.verticalSpacing = 0;
+ shell.setText(title);
+ shell.setLayout(layout);
+ Link link = new Link(shell, SWT.NONE);
+ link.setText("close");
+ GridData data = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
+ link.setLayoutData(data);
+ link.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ shell.close();
+ }
+ });
+ Group group = new Group(shell, SWT.NONE);
+ data = new GridData(SWT.LEFT, SWT.TOP, true, true);
+ group.setLayoutData(data);
+ group.setLayout(layout);
+ group.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ FormText text = toolkit.createFormText(group, true);
+ configureFormText(ResolveVisualizerForm.this.form.getForm(), text);
+ if (href instanceof IMessage[]) {
+ text.setText(createFormTextContent((IMessage[]) href), true, false);
+ }
+
+ shell.setLocation(hl);
+ shell.pack();
+ shell.open();
+ } else if (href instanceof IMessage[]) {
+ IMessage oneMessage = ((IMessage[]) href)[0];
+ Set/**/ conflicts = (Set/**/) oneMessage.getData();
+ if (conflicts != null) {
+ viewer.setSelection(new StructuredSelection(new ArrayList(conflicts)));
+ }
+ }
+ }
+ });
+ }
+
+ public void enableSearchBox(boolean enable) {
+ this.searchLabel.setEnabled(enable);
+ this.searchBox.setEnabled(enable);
+ }
+
+ /**
+ * Creates the sash form to separate the graph from the controls.
+ *
+ * @param parent
+ */
+ private void createSash(Composite parent) {
+ sash = new SashForm(parent, SWT.NONE);
+ this.toolkit.paintBordersFor(parent);
+
+ createGraphSection(sash);
+ createOptionsSection(sash);
+ sash.setWeights(new int[] { 10, 2 });
+ }
+
+ private void createOptionsSection(Composite parent) {
+ Section controls = this.toolkit.createSection(parent, Section.TITLE_BAR | Section.EXPANDED);
+
+ controls.setText("Options");
+ Composite controlComposite = new Composite(controls, SWT.NONE) {
+ public Point computeSize(int hint, int hint2, boolean changed) {
+ return new Point(0, 0);
+ }
+ };
+ this.toolkit.adapt(controlComposite);
+ controlComposite.setLayout(new GridLayout());
+
+ Section autoSelectOptions = this.toolkit.createSection(controlComposite, Section.EXPANDED);
+ autoSelectOptions.setText("Auto Selection");
+ autoSelectOptions.setLayout(new FillLayout());
+ Composite autoSelectOptionsComposite = this.toolkit.createComposite(autoSelectOptions);
+ autoSelectOptionsComposite.setLayout(new TableWrapLayout());
+
+ showShortestRootPath = this.toolkit.createButton(autoSelectOptionsComposite, "Shortest path to root", SWT.RADIO);
+ showShortestRootPath.setLayoutData(new TableWrapData(TableWrapData.FILL));
+ showShortestRootPath.setSelection(true);
+ showShortestRootPath.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ view.setAutoSelectDecorator(new ShortestRootPathAlgorithm());
+ }
+ });
+
+ showAllRootPaths = this.toolkit.createButton(autoSelectOptionsComposite, "All paths to root", SWT.RADIO);
+ showAllRootPaths.setLayoutData(new TableWrapData(TableWrapData.FILL));
+ showAllRootPaths.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ view.setAutoSelectDecorator(new AllRootPathsAlgorithm());
+ }
+ });
+
+ showAllCallers = this.toolkit.createButton(autoSelectOptionsComposite, "All callers", SWT.RADIO);
+ showAllCallers.setLayoutData(new TableWrapData(TableWrapData.FILL));
+ showAllCallers.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ view.setAutoSelectDecorator(new AllCallersAlgorithm());
+ }
+ });
+
+ showAllDependencies = this.toolkit.createButton(autoSelectOptionsComposite, "All dependencies", SWT.RADIO);
+ showAllDependencies.setLayoutData(new TableWrapData(TableWrapData.FILL));
+ showAllDependencies.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ view.setAutoSelectDecorator(new AllDependencyAlgorithm());
+ }
+ });
+
+ showSameModuleId = this.toolkit.createButton(autoSelectOptionsComposite, "Other revisions", SWT.RADIO);
+ showSameModuleId.setLayoutData(new TableWrapData(TableWrapData.FILL));
+ showSameModuleId.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ view.setAutoSelectDecorator(new SameModuleIdAlgorithm());
+ }
+ });
+
+ autoSelectOptions.setClient(autoSelectOptionsComposite);
+
+ Section filterOptions = this.toolkit.createSection(controlComposite, Section.EXPANDED);
+ filterOptions.setText("Filter Options");
+ filterOptions.setLayout(new FillLayout());
+ Composite filterOptionsComposite = this.toolkit.createComposite(filterOptions);
+ filterOptionsComposite.setLayout(new TableWrapLayout());
+
+ evictionFilterEnablement = this.toolkit.createButton(filterOptionsComposite, "Hide evicted nodes", SWT.CHECK);
+ evictionFilterEnablement.setLayoutData(new TableWrapData(TableWrapData.FILL));
+ evictionFilterEnablement.setSelection(true);
+ evictionFilter.setEnabled(true);
+ evictionFilterEnablement.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if(evictionFilterEnablement.getSelection()) {
+ evictionFilter.setEnabled(true);
+ view.refresh();
+ }
+ else {
+ evictionFilter.setEnabled(false);
+ view.refresh();
+ }
+ }
+ });
+
+ depthLimitFilterEnablement = this.toolkit.createButton(filterOptionsComposite, "Limit depth", SWT.CHECK);
+ depthLimitFilterEnablement.setLayoutData(new TableWrapData(TableWrapData.FILL));
+ depthLimitFilterEnablement.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if(depthLimitFilterEnablement.getSelection()) {
+ depthFilter.setDepth(depthLimit.getSelection());
+ depthFilter.setEnabled(true);
+ view.refresh();
+ depthLimit.setEnabled(true);
+ }
+ else {
+ depthFilter.setEnabled(false);
+ view.refresh();
+ depthLimit.setEnabled(false);
+ }
+ }
+ });
+
+ depthLimit = new Spinner(filterOptionsComposite, 0);
+ toolkit.adapt(depthLimit);
+ depthLimit.setMinimum(1);
+ depthLimit.setSelection(2);
+ depthLimit.setIncrement(1);
+ depthLimit.setSize(150,40);
+ depthLimit.setBackground(new Color(Display.getDefault(), 216, 228, 248));
+ depthLimit.setEnabled(false);
+ depthLimit.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ depthFilter.setDepth(depthLimit.getSelection());
+ depthFilter.setEnabled(true);
+ view.refresh();
+ }
+ });
+
+ filterOptions.setClient(filterOptionsComposite);
+
+ controls.setClient(controlComposite);
+ }
+
+ public GraphViewer getGraphViewer() {
+ return viewer;
+ }
+
+ public ScrolledForm getForm() {
+ return form;
+ }
+
+ public Text getSearchBox() {
+ return this.searchBox;
+ }
+
+ private class InternalGraphViewer extends GraphViewer {
+ public InternalGraphViewer(Composite parent, int style) {
+ super(parent, style);
+ Graph graph = new Graph(parent, style) {
+ public Point computeSize(int hint, int hint2, boolean changed) {
+ return new Point(0, 0);
+ }
+ };
+ setControl(graph);
+ }
+ }
+
+ private static class ThumbnailNavigator extends Composite {
+ FigureCanvas thumbnail;
+ ScrollableThumbnail tb;
+
+ public ThumbnailNavigator(Composite parent, int style) {
+ super(parent, style);
+ this.setLayout(new FormLayout());
+ createZoomableCanvas(this);
+ }
+
+ public void setGraph(Graph graph) {
+ if (graph.getParent() != this) {
+ throw new AssertionError("Graph must be a child of this zoomable composite.");
+ }
+ createContents(graph);
+ tb.setViewport(graph.getViewport());
+ tb.setSource(graph.getContents());
+ }
+
+ private void createZoomableCanvas(Composite parent) {
+ FormData data = new FormData();
+ data.top = new FormAttachment(100,-100);
+ data.left = new FormAttachment(100,-100);
+ data.right = new FormAttachment(100,0);
+ data.bottom = new FormAttachment(100,0);
+
+ thumbnail = new FigureCanvas(parent, SWT.NONE);
+ thumbnail.setBackground(ColorConstants.white);
+ thumbnail.setLayoutData(data);
+
+ tb = new ScrollableThumbnail();
+ tb.setBorder(new LineBorder(1));
+ thumbnail.setContents(tb);
+ }
+
+ private void createContents(Control control) {
+ FormData data = new FormData();
+ data.top = new FormAttachment(0,0);
+ data.left = new FormAttachment(0,0);
+ data.right = new FormAttachment(100,0);
+ data.bottom = new FormAttachment(100,0);
+ control.setParent(this);
+ control.setLayoutData(data);
+ }
+
+ }
+
+ private class DepthFilter extends IvyNodeElementFilterAdapter {
+ private int depth = 2;
+
+ public boolean accept(IvyNodeElement unfiltered) {
+ return unfiltered.getDepth() - view.getCurrentRoot().getDepth() <= depth;
+ }
+
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+ }
+
+ private class EvictionFilter extends IvyNodeElementFilterAdapter {
+ public boolean accept(IvyNodeElement unfiltered) {
+ return !unfiltered.isEvicted();
+ }
+ }
+
+ public ManagedForm getManagedForm() {
+ return managedForm;
+ }
+
+ private Image getImage(int type) {
+ switch (type) {
+ case IMessageProvider.ERROR:
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_ERROR_TSK);
+ case IMessageProvider.WARNING:
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_WARN_TSK);
+ case IMessageProvider.INFORMATION:
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_INFO_TSK);
+ }
+ return null;
+ }
+
+ private void configureFormText(final Form form, FormText text) {
+ text.addHyperlinkListener(new HyperlinkAdapter() {
+ public void linkActivated(HyperlinkEvent e) {
+ String is = (String) e.getHref();
+ try {
+ ((FormText) e.widget).getShell().dispose();
+ int index = Integer.parseInt(is);
+ IMessage[] messages = form.getChildrenMessages();
+ IMessage message = messages[index];
+ Set/**/ conflicts = (Set/**/) message.getData();
+ if (conflicts != null) {
+ viewer.setSelection(new StructuredSelection(new ArrayList(conflicts)));
+ }
+ } catch (NumberFormatException ex) {
+ }
+ }
+ });
+ text.setImage("error", getImage(IMessageProvider.ERROR));
+ text.setImage("warning", getImage(IMessageProvider.WARNING));
+ text.setImage("info", getImage(IMessageProvider.INFORMATION));
+ }
+
+ String createFormTextContent(IMessage[] messages) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.println("");
+ pw.flush();
+ return sw.toString();
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/AllCallersAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/AllCallersAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/AllCallersAlgorithm.java (revision 0)
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Map;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.zest.core.viewers.EntityConnectionData;
+
+public class AllCallersAlgorithm extends LabelDecoratorAlgorithmAdapter {
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ if (selected != null) {
+ highlightEntities.put(selected, entityColor);
+ IvyNodeElement[] directCallers = selected.getCallers();
+ for (int i = 0; i < directCallers.length; i++) {
+ highlightRelationships.put(new EntityConnectionData(directCallers[i], selected), relationshipColor);
+ highlightEntities.put(directCallers[i], entityColor);
+ highlightEntities.put(directCallers[i], entityColor);
+ }
+ }
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/AllDependencyAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/AllDependencyAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/AllDependencyAlgorithm.java (revision 0)
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Map;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.zest.core.viewers.EntityConnectionData;
+
+public class AllDependencyAlgorithm extends LabelDecoratorAlgorithmAdapter {
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ if(selected != null) {
+ highlightDependenciesRecursive(selected, highlightRelationships, highlightEntities);
+ }
+ }
+
+ private void highlightDependenciesRecursive(IvyNodeElement node,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ highlightEntities.put(node, entityColor);
+
+ IvyNodeElement[] directDependencies = node.getDependencies();
+ for(int i = 0; i < directDependencies.length; i++) {
+ highlightRelationships.put(new EntityConnectionData(node, directDependencies[i]), relationshipColor);
+ highlightDependenciesRecursive(directDependencies[i], highlightRelationships, highlightEntities);
+ }
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/AllRootPathsAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/AllRootPathsAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/AllRootPathsAlgorithm.java (revision 0)
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Map;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.zest.core.viewers.EntityConnectionData;
+
+public class AllRootPathsAlgorithm extends LabelDecoratorAlgorithmAdapter {
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ if (selected != null) {
+ highlightCallersRecursive(selected, highlightRelationships, highlightEntities);
+ }
+ }
+
+ private void highlightCallersRecursive(IvyNodeElement node,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ highlightEntities.put(node, entityColor);
+ IvyNodeElement[] directCallers = node.getCallers();
+ for(int i = 0; i < directCallers.length; i++) {
+ highlightRelationships.put(new EntityConnectionData(directCallers[i], node), relationshipColor);
+ highlightCallersRecursive(directCallers[i], highlightRelationships, highlightEntities);
+ }
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/ConfigurationConflictAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/ConfigurationConflictAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/ConfigurationConflictAlgorithm.java (revision 0)
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Map;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.zest.core.widgets.ZestStyles;
+
+public class ConfigurationConflictAlgorithm extends LabelDecoratorAlgorithmAdapter {
+ public ConfigurationConflictAlgorithm() {
+ // set default colors for this algorithm
+ entityColor = new Color(null, 215, 27, 27);
+ relationshipColor = new ConnectionStyle(ZestStyles.CONNECTIONS_SOLID,
+ ColorConstants.red, 1, false);
+ }
+
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map highlightRelationships, Map highlightEntities) {
+ IvyNodeElement[] deepDependencies = root.getDeepDependencies();
+ for(int i = 0; i < deepDependencies.length; i++) {
+ if(deepDependencies[i].getConflicts().length > 0) {
+ highlightEntities.put(deepDependencies[i], entityColor);
+ }
+ }
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/ConnectionStyle.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/ConnectionStyle.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/ConnectionStyle.java (revision 0)
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.zest.core.widgets.ZestStyles;
+
+public class ConnectionStyle {
+ private static final Color DARK_RED = new Color(Display.getDefault(), 127, 0, 0);
+
+ private int lineWidth = 1;
+ private Color highlightColor = DARK_RED;
+ private int connectionStyle = ZestStyles.CONNECTIONS_SOLID;
+ private boolean revealOnHighlight = true;
+
+ /**
+ * Accept the defaults
+ */
+ public ConnectionStyle() {
+ }
+
+ public ConnectionStyle(int connectionStyle, Color highlightColor, int lineWidth,
+ boolean revealOnHighlight) {
+ super();
+ this.connectionStyle = connectionStyle;
+ this.highlightColor = highlightColor;
+ this.lineWidth = lineWidth;
+ this.revealOnHighlight = revealOnHighlight;
+ }
+
+ public static Color getDARK_RED() {
+ return DARK_RED;
+ }
+
+ public int getLineWidth() {
+ return lineWidth;
+ }
+
+ public Color getHighlightColor() {
+ return highlightColor;
+ }
+
+ public int getConnectionStyle() {
+ return connectionStyle;
+ }
+
+ public boolean isRevealOnHighlight() {
+ return revealOnHighlight;
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/DirectDependenciesAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/DirectDependenciesAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/DirectDependenciesAlgorithm.java (revision 0)
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Map;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.zest.core.viewers.EntityConnectionData;
+
+public class DirectDependenciesAlgorithm extends LabelDecoratorAlgorithmAdapter {
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ if(selected != null) {
+ highlightEntities.put(root, entityColor);
+ IvyNodeElement[] dependencies = root.getDependencies();
+ for(int i = 0; i < dependencies.length; i++) {
+ highlightEntities.put(dependencies[i], entityColor);
+ highlightRelationships.put(
+ new EntityConnectionData(root, dependencies[i]),
+ relationshipColor);
+ }
+ }
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/ILabelDecoratorAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/ILabelDecoratorAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/ILabelDecoratorAlgorithm.java (revision 0)
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Map;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+
+public interface ILabelDecoratorAlgorithm {
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities);
+}
\ No newline at end of file
Index: src/java/org/apache/ivyde/resolvevisualizer/label/LabelDecoratorAlgorithmAdapter.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/LabelDecoratorAlgorithmAdapter.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/LabelDecoratorAlgorithmAdapter.java (revision 0)
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.swt.graphics.Color;
+
+
+public abstract class LabelDecoratorAlgorithmAdapter implements ILabelDecoratorAlgorithm {
+ protected Color entityColor = ColorConstants.orange;
+ protected ConnectionStyle relationshipColor = new ConnectionStyle();
+
+ /**
+ * Specify custom colors for this algorithm instance.
+ * @param entityColor
+ * @param relationshipColor
+ */
+ public void setStyles(Color entityColor, ConnectionStyle relationshipColor) {
+ this.entityColor = entityColor;
+ this.relationshipColor = relationshipColor;
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/SameModuleIdAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/SameModuleIdAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/SameModuleIdAlgorithm.java (revision 0)
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Map;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+
+public class SameModuleIdAlgorithm extends LabelDecoratorAlgorithmAdapter {
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ if (selected != null) {
+ IvyNodeElement[] deepDependencies = root.getDeepDependencies();
+ for(int i = 0; i < deepDependencies.length; i++) {
+ if(deepDependencies[i].getOrganization().equals(selected.getOrganization()) &&
+ deepDependencies[i].getName().equals(selected.getName())) {
+ highlightEntities.put(deepDependencies[i], entityColor);
+ }
+ }
+ }
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/label/ShortestRootPathAlgorithm.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/label/ShortestRootPathAlgorithm.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/label/ShortestRootPathAlgorithm.java (revision 0)
@@ -0,0 +1,78 @@
+package org.apache.ivyde.resolvevisualizer.label;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ivyde.resolvevisualizer.model.IvyNodeElement;
+import org.eclipse.zest.core.viewers.EntityConnectionData;
+
+public class ShortestRootPathAlgorithm extends LabelDecoratorAlgorithmAdapter {
+ public void calculateHighlighted(IvyNodeElement root, IvyNodeElement selected,
+ Map/**/ highlightRelationships,
+ Map/**/ highlightEntities) {
+ // Calculates the smart path.
+ if (selected != null) {
+ IvyNodeElement[] path = getShortestPathToDescendent(root, selected);
+ if (path.length > 1) {
+ for (int i = 0; i < path.length-1; i++) {
+ EntityConnectionData entityConnectionData = new EntityConnectionData(path[i+1], path[i]);
+ highlightRelationships.put(entityConnectionData, relationshipColor);
+ highlightEntities.put(path[i], entityColor);
+ }
+ highlightEntities.put(path[path.length-1], entityColor);
+ }
+// highlightEntities.put(root, DEFAULT_ENTITY_HIGHLIGHT);
+ }
+ }
+
+ public IvyNodeElement[] getShortestPathToDescendent(IvyNodeElement root, IvyNodeElement target) {
+ LinkedList/**/ q = new LinkedList/**/();
+ Set/**/ orderedSet = new HashSet/**/();
+ LinkedList/**/ orderedList = new LinkedList/**/();
+ q.add(root);
+ while (!q.isEmpty()) {
+ IvyNodeElement head = (IvyNodeElement) q.remove(0);
+ if (!orderedSet.contains(head)) {
+ orderedSet.add(head);
+ orderedList.add(head);
+ q.addAll(Arrays.asList(head.getDependencies()));
+ }
+ }
+ IvyNodeElement[] path = fixedWeightDijkstraAlgorithm(orderedList, root, target);
+ return path;
+ }
+
+ private IvyNodeElement[] fixedWeightDijkstraAlgorithm(LinkedList q, IvyNodeElement s, IvyNodeElement t) {
+ HashMap/**/ previous = new HashMap/**/();
+ HashMap/**/ dValues = new HashMap/**/();
+ for (Iterator/**/ iter = q.iterator(); iter.hasNext();) {
+ dValues.put(iter.next(), new Integer(Integer.MAX_VALUE / 10));
+ }
+ dValues.put(s, new Integer(0));
+
+ while (!q.isEmpty()) {
+ IvyNodeElement head = (IvyNodeElement) q.remove(0);
+ IvyNodeElement[] outgoing = head.getDependencies();
+ for (int i = 0; i < outgoing.length; i++) {
+ IvyNodeElement v = outgoing[i];
+ if (((Integer) dValues.get(head)).intValue() + 1 < ((Integer) dValues.get(v)).intValue()) {
+ previous.put(v, head);
+ dValues.put(v, new Integer(((Integer) dValues.get(head)).intValue() + 1));
+ }
+ }
+ }
+ LinkedList/**/ path = new LinkedList/**/();
+ IvyNodeElement currentNode = t;
+ while (previous.containsKey(currentNode)) {
+ path.add(currentNode);
+ currentNode = (IvyNodeElement) previous.get(currentNode);
+ }
+ path.add(currentNode);
+ return (IvyNodeElement[]) path.toArray(new IvyNodeElement[path.size()]);
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/model/IIvyNodeElementFilter.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/model/IIvyNodeElementFilter.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/model/IIvyNodeElementFilter.java (revision 0)
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.model;
+
+public interface IIvyNodeElementFilter {
+ public IvyNodeElement[] filter(IvyNodeElement[] unfiltered);
+ public boolean isEnabled();
+ public void setEnabled(boolean enabled);
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElement.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElement.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElement.java (revision 0)
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.model;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+
+/**
+ * Assists in the further separation of concerns between the
+ * view and the Ivy resolve report. The view looks at the IvyNode
+ * in a unique way that can lead to expensive operations if we do
+ * not achieve this separation.
+ */
+public class IvyNodeElement {
+ private ModuleRevisionId moduleRevisionId;
+ private boolean evicted = false;
+ private int depth = Integer.MAX_VALUE / 10;
+ private Collection/**/ dependencies = new HashSet/**/();
+ private Collection/**/ callers = new HashSet/**/();
+ private Collection/**/ conflicts = new HashSet/**/();
+
+ /**
+ * The caller configurations that caused this node to be reached in the resolution, grouped by caller.
+ */
+ private Map/**/ callerConfigurationMap = new HashMap/**/();
+
+ /**
+ * We try to avoid building the list of this nodes deep dependencies by storing them in this cache by depth level.
+ */
+ private IvyNodeElement[] deepDependencyCache;
+
+ public boolean equals(Object obj) {
+ if(obj instanceof IvyNodeElement) {
+ IvyNodeElement elem = (IvyNodeElement) obj;
+ if(elem.getOrganization().equals(getOrganization()) && elem.getName().equals(getName()) && elem.getRevision().equals(getRevision()))
+ return true;
+ }
+ return false;
+ }
+
+ public IvyNodeElement[] getDependencies() {
+ return (IvyNodeElement[]) dependencies.toArray(new IvyNodeElement[dependencies.size()]);
+ }
+
+ /**
+ * Recursive dependency retrieval
+ * @return The array of nodes that represents a node's immediate and transitive dependencies down to
+ * an arbitrary depth.
+ */
+ public IvyNodeElement[] getDeepDependencies() {
+ if(deepDependencyCache == null) {
+ deepDependencyCache = (IvyNodeElement[]) getDeepDependencies(this).toArray(new IvyNodeElement[] {});
+ }
+ return deepDependencyCache;
+ }
+
+ /**
+ * Recursive dependency retrieval
+ * @param node
+ * @return
+ */
+ private Collection/**/ getDeepDependencies(IvyNodeElement node) {
+ Collection/**/ deepDependencies = new HashSet/**/();
+ deepDependencies.add(node);
+
+ IvyNodeElement[] directDependencies = node.getDependencies();
+ for(int i = 0; i < directDependencies.length; i++) {
+ deepDependencies.addAll(getDeepDependencies(directDependencies[i]));
+ }
+
+ return deepDependencies;
+ }
+
+ /**
+ * @return An array of configurations by which this module was resolved
+ */
+ public String[] getCallerConfigurations(IvyNodeElement caller) {
+ return (String[]) callerConfigurationMap.get(caller);
+ }
+
+ public void setCallerConfigurations(IvyNodeElement caller, String[] configurations) {
+ callerConfigurationMap.put(caller, configurations);
+ }
+
+ public String getOrganization() {
+ return moduleRevisionId.getOrganisation();
+ }
+
+ public String getName() {
+ return moduleRevisionId.getName();
+ }
+
+ public String getRevision() {
+ return moduleRevisionId.getRevision();
+ }
+
+ public boolean isEvicted() {
+ return evicted;
+ }
+
+ public void setEvicted(boolean evicted) {
+ this.evicted = evicted;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ /**
+ * Set this node's depth and recursively update the node's children to relative to the new
+ * value.
+ *
+ * @param depth
+ */
+ public void setDepth(int depth) {
+ this.depth = depth;
+ for(Iterator iter = dependencies.iterator(); iter.hasNext();) {
+ IvyNodeElement dependency = (IvyNodeElement) iter.next();
+ dependency.setDepth(depth + 1);
+ }
+ }
+
+ public IvyNodeElement[] getConflicts() {
+ return (IvyNodeElement[]) conflicts.toArray(new IvyNodeElement[conflicts.size()]);
+ }
+
+ public void setConflicts(Collection conflicts) {
+ this.conflicts = conflicts;
+ }
+
+ public ModuleRevisionId getModuleRevisionId() {
+ return moduleRevisionId;
+ }
+
+ public void setModuleRevisionId(ModuleRevisionId moduleRevisionId) {
+ this.moduleRevisionId = moduleRevisionId;
+ }
+
+ public void addCaller(IvyNodeElement caller) {
+ callers.add(caller);
+ caller.dependencies.add(this);
+ }
+
+ public IvyNodeElement[] getCallers() {
+ return (IvyNodeElement[]) callers.toArray(new IvyNodeElement[callers.size()]);
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElementAdapter.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElementAdapter.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElementAdapter.java (revision 0)
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ivy.core.module.id.ModuleId;
+import org.apache.ivy.core.report.ResolveReport;
+import org.apache.ivy.core.resolve.IvyNode;
+import org.apache.ivy.core.resolve.IvyNodeCallers.Caller;
+
+public class IvyNodeElementAdapter {
+ /**
+ * Adapt all dependencies and evictions from the ResolveReport.
+ * @param report
+ * @return the root node adapted from the ResolveReport
+ */
+ public static IvyNodeElement adapt(ResolveReport report) {
+ Map/**/ resolvedNodes = new HashMap/**/();
+
+ IvyNodeElement root = new IvyNodeElement();
+ root.setModuleRevisionId(report.getModuleDescriptor().getModuleRevisionId());
+ resolvedNodes.put(report.getModuleDescriptor().getModuleRevisionId(), root);
+
+ List/**/ dependencies = report.getDependencies();
+
+ // First pass - build the map of resolved nodes by revision id
+ for(Iterator iter = dependencies.iterator(); iter.hasNext();) {
+ IvyNode node = (IvyNode) iter.next();
+ if(node.getAllEvictingNodes() != null) {
+ // Nodes that are evicted as a result of conf inheritance still appear
+ // as dependencies, but with eviction data. They also appear as evictions.
+ // We map them as evictions rather than dependencies.
+ continue;
+ }
+ IvyNodeElement nodeElement = new IvyNodeElement();
+ nodeElement.setModuleRevisionId(node.getResolvedId());
+ resolvedNodes.put(node.getResolvedId(), nodeElement);
+ }
+
+ // Second pass - establish relationships between the resolved nodes
+ for(Iterator iter = dependencies.iterator(); iter.hasNext();) {
+ IvyNode node = (IvyNode) iter.next();
+ if(node.getAllEvictingNodes() != null) {
+ continue; // see note above
+ }
+
+ IvyNodeElement nodeElement = (IvyNodeElement) resolvedNodes.get(node.getResolvedId());
+ Caller[] callers = node.getAllRealCallers();
+ for(int i = 0; i < callers.length; i++) {
+ IvyNodeElement caller = (IvyNodeElement) resolvedNodes.get(callers[i].getModuleRevisionId());
+ if(caller != null) {
+ nodeElement.addCaller(caller);
+ nodeElement.setCallerConfigurations(caller, callers[i].getCallerConfigurations());
+ }
+ }
+ }
+
+ IvyNode[] evictions = report.getEvictedNodes();
+ for(int i = 0; i < evictions.length; i++) {
+ IvyNode eviction = evictions[i];
+ IvyNodeElement evictionElement = new IvyNodeElement();
+ evictionElement.setModuleRevisionId(eviction.getResolvedId());
+ evictionElement.setEvicted(true);
+
+ Caller[] callers = eviction.getAllCallers();
+ for(int j = 0; j < callers.length; j++) {
+ IvyNodeElement caller = (IvyNodeElement) resolvedNodes.get(callers[j].getModuleRevisionId());
+ if(caller != null) {
+ evictionElement.addCaller(caller);
+ evictionElement.setCallerConfigurations(caller, callers[j].getCallerConfigurations());
+ }
+ }
+ }
+
+ // Recursively set depth starting at root
+ root.setDepth(0);
+ findConflictsBeneathNode(root);
+
+ return root;
+ }
+
+ /**
+ * Derives configuration conflicts that exist between node and all of its descendant dependencies.
+ * @param node
+ */
+ private static void findConflictsBeneathNode(IvyNodeElement node) {
+ // Derive conflicts
+ Map/*>*/ moduleRevisionMap = new HashMap/*>*/();
+ IvyNodeElement[] deepDependencies = node.getDeepDependencies();
+ for(int i = 0; i < deepDependencies.length; i++) {
+ if(deepDependencies[i].isEvicted())
+ continue;
+
+ ModuleId moduleId = deepDependencies[i].getModuleRevisionId().getModuleId();
+ if(moduleRevisionMap.containsKey(moduleId)) {
+ Collection/**/ conflicts = (Collection/**/) moduleRevisionMap.get(moduleId);
+ conflicts.add(deepDependencies[i]);
+ for(Iterator iter = conflicts.iterator(); iter.hasNext();) {
+ IvyNodeElement conflict = (IvyNodeElement) iter.next();
+ conflict.setConflicts(conflicts);
+ }
+ }
+ else {
+ List/**/ immutableMatchingSet = Arrays.asList(new IvyNodeElement[] {deepDependencies[i]});
+ moduleRevisionMap.put(moduleId, new HashSet(immutableMatchingSet));
+ }
+ }
+ }
+}
Index: src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElementFilterAdapter.java
===================================================================
--- src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElementFilterAdapter.java (revision 0)
+++ src/java/org/apache/ivyde/resolvevisualizer/model/IvyNodeElementFilterAdapter.java (revision 0)
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivyde.resolvevisualizer.model;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+public abstract class IvyNodeElementFilterAdapter implements IIvyNodeElementFilter {
+ protected boolean enabled = false;
+
+ public IvyNodeElement[] filter(IvyNodeElement[] unfiltered) {
+ if(!enabled)
+ return unfiltered;
+
+ Collection/**/ filtered = new HashSet/**/();
+ for(int i = 0; i < unfiltered.length; i++) {
+ if(accept(unfiltered[i]))
+ filtered.add(unfiltered[i]);
+ }
+
+ return (IvyNodeElement[]) filtered.toArray(new IvyNodeElement[filtered.size()]);
+ }
+
+ public abstract boolean accept(IvyNodeElement unfiltered);
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+}