001/* 002 * Copyright (c) 2015 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2015-11-02 20:00:34 +0000 (Mon, 02 Nov 2015) $' 007 * '$Revision: 34198 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029package org.kepler.profiling.gui; 030 031import java.awt.Container; 032import java.awt.event.ActionEvent; 033import java.awt.event.ActionListener; 034 035import javax.swing.JMenuItem; 036import javax.swing.JTabbedPane; 037 038import org.kepler.gui.ModelToFrameManager; 039import org.kepler.gui.TabPane; 040import org.kepler.gui.TabPaneFactory; 041import org.kepler.gui.frame.TabbedKeplerGraphFrame; 042import org.kepler.moml.NamedObjId; 043import org.kepler.provenance.ProvenanceRecorder; 044import org.kepler.provenance.QueryException; 045import org.kepler.provenance.Queryable; 046import org.kepler.provenance.RecordPlayer; 047import org.kepler.provenance.RecordingException; 048 049import ptolemy.actor.gui.Configuration; 050import ptolemy.actor.gui.Effigy; 051import ptolemy.actor.gui.Tableau; 052import ptolemy.actor.gui.TableauFrame; 053import ptolemy.kernel.ComponentEntity; 054import ptolemy.kernel.util.ChangeListener; 055import ptolemy.kernel.util.ChangeRequest; 056import ptolemy.kernel.util.IllegalActionException; 057import ptolemy.kernel.util.NameDuplicationException; 058import ptolemy.kernel.util.NamedObj; 059import ptolemy.util.MessageHandler; 060import ptolemy.vergil.basic.BasicGraphFrame; 061 062/** A panel that displays actor execution information for the workflow 063 * contained by the parent frame that creates the panel. 064 * 065 * @author Daniel Crawl 066 * @version $Id: CurrentExecutionPanel.java 34198 2015-11-02 20:00:34Z crawl $ 067 * 068 */ 069public class CurrentExecutionPanel extends ExecutionMonitorPanel 070 implements ChangeListener { 071 072 /** Create a new CurrentExecutionPanel with the specified name. */ 073 public CurrentExecutionPanel(String name) { 074 super(name); 075 } 076 077 /** A changed occurred in the workflow structure. */ 078 @Override 079 public void changeExecuted(ChangeRequest change) { 080 081 // see if we've already created the recording 082 if(_executionMonitorRecording == null) { 083 // see if the default provenance recorder is present. 084 // if so, create a new recording to receive provenance 085 // events and stop listening for workflow change events. 086 ProvenanceRecorder recorder = ProvenanceRecorder.getDefaultProvenanceRecorder(_workflow); 087 if(recorder != null) { 088 try { 089 _executionMonitorRecording = new ExecutionMonitorRecording(); 090 recorder.addPiggyback(_executionMonitorRecording); 091 } catch (RecordingException e) { 092 MessageHandler.error("Error creating Execution Monitor Recordiner", e); 093 } 094 _workflow.removeChangeListener(this); 095 // receive a notification when provenance turned on/off 096 recorder.addEnabledListener(this); 097 } 098 } 099 } 100 101 /** A change failed in the workflow structure. */ 102 @Override 103 public void changeFailed(ChangeRequest change, Exception exception) { 104 // do nothing. 105 }; 106 107 /** Initialize the tab. */ 108 @Override 109 public void initializeTab() throws Exception { 110 super.initializeTab(); 111 // listen for changes in the workflow so that we can get 112 // a reference to the default provenance recorder. 113 _workflow.addChangeListener(this); 114 115 _statusLabel.setText("Run workflow to see execution information."); 116 } 117 118 /** A factory to create the tab pane. */ 119 public static class Factory extends TabPaneFactory { 120 121 public Factory(NamedObj container, String name) 122 throws IllegalActionException, NameDuplicationException { 123 super(container, name); 124 } 125 126 @Override 127 public TabPane createTabPane(TableauFrame parent) { 128 CurrentExecutionPanel pane = new CurrentExecutionPanel(getName()); 129 return pane; 130 } 131 } 132 133 /** Initialize the pop up menu for the execution table. */ 134 @Override 135 protected void _initContextMenu() { 136 super._initContextMenu(); 137 138 // add an item that goes to the actor in the selected row. 139 JMenuItem goToActor = new JMenuItem("Go To Actor"); 140 goToActor.addActionListener(new ActionListener() { 141 @Override 142 public void actionPerformed(ActionEvent event) { 143 // get the selected row 144 ActorInfo info = _getSelectedRowInfo(); 145 if(info != null) { 146 147 // get the actor in the selected row 148 ComponentEntity<?> entity = _workflow.getEntity(info.name); 149 if(entity != null) { 150 151 // open the frame for the actor and center on the actor 152 // if there is already a frame opened for this actor, then 153 // this just centers it on the actor. 154 BasicGraphFrame.openComposite(_frame, entity); 155 156 // if the actor was already opened in a tabbed frame, 157 // then we want to set that tab to be selected. 158 // first, we get the frame. 159 160 NamedObj container = entity.getContainer(); 161 162 Effigy effigy = Configuration.findEffigy(entity.toplevel()); 163 if (effigy == null) { 164 MessageHandler.error("Failed to find an " 165 + "effigy for the toplevel " 166 + entity.toplevel().getFullName()); 167 return; 168 } 169 170 Configuration configuration = (Configuration) effigy.toplevel(); 171 172 Tableau tableau = null; 173 try { 174 tableau = configuration.openInstance(container); 175 } catch (Exception e) { 176 MessageHandler.error("Error opening window for " + container, e); 177 return; 178 } 179 180 BasicGraphFrame frame = (BasicGraphFrame) tableau.getFrame(); 181 182 // now select the tab containing the container of the actor 183 // (if the frame is a TabbedKeplerGraphFrame) 184 if(frame instanceof TabbedKeplerGraphFrame) { 185 ((TabbedKeplerGraphFrame)frame).setSelectedTab(container); 186 } else if(frame == null) { 187 frame = ModelToFrameManager.getInstance().getFrame(container); 188 if(frame instanceof TabbedKeplerGraphFrame) { 189 ((TabbedKeplerGraphFrame)frame).setSelectedTab(container); 190 } 191 } 192 193 // finally, set canvas tab to be selected. 194 Container jgraphTabbedContainer = frame.getJGraph().getParent().getParent().getParent(); 195 if(jgraphTabbedContainer instanceof JTabbedPane) { 196 ((JTabbedPane) jgraphTabbedContainer).setSelectedIndex(0); 197 } 198 199 if(frame == CurrentExecutionPanel.this._frame) { 200 201 // switch to Workflow tab 202 JTabbedPane tabbedPane = (JTabbedPane) CurrentExecutionPanel.this.getParent(); 203 tabbedPane.setSelectedIndex(0); 204 } 205 206 } 207 } 208 } 209 }); 210 _executionTableContextMenu.add(goToActor); 211 212 } 213 214 /** Replay the last execution. */ 215 @Override 216 protected void _replay() { 217 if(_executionMonitorRecording != null) { 218 try { 219 Queryable query = ProvenanceRecorder.getDefaultQueryable(_workflow); 220 Integer execId = query.getLastExecutionForWorkflow(NamedObjId.getIdFor(_workflow)); 221 if(execId == null) { 222 MessageHandler.error("Could not find execution id for workflow."); 223 return; 224 } 225 RecordPlayer player = new RecordPlayer(query, _executionMonitorRecording); 226 player.setPlayPortEvents(false); 227 // NOTE: play using the existing workflow. otherwise the workflow is loaded 228 // and parsed from provenance and subsequent executions of the existing 229 // workflow results in the actor names being wrong in the execution panel. 230 player.play(execId, _workflow); 231 } catch (QueryException | RecordingException e) { 232 // TODO Auto-generated catch block 233 e.printStackTrace(); 234 } 235 } 236 } 237}