org.apache.ivyde.eclipse.resolvevisualizer.ResolveVisualizerForm.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ivyde.eclipse.resolvevisualizer.ResolveVisualizerForm.java

Source

/*
 *  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.eclipse.resolvevisualizer;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Set;

import org.apache.ivyde.eclipse.resolvevisualizer.label.AllCallersAlgorithm;
import org.apache.ivyde.eclipse.resolvevisualizer.label.AllDependencyAlgorithm;
import org.apache.ivyde.eclipse.resolvevisualizer.label.AllRootPathsAlgorithm;
import org.apache.ivyde.eclipse.resolvevisualizer.label.SameModuleIdAlgorithm;
import org.apache.ivyde.eclipse.resolvevisualizer.label.ShortestRootPathAlgorithm;
import org.apache.ivyde.eclipse.resolvevisualizer.model.IvyNodeElement;
import org.apache.ivyde.eclipse.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("<A>close</A>");
                    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/* <IvyNodeElement> */ conflicts = (Set/* <IvyNodeElement> */) 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/* <IvyNodeElement> */ conflicts = (Set/* <IvyNodeElement> */) 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("<form>");
        for (int i = 0; i < messages.length; i++) {
            IMessage message = messages[i];
            pw.print("<li vspace=\"false\" style=\"image\" indent=\"16\" value=\"");
            switch (message.getMessageType()) {
            case IMessageProvider.ERROR:
                pw.print("error");
                break;
            case IMessageProvider.WARNING:
                pw.print("warning");
                break;
            case IMessageProvider.INFORMATION:
                pw.print("info");
                break;
            }
            pw.print("\"> <a href=\"");
            pw.print(i + "");
            pw.print("\">");
            if (message.getPrefix() != null) {
                pw.print(message.getPrefix());
            }
            pw.print(message.getMessage());
            pw.println("</a></li>");
        }
        pw.println("</form>");
        pw.flush();
        return sw.toString();
    }
}