net.sf.taverna.t2.workbench.ui.workflowexplorer.WorkflowExplorerTreeCellRenderer.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.taverna.t2.workbench.ui.workflowexplorer.WorkflowExplorerTreeCellRenderer.java

Source

/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.workbench.ui.workflowexplorer;

import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.controlLinkIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.datalinkIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.folderClosedIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.folderOpenIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.inputIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.inputPortIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.outputIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.outputPortIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.workflowExplorerIcon;

import java.awt.Component;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

import net.sf.taverna.t2.lang.ui.icons.Icons;
//import net.sf.taverna.t2.visit.VisitReport.Status;
import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
import net.sf.taverna.t2.workbench.report.ReportManager;

import org.apache.commons.beanutils.BeanUtils;

import uk.org.taverna.scufl2.api.activity.Activity;
import uk.org.taverna.scufl2.api.common.Scufl2Tools;
import uk.org.taverna.scufl2.api.core.BlockingControlLink;
import uk.org.taverna.scufl2.api.core.DataLink;
import uk.org.taverna.scufl2.api.core.Processor;
import uk.org.taverna.scufl2.api.core.Workflow;
import uk.org.taverna.scufl2.api.port.InputProcessorPort;
import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
import uk.org.taverna.scufl2.api.port.OutputProcessorPort;
import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
import uk.org.taverna.scufl2.api.port.Port;
import uk.org.taverna.scufl2.api.port.ProcessorPort;
import uk.org.taverna.scufl2.api.port.ReceiverPort;
import uk.org.taverna.scufl2.api.port.SenderPort;
import uk.org.taverna.scufl2.api.profiles.ProcessorBinding;

/**
 * Cell renderer for Workflow Explorer tree.
 *
 * @author Alex Nenadic
 * @author David Withers
 */
public class WorkflowExplorerTreeCellRenderer extends DefaultTreeCellRenderer {
    // FIXME This enum is just a workaround
    enum Status {
        OK, WARNING, SEVERE
    }

    private static final long serialVersionUID = -1326663036193567147L;
    private static final String RUNS_AFTER = " runs after ";

    private final ActivityIconManager activityIconManager;

    @SuppressWarnings("unused")
    private Workflow workflow = null;
    @SuppressWarnings("unused")
    private final ReportManager reportManager;

    private Scufl2Tools scufl2Tools = new Scufl2Tools();

    public WorkflowExplorerTreeCellRenderer(Workflow workflow, ReportManager reportManager,
            ActivityIconManager activityIconManager) {
        super();
        this.workflow = workflow;
        this.reportManager = reportManager;
        this.activityIconManager = activityIconManager;
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
            boolean leaf, int row, boolean hasFocus) {
        Component result = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

        Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
        // TODO rewrite report manager to use scufl2 validation
        // Status status = reportManager.getStatus(workflow, userObject);
        Status status = Status.OK;
        WorkflowExplorerTreeCellRenderer renderer = (WorkflowExplorerTreeCellRenderer) result;

        if (userObject instanceof Workflow) { // the root node
            if (!hasGrandChildren((DefaultMutableTreeNode) value))
                renderer.setIcon(workflowExplorerIcon);
            else
                renderer.setIcon(chooseIcon(workflowExplorerIcon, status));
            renderer.setText(((Workflow) userObject).getName());
        } else if (userObject instanceof InputWorkflowPort) {
            renderer.setIcon(chooseIcon(inputIcon, status));
            renderer.setText(((InputWorkflowPort) userObject).getName());
        } else if (userObject instanceof OutputWorkflowPort) {
            renderer.setIcon(chooseIcon(outputIcon, status));
            renderer.setText(((OutputWorkflowPort) userObject).getName());
        } else if (userObject instanceof Processor) {
            Processor p = (Processor) userObject;
            /*
             * Get the activity associated with the processor - currently only
             * the first one in the list gets displayed
             */
            List<ProcessorBinding> processorbindings = scufl2Tools.processorBindingsForProcessor(p,
                    p.getParent().getParent().getMainProfile());
            String text = p.getName();
            if (!processorbindings.isEmpty()) {
                Activity activity = processorbindings.get(0).getBoundActivity();
                Icon basicIcon = activityIconManager.iconForActivity(activity);
                renderer.setIcon(chooseIcon(basicIcon, status));

                try {
                    String extraDescription = BeanUtils.getProperty(activity, "extraDescription");
                    text += " - " + extraDescription;
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    // no problem
                }
            }
            renderer.setText(text);
        }
        // Processor's child input port
        else if (userObject instanceof InputProcessorPort) {
            renderer.setIcon(chooseIcon(inputPortIcon, status));
            renderer.setText(((InputProcessorPort) userObject).getName());
        }
        // Processor's child output port
        else if (userObject instanceof OutputProcessorPort) {
            renderer.setIcon(chooseIcon(outputPortIcon, status));
            renderer.setText(((OutputProcessorPort) userObject).getName());
        } else if (userObject instanceof DataLink) {
            renderer.setIcon(chooseIcon(datalinkIcon, status));
            SenderPort source = ((DataLink) userObject).getReceivesFrom();
            String sourceName = findName(source);
            ReceiverPort sink = ((DataLink) userObject).getSendsTo();
            String sinkName = findName(sink);
            renderer.setText(sourceName + " -> " + sinkName);
        } else if (userObject instanceof BlockingControlLink) {
            renderer.setIcon(chooseIcon(controlLinkIcon, status));
            String htmlText = "<html><head></head><body>" + ((BlockingControlLink) userObject).getBlock().getName()
                    + " " + RUNS_AFTER + " " + ((BlockingControlLink) userObject).getUntilFinished().getName()
                    + "</body></html>";
            renderer.setText(htmlText);

        } else {
            /*
             * It one of the main container nodes (inputs, outputs, processors,
             * datalinks) or a nested workflow node
             */
            if (expanded)
                renderer.setIcon(folderOpenIcon);
            else
                renderer.setIcon(folderClosedIcon);
        }

        return result;
    }

    private static Icon chooseIcon(final Icon basicIcon, Status status) {
        if (status == null)
            return basicIcon;
        if (status == Status.OK)
            return basicIcon;
        else if (status == Status.WARNING)
            return Icons.warningIcon;
        else if (status == Status.SEVERE)
            return Icons.severeIcon;
        return basicIcon;
    }

    private static boolean hasGrandChildren(DefaultMutableTreeNode node) {
        int childCount = node.getChildCount();
        for (int i = 0; i < childCount; i++)
            if (node.getChildAt(i).getChildCount() > 0)
                return true;
        return false;
    }

    private String findName(Port port) {
        if (port instanceof ProcessorPort) {
            String sourceProcessorName = ((ProcessorPort) port).getParent().getName();
            return sourceProcessorName + ":" + port.getName();
        }
        return port.getName();
    }
}