Java tutorial
/******************************************************************************* * 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(); } }