package com.redhat.ceylon.eclipse.code.moduledependencies;
import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getModule;
import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getModuleDependenciesForProject;
import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getProjectSourceModules;
import static com.redhat.ceylon.eclipse.java2ceylon.Java2CeylonProxies.modelJ2C;
import static com.redhat.ceylon.eclipse.ui.CeylonPlugin.PLUGIN_ID;
import static com.redhat.ceylon.eclipse.util.EditorUtil.createColor;
import static com.redhat.ceylon.eclipse.util.Highlights.DOC_BACKGROUND;
import static com.redhat.ceylon.eclipse.util.Highlights.getCurrentThemeColor;
import static org.eclipse.core.resources.ResourcesPlugin.getWorkspace;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.Polyline;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.internal.editors.text.EditorsPlugin;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.zest.core.viewers.GraphViewer;
import org.eclipse.zest.core.viewers.IGraphContentProvider;
import org.eclipse.zest.core.viewers.ISelfStyleProvider;
import org.eclipse.zest.core.widgets.GraphConnection;
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.HorizontalTreeLayoutAlgorithm;
import org.eclipse.zest.layouts.algorithms.RadialLayoutAlgorithm;
import org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm;
import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm;
import com.redhat.ceylon.eclipse.code.editor.CeylonEditor;
import com.redhat.ceylon.eclipse.code.navigator.ExternalModuleNode;
import com.redhat.ceylon.eclipse.code.navigator.SourceModuleNode;
import com.redhat.ceylon.eclipse.code.parse.CeylonParseController;
import com.redhat.ceylon.eclipse.core.builder.CeylonNature;
import com.redhat.ceylon.eclipse.ui.CeylonPlugin;
import com.redhat.ceylon.eclipse.ui.CeylonResources;
import com.redhat.ceylon.eclipse.util.EditorUtil;
import com.redhat.ceylon.ide.common.model.BaseIdeModule;
import com.redhat.ceylon.ide.common.model.CeylonProject;
import com.redhat.ceylon.ide.common.model.CeylonProjectBuild;
import com.redhat.ceylon.ide.common.model.ModelListener;
import com.redhat.ceylon.ide.common.model.ModuleDependencies;
import com.redhat.ceylon.ide.common.model.ModuleDependencies.Dependency;
import com.redhat.ceylon.ide.common.model.ModuleDependencies.ModuleReference;
import com.redhat.ceylon.ide.common.model.ModuleDependencies.ModuleWeakReference;
import com.redhat.ceylon.ide.common.typechecker.ExternalPhasedUnit;
import com.redhat.ceylon.ide.common.typechecker.ProjectPhasedUnit;
import com.redhat.ceylon.ide.common.vfs.FileVirtualFile;
import com.redhat.ceylon.model.typechecker.model.Module;
import com.redhat.ceylon.model.typechecker.model.ModuleImport;
public class DependencyGraphView extends ViewPart implements IShowInTarget, ModelListener<IProject, IResource, IFolder, IFile> {
private enum Layout {
spring("Spring"),
radial("Radial"),
horizonatlTree("Horizontal Tree"),
verticalTree("Vertical Tree");
String label;
private Layout(String label) {
this.label = label;
}
@Override
public String toString() {
return label;
}
public LayoutAlgorithm getLayoutAlgorithm() {
switch(this) {
case spring :
SpringLayoutAlgorithm sla = new SpringLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING);
return sla;
case radial :
RadialLayoutAlgorithm rla = new RadialLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING);
rla.setRangeToLayout(-1.41, 1.41);
return rla;
case horizonatlTree :
return new HorizontalTreeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING);
case verticalTree :
return new TreeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING);
}
return null;
}
public final static Layout[] values = Layout.values();
}
static final String ID = PLUGIN_ID + ".view.DependencyGraphView";
private IProject project;
private Map<String, IProject> projectMap = new ConcurrentHashMap<String, IProject>();
private IResourceChangeListener updateProjectComboListener;
private GraphViewer viewer;
private boolean showLanguageModuleVersions = false;
private Combo projectCombo;
private Combo viewCombo;
private Image overridesImage = null;
public void setProject(IProject project) {
if (project!=null) {
this.project = project;
int index =
Arrays.asList(projectCombo.getItems())
.indexOf(project.getName());
projectCombo.select(index);
init();
}
}
class GraphContentProvider implements IGraphContentProvider {
@Override
public void dispose() {}
@Override
public void inputChanged(Viewer viewer,
Object oldInput, Object newInput) {}
@Override
public Object getSource(Object rel) {
assert (rel instanceof Dependency);
return ((Dependency) rel).getSource();
}
@Override
public Object getDestination(Object rel) {
assert (rel instanceof Dependency);
return ((Dependency) rel).getTarget();
}
@Override
public Object[] getElements(Object input) {
return ((ModuleDependencies) input).getAllDependencies().toArray();
}
}
class GraphLabelProvider extends LabelProvider implements ISelfStyleProvider {
@Override
public String getText(Object element) {
if (element instanceof ModuleWeakReference) {
Module module = ((ModuleWeakReference) element).get();
if (module != null) {
return module.getNameAsString() + "\n" + module.getVersion();
}
}
if (element instanceof ModuleReference) {
return ((ModuleReference) element).getIdentifier();
}
return "";
}
private String importPrefix(boolean optional, boolean export, boolean initialUpperCase) {
if (optional) {
return (initialUpperCase ? "O" : "o") + "ptional import";
} else if (export) {
return (initialUpperCase ? "E" : "e") + "xported import";
} else {
return (initialUpperCase ? "L" : "l") + "ocal import";
}
}
@Override
public void selfStyleConnection(Object element,
GraphConnection connection) {
connection.setLineWidth(1);
String tooltipText = "";
boolean overriding = false;
if (element instanceof Dependency) {
Dependency dep = (Dependency) element;
if (dep.optional) {
connection.setConnectionStyle(ZestStyles.CONNECTIONS_DOT);
}
if (dep.exported) {
connection.setLineWidth(4);
}
tooltipText = importPrefix(dep.optional, dep.exported, true);
Object source = dep.getSource();
Object target = dep.getTarget();
if (source instanceof ModuleWeakReference
&& target instanceof ModuleWeakReference) {
Module sourceMod = ((ModuleWeakReference) source).get();
Module targetMod = ((ModuleWeakReference) target).get();
if (sourceMod != null
&& targetMod != null) {
for (ModuleImport mi : sourceMod.getImports()) {
if (mi.getModule().equals(targetMod)) {
ModuleImport overridenImport = mi.getOverridenModuleImport();
if (overridenImport != null) {
overriding = true;
tooltipText += "\nOverrides the import of '" +
overridenImport.getModule().getNameAsString() +
"', version " + overridenImport.getModule().getVersion();
}
break;
}
}
List<ModuleImport> overridenModuleImports = sourceMod.getOverridenImports();
if (overridenModuleImports != null) {
boolean isChanged = true;
for (ModuleImport mi : overridenModuleImports) {
if (mi.getModule().equals(targetMod) &&
mi.isExport() == dep.exported &&
mi.isOptional() == dep.optional) {
isChanged = false;
break;
}
}
if (isChanged) {
overriding = true;
tooltipText += "\nModified by the dependency overrides of the importing module";
}
}
}
}
}
if (overriding) {
connection.setLineColor(connection.getDisplay().getSystemColor(SWT.COLOR_BLUE));
connection.setHighlightColor(connection.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE));
connection.setImage(overridesImage);
} else {
connection.setLineColor(connection.getDisplay().getSystemColor(SWT.COLOR_GRAY));
connection.setHighlightColor(connection.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
}
Label tooltip = new Label(tooltipText);
connection.setTooltip(tooltip);
connection.setConnectionStyle(ZestStyles.CONNECTIONS_DIRECTED);
Connection figure = connection.getConnectionFigure();
if (figure instanceof Polyline) {
((Polyline) figure).setAntialias(SWT.ON);
}
PolygonDecoration decoration = new PolygonDecoration();
decoration.setFill(true);
decoration.setLineWidth(connection.getLineWidth());
decoration.setLineJoin(SWT.JOIN_ROUND);
decoration.setAntialias(SWT.ON);
((PolylineConnection) figure).setTargetDecoration(decoration);
}
@Override
public Image getImage(Object element) {
if (element instanceof ModuleReference) {
return CeylonResources.MODULE;
}
else {
return null;
}
}
@Override
public void selfStyleNode(Object element, GraphNode node) {
if (element instanceof ModuleWeakReference) {
Module module = ((ModuleWeakReference) element).get();
if (module == null) {
node.setVisible(false);
}
else {
node.setForegroundColor(node.getDisplay()
.getSystemColor(SWT.COLOR_BLACK));
String label = "";
if (!module.isAvailable()) {
node.setBackgroundColor(node.getDisplay()
.getSystemColor(SWT.COLOR_GRAY));
node.setHighlightColor(node.getDisplay()
.getSystemColor(SWT.COLOR_DARK_GRAY));
label = "Unresolved module (not visible from any project module)";
}
else if (module.isJava()) {
node.setBackgroundColor(node.getDisplay()
.getSystemColor(SWT.COLOR_CYAN));
node.setHighlightColor(node.getDisplay()
.getSystemColor(SWT.COLOR_DARK_CYAN));
label = "Java archive module";
}
else if (module instanceof BaseIdeModule) {
BaseIdeModule jdtModule = (BaseIdeModule) module;
if (jdtModule.getIsCeylonArchive()) {
node.setBackgroundColor(node.getDisplay()
.getSystemColor(SWT.COLOR_GREEN));
node.setHighlightColor(node.getDisplay()
.getSystemColor(SWT.COLOR_DARK_GREEN));
label = "Ceylon archive module";
}
else if (jdtModule.getIsProjectModule()) {
node.setBackgroundColor(node.getDisplay()
.getSystemColor(SWT.COLOR_YELLOW));
node.setHighlightColor(node.getDisplay()
.getSystemColor(SWT.COLOR_DARK_YELLOW));
label = "Project source module";
}
}
if (showLanguageModuleVersions) {
for (ModuleImport mi : module.getImports()) {
if (mi.getModule() != null
&& mi.getModule().getNameAsString().equals(Module.LANGUAGE_MODULE_NAME)) {
label += "\n - imports language module, version " + mi.getModule().getVersion();
}
}
}
node.setTooltip(new Label(label));
}
}
}
}
@Override
public void createPartControl(Composite parent) {
IPreferenceStore editorPreferenceStore =
EditorsPlugin.getDefault().getPreferenceStore();
if (!editorPreferenceStore.getBoolean(
PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
parent.setBackground(
getCurrentThemeColor(DOC_BACKGROUND));
// createColor(CeylonPlugin.getPreferences(),
// PREFERENCE_COLOR_BACKGROUND));
}
if (!editorPreferenceStore.getBoolean(
PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT)) {
parent.setForeground(
createColor(editorPreferenceStore,
PREFERENCE_COLOR_FOREGROUND));
}
setPartName("Ceylon Module Dependencies");
// setContentDescription("Ceylon module dependencies");
parent.setLayout(new GridLayout(4, false));
initProjectCombo(parent);
initViewCombo(parent);
createViewer(parent);
createMenu();
setProject(projectMap.get(projectCombo.getText()));
modelJ2C().ceylonModel().addModelListener(this);
}
LayoutAlgorithm getCurrentLayoutAlgorithm() {
int index = viewCombo.getSelectionIndex();
if (index > -1) {
return Layout.values[index].getLayoutAlgorithm();
}
return new HorizontalTreeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING);
}
protected void createViewer(Composite parent) {
Image iconImage = CeylonPlugin.imageRegistry.get(CeylonResources.CEYLON_DELETE_IMPORT);
overridesImage = new Image(iconImage.getDevice(), iconImage.getImageData().scaledTo(20, 20));
overridesImage.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
viewer = new GraphViewer(parent, SWT.NONE);
viewer.getGraphControl()
.setNodeStyle(ZestStyles.NODES_NO_LAYOUT_RESIZE);
viewer.setContentProvider(new GraphContentProvider());
viewer.setLabelProvider(new GraphLabelProvider());
viewer.setLayoutAlgorithm(getCurrentLayoutAlgorithm());
viewer.getControl().setLayoutData(GridDataFactory.fillDefaults().span(4, 1).grab(true, true).create());
IPreferenceStore editorPreferenceStore =
EditorsPlugin.getDefault().getPreferenceStore();
if (!editorPreferenceStore.getBoolean(
PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
viewer.getControl().setBackground(
getCurrentThemeColor(DOC_BACKGROUND));
// createColor(CeylonPlugin.getPreferences(),
// PREFERENCE_COLOR_BACKGROUND));
}
if (!editorPreferenceStore.getBoolean(
PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT)) {
viewer.getControl().setForeground(
createColor(editorPreferenceStore,
PREFERENCE_COLOR_FOREGROUND));
}
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
ModuleDependencies deps = (ModuleDependencies) viewer.getInput();
Object selection = event.getSelection();
if (selection instanceof StructuredSelection) {
selection = ((StructuredSelection) selection).getFirstElement();
}
if (selection instanceof ModuleReference) {
for (Dependency dep : deps.getDirectDependencies((ModuleReference) selection)) {
GraphItem item = viewer.findGraphItem((ModuleReference) dep.getTarget());
if (item instanceof GraphNode) {
item.setVisible(true);
item.highlight();
item.unhighlight();
}
}
for (Dependency dep : deps.getDirectReverseDependencies((ModuleReference) selection)) {
GraphItem item = viewer.findGraphItem((ModuleReference) dep.getSource());
if (item instanceof GraphNode) {
item.setVisible(true);
item.highlight();
item.unhighlight();
}
}
} else if (selection instanceof Dependency) {
Dependency dep = (Dependency) selection;
GraphItem item = viewer.findGraphItem((ModuleReference) dep.getSource());
if (item instanceof GraphNode) {
item.setVisible(true);
item.highlight();
item.unhighlight();
}
item = viewer.findGraphItem((ModuleReference) dep.getTarget());
if (item instanceof GraphNode) {
item.setVisible(true);
item.highlight();
item.unhighlight();
}
}
}
});
}
private void initViewCombo(Composite parent) {
org.eclipse.swt.widgets.Label graphLayoutLabel =
new org.eclipse.swt.widgets.Label(parent, SWT.RIGHT | SWT.WRAP);
graphLayoutLabel.setText("Select the graph layout");
GridData gd = GridDataFactory.swtDefaults().align(SWT.END, SWT.CENTER).create();
graphLayoutLabel.setLayoutData(gd);
viewCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
viewCombo.setLayoutData(GridDataFactory.swtDefaults().hint(120, SWT.DEFAULT).create());
viewCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
try {
viewer.setLayoutAlgorithm(getCurrentLayoutAlgorithm());
viewer.applyLayout();
} catch(Exception ex){
e.doit = false;
}
}
});
List<String> items = new ArrayList<String>(Layout.values.length);
for (Layout layout : Layout.values) {
items.add(layout.toString());
}
viewCombo.setItems(items.toArray(new String[0]));
viewCombo.setText(viewCombo.getItem(0));
}
private void initProjectCombo(Composite parent) {
org.eclipse.swt.widgets.Label projectLabel =
new org.eclipse.swt.widgets.Label(parent, SWT.RIGHT | SWT.WRAP);
projectLabel.setText("Display modules for project");
GridData gd = GridDataFactory.swtDefaults().align(SWT.END, SWT.CENTER).create();
projectLabel.setLayoutData(gd);
projectCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
projectCombo.setLayoutData(GridDataFactory.swtDefaults().hint(200, SWT.DEFAULT).create());
projectCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setProject(projectMap.get(projectCombo.getText()));
}
});
updateProjectCombo();
updateProjectComboListener = new IResourceChangeListener() {
@Override
public void resourceChanged(IResourceChangeEvent event) {
if (event.getResource() == null || event.getResource() instanceof IProject) {
updateProjectComboAsync();
}
}
};
getWorkspace().addResourceChangeListener(updateProjectComboListener);
}
private void updateProjectComboAsync() {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (!projectCombo.isDisposed()) {
updateProjectCombo();
}
}
});
}
private void updateProjectCombo() {
projectMap.clear();
IProject[] projects = getWorkspace().getRoot().getProjects();
if (projects != null) {
for (IProject project : projects) {
if (project.isOpen() && CeylonNature.isEnabled(project)) {
projectMap.put(project.getName(), project);
}
}
}
List<String> projectNames = new ArrayList<String>(projectMap.keySet());
// projectNames.add("");
Collections.sort(projectNames);
int selectedIndex = projectCombo.getSelectionIndex();
String selectedProjectName = selectedIndex != -1 ? projectCombo.getItem(selectedIndex) : "";
projectCombo.setItems(projectNames.toArray(new String[]{}));
if (projectNames.contains(selectedProjectName)) {
projectCombo.select(projectNames.indexOf(selectedProjectName));
} else {
projectCombo.select(0);
}
}
protected void createMenu() {
final IMenuManager partMenu =
getViewSite().getActionBars().getMenuManager();
partMenu.add(new Action("Lay Out") {
@Override
public void run() {
viewer.applyLayout();
}
});
partMenu.add(new Action("Show All") {
@Override
public void run() {
viewer.resetFilters();
viewer.refresh();
viewer.applyLayout();
}
});
partMenu.add(new Action("Show language module imports") {
@Override
public void run() {
showLanguageModuleVersions = true;
viewer.refresh();
viewer.applyLayout();
}
});
partMenu.add(new Action("Hide language module imports") {
@Override
public void run() {
showLanguageModuleVersions = false;
viewer.refresh();
viewer.applyLayout();
}
});
final MenuManager viewerMenu = new MenuManager();
viewer.getControl().setMenu(viewerMenu.createContextMenu(viewer.getControl()));
viewerMenu.setRemoveAllWhenShown(true);
viewerMenu.addMenuListener(new IMenuListener() {
@Override
public void menuAboutToShow(IMenuManager manager) {
manager.add(new Action("Show Dependencies Only") {
@Override
public boolean isEnabled() {
IStructuredSelection selection =
(IStructuredSelection)
viewer.getSelection();
return selection.size() == 1
&& selection.getFirstElement() != null;
}
@Override
public void run() {
IStructuredSelection selection =
(IStructuredSelection)
viewer.getSelection();
Object first = selection.getFirstElement();
if (first instanceof ModuleReference) {
final ModuleReference selectedModuleRef =
(ModuleReference) first;
narrowToDependencies(selectedModuleRef);
}
}
});
manager.add(new Action("Show Referencing Modules Only") {
@Override
public boolean isEnabled() {
IStructuredSelection selection =
(IStructuredSelection) viewer.getSelection();
return selection.size() == 1
&& selection.getFirstElement() != null;
}
@Override
public void run() {
IStructuredSelection selection =
(IStructuredSelection) viewer.getSelection();
Object first = selection.getFirstElement();
if (first instanceof ModuleReference) {
final ModuleReference selectedModuleRef =
(ModuleReference) first;
narrowToReferences(selectedModuleRef);
}
}
});
manager.add(new Action("Show All") {
@Override
public void run() {
viewer.resetFilters();
viewer.refresh();
viewer.applyLayout();
}
});
}
});
}
protected void narrowToDependencies(
final ModuleReference selectedModuleRef) {
ModuleDependencies moduleDependencies =
(ModuleDependencies) viewer.getInput();
final Iterable<Module> modulesToShow =
moduleDependencies.getTransitiveDependencies(selectedModuleRef);
viewer.setFilters(new ViewerFilter[] {
new ViewerFilter() {
@Override
public boolean select(Viewer viewer,
Object parentElement, Object element) {
if (element.equals(selectedModuleRef) ||
element instanceof Dependency) {
return true;
}
if (element instanceof ModuleWeakReference) {
Module moduleToSort =
((ModuleWeakReference) element).get();
for (Module moduleToShow : modulesToShow) {
if (moduleToShow.equals(moduleToSort)) {
return true;
}
}
}
return false;
}
}
});
viewer.refresh();
viewer.applyLayout();
}
protected void narrowToReferences(
final ModuleReference selectedModuleRef) {
ModuleDependencies moduleDependencies =
(ModuleDependencies) viewer.getInput();
final Iterable<Module> modulesToShow =
moduleDependencies.getReferencingModules(selectedModuleRef);
viewer.setFilters(new ViewerFilter[] {
new ViewerFilter() {
@Override
public boolean select(Viewer viewer,
Object parentElement, Object element) {
if (element.equals(selectedModuleRef) ||
element instanceof Dependency) {
return true;
}
if (element instanceof ModuleWeakReference) {
Module moduleToSort =
((ModuleWeakReference) element).get();
for (Module moduleToShow : modulesToShow) {
if (moduleToShow.equals(moduleToSort)) {
return true;
}
}
}
return false;
}
}
});
viewer.refresh();
viewer.applyLayout();
}
private void init() {
if (project==null) {
return;
}
ModuleDependencies dependencies =
getModuleDependenciesForProject(project);
if (dependencies == null) {
return;
}
viewer.setInput(dependencies);
}
@Override
public void dispose() {
getWorkspace().removeResourceChangeListener(updateProjectComboListener);
modelJ2C().ceylonModel().removeModelListener(this);
}
@Override
public void setFocus() {}
@Override
public boolean show(ShowInContext context) {
ISelection selection = context.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss =
(IStructuredSelection) selection;
Object[] elements = ss.toArray();
for (int i=0; i<elements.length; i++) {
Object element = elements[i];
if (element instanceof SourceModuleNode) {
SourceModuleNode module = (SourceModuleNode) element;
setProject(module.getProject());
select(module.getModule());
return true;
}
else if (element instanceof ExternalModuleNode) {
if (selection instanceof TreeSelection) {
TreePath path = ((TreeSelection) selection).getPaths()[i];
Object top = path.getFirstSegment();
if (top instanceof IProject) {
setProject((IProject) top);
select(((ExternalModuleNode) path.getLastSegment()).getModule());
return true;
}
}
select(((ExternalModuleNode) element).getModule());
return true;
}
else if (element instanceof IProject) {
setProject((IProject) element);
select(getProjectSourceModules(project));
return true;
}
else if (element instanceof IJavaElement) {
setProject(((IJavaElement) element).getJavaProject().getProject());
if (element instanceof IPackageFragment) {
Module module = getModule((IPackageFragment) element);
if (module!=null) {
select(module);
}
}
return true;
}
else if (element instanceof IResource) {
setProject(((IResource) element).getProject());
if (element instanceof IFile) {
Module module = getModule((IFile) element);
if (module!=null) {
select(module);
}
}
else if (element instanceof IFolder) {
Module module = getModule((IFolder) element);
if (module!=null) {
select(module);
}
}
return true;
}
}
}
else {
IEditorPart editor = EditorUtil.getCurrentEditor();
if (editor instanceof CeylonEditor) {
CeylonParseController controller = ((CeylonEditor) editor).getParseController();
setProject(controller.getProject());
Module module = controller.getLastPhasedUnit().getPackage().getModule();
select(module);
return true;
}
}
return false;
}
private void select(Collection<Module> modules) {
if (!modules.isEmpty()) {
List<ModuleReference> list = new ArrayList<ModuleReference>();
for (Module module: modules) {
list.add(ModuleDependencies.reference(module));
}
viewer.setSelection(new StructuredSelection(list), true);
}
}
private void select(Module module) {
viewer.setSelection(new StructuredSelection(ModuleDependencies.reference(module)), true);
}
@Override
public Object ceylonModelParsed(final CeylonProject<IProject, IResource, IFolder, IFile> project) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (!projectCombo.isDisposed()) {
if (project.getName().equals(projectCombo.getText())) {
setProject(project.getIdeArtifact());
}
}
}
});
return null;
}
@Override
public Object ceylonProjectAdded(
CeylonProject<IProject, IResource, IFolder, IFile> project) {
return null;
}
@Override
public Object ceylonProjectRemoved(
CeylonProject<IProject, IResource, IFolder, IFile> project) {
return null;
}
@Override
public Object buildMessagesChanged(
CeylonProject<IProject,IResource,IFolder,IFile> project,
ceylon.language.Iterable<? extends CeylonProjectBuild<IProject,IResource,IFolder,IFile>.SourceFileMessage,? extends Object> frontendMessages,
ceylon.language.Iterable<? extends CeylonProjectBuild<IProject,IResource,IFolder,IFile>.SourceFileMessage,? extends Object> backMessages,
ceylon.language.Iterable<? extends CeylonProjectBuild<IProject,IResource,IFolder,IFile>.ProjectMessage,? extends Object> projectMessages) {
return null;
}
@Override
public Object modelFilesUpdated(
ceylon.language.Iterable<? extends FileVirtualFile<IProject, IResource, IFolder, IFile>, ? extends Object> arg0) {
return null;
}
@Override
public Object modelPhasedUnitsTypechecked(
ceylon.language.Iterable<? extends ProjectPhasedUnit<IProject, IResource, IFolder, IFile>, ? extends Object> arg0) {
return null;
}
@Override
public Object externalPhasedUnitsTypechecked(
ceylon.language.Iterable<? extends ExternalPhasedUnit, ? extends Object> arg0,
boolean arg1) {
return null;
}
}