001/** 002 * '$Author: crawl $' 003 * '$Date: 2015-11-02 18:39:49 +0000 (Mon, 02 Nov 2015) $' 004 * '$Revision: 34180 $' 005 * 006 * For Details: 007 * http://www.kepler-project.org 008 * 009 * Copyright (c) 2009-2010 The Regents of the 010 * University of California. All rights reserved. Permission is hereby granted, 011 * without written agreement and without license or royalty fees, to use, copy, 012 * modify, and distribute this software and its documentation for any purpose, 013 * provided that the above copyright notice and the following two paragraphs 014 * appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF 015 * CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, 016 * OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS 017 * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE 018 * POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY 019 * DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 021 * SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 * ENHANCEMENTS, OR MODIFICATIONS. 024 */ 025 026package org.kepler.workflowrunmanager.gui; 027 028import java.awt.BorderLayout; 029import java.awt.Component; 030import java.awt.Cursor; 031import java.awt.Dimension; 032import java.awt.FlowLayout; 033import java.awt.Font; 034import java.awt.event.ActionEvent; 035import java.awt.event.ActionListener; 036import java.awt.event.FocusEvent; 037import java.awt.event.FocusListener; 038import java.awt.event.WindowAdapter; 039import java.awt.event.WindowEvent; 040import java.beans.PropertyChangeEvent; 041import java.beans.PropertyChangeListener; 042import java.io.File; 043import java.io.IOException; 044import java.text.DateFormat; 045import java.util.ArrayList; 046import java.util.Collection; 047import java.util.HashMap; 048import java.util.HashSet; 049import java.util.Iterator; 050import java.util.List; 051import java.util.ListIterator; 052import java.util.Map; 053import java.util.Set; 054import java.util.Vector; 055import java.util.concurrent.Executors; 056 057import javax.swing.DefaultCellEditor; 058import javax.swing.JButton; 059import javax.swing.JComboBox; 060import javax.swing.JLabel; 061import javax.swing.JList; 062import javax.swing.JMenuItem; 063import javax.swing.JOptionPane; 064import javax.swing.JPanel; 065import javax.swing.JPopupMenu; 066import javax.swing.JScrollPane; 067import javax.swing.JTable; 068import javax.swing.JTextField; 069import javax.swing.JToolBar; 070import javax.swing.ListCellRenderer; 071import javax.swing.SwingWorker; 072import javax.swing.event.CellEditorListener; 073import javax.swing.event.ChangeEvent; 074import javax.swing.event.ListSelectionEvent; 075import javax.swing.event.ListSelectionListener; 076import javax.swing.table.TableCellEditor; 077import javax.swing.table.TableColumn; 078 079import org.apache.commons.logging.Log; 080import org.apache.commons.logging.LogFactory; 081import org.kepler.authentication.AuthenticationException; 082import org.kepler.build.util.Version; 083import org.kepler.gui.ComponentLibraryTab; 084import org.kepler.gui.KeplerGraphFrame; 085import org.kepler.gui.KeplerGraphFrame.Components; 086import org.kepler.gui.KeplerGraphFrameUpdater; 087import org.kepler.gui.TabPane; 088import org.kepler.gui.TabPaneFactory; 089import org.kepler.gui.kar.ImportModuleDependenciesAction; 090import org.kepler.gui.lsid.LSIDViewer; 091import org.kepler.gui.state.StateChangeEvent; 092import org.kepler.gui.state.StateChangeMonitor; 093import org.kepler.kar.KARFile; 094import org.kepler.kar.ModuleDependencyUtil; 095import org.kepler.kar.SaveKAR; 096import org.kepler.kar.handlers.ProvKAREntryHandler; 097import org.kepler.objectmanager.cache.CacheException; 098import org.kepler.objectmanager.cache.CacheManager; 099import org.kepler.objectmanager.lsid.KeplerLSID; 100import org.kepler.objectmanager.repository.Repository; 101import org.kepler.objectmanager.repository.RepositoryManager; 102import org.kepler.provenance.ProvenanceEnabledListener; 103import org.kepler.provenance.ProvenanceRecorder; 104import org.kepler.provenance.QueryException; 105import org.kepler.provenance.Queryable; 106import org.kepler.provenance.RecordPlayer; 107import org.kepler.provenance.Recording; 108import org.kepler.provenance.RecordingException; 109import org.kepler.tagging.TaggingContext; 110import org.kepler.tagging.TaggingContextManager; 111import org.kepler.tagging.WindowIdentifier; 112import org.kepler.tagging.gui.TagBarInsertionUI; 113import org.kepler.tagging.gui.TagBarUI; 114import org.kepler.tagging.gui.TaggingPanel; 115import org.kepler.util.ProvenanceStore; 116import org.kepler.util.WorkflowRun; 117import org.kepler.workflowrunmanager.WRMDefaults; 118import org.kepler.workflowrunmanager.WorkflowRunManager; 119import org.kepler.workflowrunmanager.WorkflowRunManagerEvent; 120import org.kepler.workflowrunmanager.WorkflowRunManagerEventListener; 121import org.kepler.workflowrunmanager.WorkflowRunManagerManager; 122import org.kepler.workflowrunmanager.gui.kar.ExportRunsArchiveAction; 123 124import ptolemy.actor.CompositeActor; 125import ptolemy.actor.gui.PtolemyFrame; 126import ptolemy.actor.gui.TableauFrame; 127import ptolemy.kernel.ComponentEntity; 128import ptolemy.kernel.util.IllegalActionException; 129import ptolemy.kernel.util.NameDuplicationException; 130import ptolemy.kernel.util.NamedObj; 131import ptolemy.util.MessageHandler; 132import util.TableSorter; 133 134/** 135 * WorkflowRunManager TabPane 136 * 137 * @author Derik Barseghian 138 * 139 */ 140public class WorkflowRunManagerPanel extends JPanel implements TabPane, 141 WorkflowRunManagerEventListener, ProvenanceEnabledListener, 142 KeplerGraphFrameUpdater, ActionListener, PropertyChangeListener { 143 144 private static final Log log = LogFactory 145 .getLog(WorkflowRunManagerPanel.class.getName()); 146 147 private TableauFrame _frame; 148 private String _tabName; 149 // XXX for incomplete feature, hide/show columns: 150 // private boolean tempVisibleToggle = true; 151 152 private WRMDefaults wrmDefaults = WRMDefaults.getInstance(); 153 154 private WorkflowRunManagerTableModel wrmTableModel = null; 155 private JTable wrmjTable = null; 156 private TableSorter sorter = null; 157 private JPopupMenu popupMenu = new JPopupMenu(); 158 private static final String OPEN_RUNS = "Open"; 159 private static final String EXPORT_ARCHIVE = "Export Archive..."; 160 private static final String UPLOAD_TO_REPOSITORY = "Upload to Repository..."; 161 private static final String DELETE_RUN = "Delete"; 162 private static final String CHANGE_COL_VISIBLE = "change colgroup visible test"; 163 private static final String VIEW_RUN_LSID = "View Run LSID"; 164 private static final String VIEW_WORKFLOW_LSID = "View Workflow LSID"; 165 private static final String ENABLE_PROVENANCE = "Enable menu by turning on Provenance in toolbar"; 166 private static final String RUNS_INCOMPAT_MOD_DEPS = "Runs have different module dependencies, can't archive together"; 167 private static final String DOWNLOAD_KAR = "Download"; 168 private static final String REFRESH = "Refresh"; 169 private static final String SHOW_GRAPHICAL_ACTORS_OUTPUTS = "Show Graphical Actors Outputs"; 170 171 private JLabel unsupportedRecordingTypeMsg = new JLabel("Provenance RecordingType unsupported by Workflow Run Manager"); 172 private JButton refreshButton = new JButton(); 173 private boolean authenticate = ComponentLibraryTab.AUTHENTICATE; 174 175 private JMenuItem openMenuItem = new JMenuItem(OPEN_RUNS); 176 private JMenuItem exportMenuItem = new JMenuItem(EXPORT_ARCHIVE); 177 private JMenuItem uploadMenuItem = new JMenuItem(UPLOAD_TO_REPOSITORY); 178 private JMenuItem deleteMenuItem = new JMenuItem(DELETE_RUN); 179 private JMenuItem viewRunLsidMenuItem = new JMenuItem(VIEW_RUN_LSID); 180 private JMenuItem viewWorkflowLSIDMenuItem = new JMenuItem(VIEW_WORKFLOW_LSID); 181 private JMenuItem provWarningMenuItem = new JMenuItem(ENABLE_PROVENANCE); 182 private JMenuItem changeColVisibleMenuItem = new JMenuItem(CHANGE_COL_VISIBLE); 183 private JMenuItem runsIncompatModDepsWarningMenuItem = new JMenuItem(RUNS_INCOMPAT_MOD_DEPS); 184 private JMenuItem downloadMenuItem = new JMenuItem(DOWNLOAD_KAR); 185 private JMenuItem showGraphicalActorsOutputsMenuItem = new JMenuItem(SHOW_GRAPHICAL_ACTORS_OUTPUTS); 186 187 private static int doubleClick = 2; 188 // warn if user tries to open this many runs: 189 private static final int openWarningLimit = 10; 190 191 private NamedObj model = null; 192 193 private int[] _lastSelectedRows = null; 194 195 private boolean _isProvenanceEnabled = true; 196 197 private WorkflowRunManager workflowRunManager = null; 198 199 private KeplerGraphFrame kgf = null; 200 201 private boolean lastMouseEventWasPopupTrigger; 202 203 private ExecIdCellEditor execIdHeaderCellEditor; 204 private DateCellEditor startTimeHeaderCellEditor; 205 private DurationCellEditor durationHeaderCellEditor; 206 private CellEditorListener cellEditorListener; 207 208 /* 209 * (non-Javadoc) 210 * 211 * @see org.kepler.gui.TabPane#getParentFrame() 212 */ 213 @Override 214 public TableauFrame getParentFrame() { 215 return _frame; 216 } 217 218 /* 219 * (non-Javadoc) 220 * 221 * @see org.kepler.gui.TabPane#getTabName() 222 */ 223 @Override 224 public String getTabName() { 225 return _tabName; 226 } 227 228 public void setTabName(String name) { 229 _tabName = name; 230 } 231 232 /* 233 * (non-Javadoc) 234 * 235 * @see org.kepler.gui.TabPane#initializeTab() 236 */ 237 @Override 238 public void initializeTab() throws Exception { 239 240 this.removeAll(); 241 this.repaint(); 242 this.revalidate(); 243 // Add components to the JPanel here. 244 this.setLayout(new BorderLayout()); 245 246 kgf = (KeplerGraphFrame) this._frame; 247 248 resetProvenanceInfo(wrmDefaults.getDefaultProvenanceStore()); 249 250 wrmTableModel = new WorkflowRunManagerTableModel(_frame); 251 252 // listen for WorkflowRunManagerEvents ourself too 253 workflowRunManager.addWorkflowRunManagerEventListener(this); 254 255 setupContextMenu(); 256 257 sorter = new TableSorter(wrmTableModel); 258 wrmjTable = new JTable(sorter); 259 260 wrmjTable.setColumnModel(new GroupableTableColumnModel()); 261 GroupableTableColumnModel groupableTableColumnModel = (GroupableTableColumnModel) wrmjTable 262 .getColumnModel(); 263 264 sorter.setTableModel(wrmTableModel); 265 266 // Create search cell text fields, each with a focus listener. On 267 // focusLost, tell the header editingStopped. 268 // TODO this doesn't work yet for the custom cell editors (date, 269 // duration, execid..) 270 JTextField tagsTextField = new JTextField(); 271 JTextField workflowTextField = new JTextField(); 272 JTextField startTimeTextField = new JTextField(); 273 JTextField durationTextField = new JTextField(); 274 JTextField userTextField = new JTextField(); 275 JTextField execIdTextField = new JTextField(); 276 277 FocusListener headerTextFieldFocusListener = new FocusListener() { 278 @Override 279 public void focusGained(FocusEvent e) { 280 } 281 282 @Override 283 public void focusLost(FocusEvent e) { 284 GroupableTableHeader header = (GroupableTableHeader) wrmjTable 285 .getTableHeader(); 286 header.editingStopped(new ChangeEvent(this)); 287 } 288 }; 289 290 tagsTextField.addFocusListener(headerTextFieldFocusListener); 291 workflowTextField.addFocusListener(headerTextFieldFocusListener); 292 startTimeTextField.addFocusListener(headerTextFieldFocusListener); 293 durationTextField.addFocusListener(headerTextFieldFocusListener); 294 userTextField.addFocusListener(headerTextFieldFocusListener); 295 execIdTextField.addFocusListener(headerTextFieldFocusListener); 296 297 DefaultCellEditor tagsHeaderCellEditor = new DefaultCellEditor( 298 tagsTextField); 299 DefaultCellEditor workflowHeaderCellEditor = new DefaultCellEditor( 300 workflowTextField); 301 startTimeHeaderCellEditor = new DateCellEditor( 302 startTimeTextField); 303 durationHeaderCellEditor = new DurationCellEditor( 304 durationTextField); 305 DefaultCellEditor userHeaderCellEditor = new DefaultCellEditor( 306 userTextField); 307 execIdHeaderCellEditor = new ExecIdCellEditor( 308 execIdTextField); 309 310 tagsHeaderCellEditor.setClickCountToStart(1); 311 workflowHeaderCellEditor.setClickCountToStart(1); 312 startTimeHeaderCellEditor.setClickCountToStart(1); 313 durationHeaderCellEditor.setClickCountToStart(1); 314 userHeaderCellEditor.setClickCountToStart(1); 315 execIdHeaderCellEditor.setClickCountToStart(1); 316 317 ColumnGroup tagsearchColumnGroup = new ColumnGroup( 318 new GroupableTableCellRenderer(), tagsHeaderCellEditor, 319 wrmDefaults.getDefault(WRMDefaults.TAGS)); 320 tagsearchColumnGroup.add(groupableTableColumnModel.getColumn(wrmDefaults 321 .getDefaultColIndex(WRMDefaults.TAGS))); 322 ColumnGroup workflowsearchColumnGroup = new ColumnGroup( 323 new GroupableTableCellRenderer(), workflowHeaderCellEditor, 324 wrmDefaults.getDefault(WRMDefaults.WORKFLOW_NAME)); 325 workflowsearchColumnGroup.add(groupableTableColumnModel.getColumn(wrmDefaults 326 .getDefaultColIndex(WRMDefaults.WORKFLOW_NAME))); 327 ColumnGroup startTimeSearchColumnGroup = new ColumnGroup( 328 new GroupableTableCellRenderer(), startTimeHeaderCellEditor, 329 wrmDefaults.getDefault(WRMDefaults.START_TIME)); 330 startTimeSearchColumnGroup.add(groupableTableColumnModel.getColumn(wrmDefaults 331 .getDefaultColIndex(WRMDefaults.START_TIME))); 332 ColumnGroup durationsearchColumnGroup = new ColumnGroup( 333 new GroupableTableCellRenderer(), durationHeaderCellEditor, 334 wrmDefaults.getDefault(WRMDefaults.DURATION)); 335 durationsearchColumnGroup.add(groupableTableColumnModel.getColumn(wrmDefaults 336 .getDefaultColIndex(WRMDefaults.DURATION))); 337 ColumnGroup usersearchColumnGroup = new ColumnGroup( 338 new GroupableTableCellRenderer(), userHeaderCellEditor, 339 wrmDefaults.getDefault(WRMDefaults.USER)); 340 usersearchColumnGroup.add(groupableTableColumnModel.getColumn(wrmDefaults 341 .getDefaultColIndex(WRMDefaults.USER))); 342 //ColumnGroup g_execIdsearch = new ColumnGroup( 343 // new GroupableTableCellRenderer(), execIdHeaderCellEditor, 344 // wrmDefaults.getDefault(WRMDefaults.EXEC_ID)); 345 //g_execIdsearch.add(cm.getColumn(wrmDefaults 346 // .getDefaultColIndex(WRMDefaults.EXEC_ID))); 347 348 groupableTableColumnModel.addColumnGroup(tagsearchColumnGroup); 349 groupableTableColumnModel.addColumnGroup(workflowsearchColumnGroup); 350 groupableTableColumnModel.addColumnGroup(startTimeSearchColumnGroup); 351 groupableTableColumnModel.addColumnGroup(durationsearchColumnGroup); 352 groupableTableColumnModel.addColumnGroup(usersearchColumnGroup); 353 //cm.addColumnGroup(g_execIdsearch); 354 355 // date column FormatRenderer 356 wrmjTable.getColumnModel().getColumn( 357 wrmDefaults.getDefaultColIndex(WRMDefaults.START_TIME)) 358 .setCellRenderer( 359 new FormatRenderer(DateFormat.getDateTimeInstance())); 360 // duration column DurationCellRenderer 361 wrmjTable.getColumnModel().getColumn( 362 wrmDefaults.getDefaultColIndex(WRMDefaults.DURATION)) 363 .setCellRenderer(new DurationCellRenderer()); 364 365 // the other columns use WRMDefaultTableCellRenderer so they can also 366 // paint error rows red: 367 wrmjTable.getColumnModel().getColumn( 368 wrmDefaults.getDefaultColIndex(WRMDefaults.TAGS)) 369 .setCellRenderer(new WRMDefaultTableCellRenderer()); 370 wrmjTable.getColumnModel().getColumn( 371 wrmDefaults.getDefaultColIndex(WRMDefaults.WORKFLOW_NAME)) 372 .setCellRenderer(new WRMDefaultTableCellRenderer()); 373 wrmjTable.getColumnModel().getColumn( 374 wrmDefaults.getDefaultColIndex(WRMDefaults.USER)) 375 .setCellRenderer(new WRMDefaultTableCellRenderer()); 376 //wrmjTable.getColumnModel().getColumn( 377 // wrmDefaults.getDefaultColIndex(WRMDefaults.EXEC_ID)) 378 // .setCellRenderer(new WRMDefaultTableCellRenderer()); 379 380 // add mouse listener for context menu and to open selected runs on a 381 // double-click 382 wrmjTable.addMouseListener(new java.awt.event.MouseAdapter() { 383 384 // os X 385 @Override 386 public void mousePressed(java.awt.event.MouseEvent evt) { 387 if ((evt.getClickCount() == doubleClick) 388 && !evt.isPopupTrigger() 389 && !lastMouseEventWasPopupTrigger 390 && _isProvenanceEnabled) { 391 // Disable double-click open since allows 392 // user to circumvent checking if runs have same mod deps, 393 // when in Strict (see how Open is disabled in the menu). 394 // Enabling would be easy, but some double-clicks would be 395 // disallowed, which seems more confusing than it's worth. 396 //openMenuItem.doClick(); 397 } else { 398 if (_isProvenanceEnabled){ 399 setTagContextToCurrentlySelectedRows(); 400 } 401 jTableShowContextMenu(evt); 402 } 403 lastMouseEventWasPopupTrigger = evt.isPopupTrigger(); 404 } 405 406 // Windows 407 @Override 408 public void mouseReleased(java.awt.event.MouseEvent evt) { 409 if ((evt.getClickCount() == doubleClick) 410 && !evt.isPopupTrigger() 411 && !lastMouseEventWasPopupTrigger 412 && _isProvenanceEnabled) { 413 } else { 414 jTableShowContextMenu(evt); 415 } 416 lastMouseEventWasPopupTrigger = evt.isPopupTrigger(); 417 } 418 }); 419 420 wrmjTable.getColumnModel().getColumn( 421 wrmDefaults.getDefaultColIndex(WRMDefaults.TAGS)) 422 .setHeaderValue(WRMDefaults.TAGS); 423 wrmjTable.getColumnModel().getColumn( 424 wrmDefaults.getDefaultColIndex(WRMDefaults.WORKFLOW_NAME)) 425 .setHeaderValue(WRMDefaults.WORKFLOW_NAME); 426 wrmjTable.getColumnModel().getColumn( 427 wrmDefaults.getDefaultColIndex(WRMDefaults.START_TIME)) 428 .setHeaderValue(WRMDefaults.START_TIME); 429 wrmjTable.getColumnModel().getColumn( 430 wrmDefaults.getDefaultColIndex(WRMDefaults.DURATION)) 431 .setHeaderValue(WRMDefaults.DURATION); 432 wrmjTable.getColumnModel().getColumn( 433 wrmDefaults.getDefaultColIndex(WRMDefaults.USER)) 434 .setHeaderValue(WRMDefaults.USER); 435 //wrmjTable.getColumnModel().getColumn( 436 // wrmDefaults.getDefaultColIndex(WRMDefaults.EXEC_ID)) 437 // .setHeaderValue(WRMDefaults.EXEC_ID); 438 439 // Set some column widths to be wide enough 440 wrmjTable.getColumnModel().getColumn( 441 wrmDefaults.getDefaultColIndex(WRMDefaults.TAGS)) 442 .setPreferredWidth(WRMDefaults.TAGS_COLUMN_WIDTH); 443 wrmjTable.getColumnModel().getColumn( 444 wrmDefaults.getDefaultColIndex(WRMDefaults.WORKFLOW_NAME)) 445 .setPreferredWidth(WRMDefaults.WORKFLOW_NAME_COLUMN_WIDTH); 446 wrmjTable.getColumnModel().getColumn( 447 wrmDefaults.getDefaultColIndex(WRMDefaults.START_TIME)) 448 .setPreferredWidth(WRMDefaults.START_TIME_COLUMN_WIDTH); 449 wrmjTable.getColumnModel().getColumn( 450 wrmDefaults.getDefaultColIndex(WRMDefaults.DURATION)) 451 .setPreferredWidth(WRMDefaults.DURATION_COLUMN_WIDTH); 452 wrmjTable.getColumnModel().getColumn( 453 wrmDefaults.getDefaultColIndex(WRMDefaults.USER)) 454 .setPreferredWidth(WRMDefaults.USER_NAME_COLUMN_WIDTH); 455 //wrmjTable.getColumnModel().getColumn( 456 // wrmDefaults.getDefaultColIndex(WRMDefaults.EXEC_ID)) 457 // .setPreferredWidth(WRMDefaults.EXEC_ID_COLUMN_WIDTH); 458 459 // Set some GUI properties of table to improve appearance: 460 wrmjTable.getColumnModel().setColumnMargin(WRMDefaults.COLUMN_MARGIN); 461 wrmjTable.setGridColor(WRMDefaults.TABLE_GRID_COLOR); 462 wrmjTable.setShowHorizontalLines(WRMDefaults.SHOW_HORIZONTAL_LINES); 463 wrmjTable.setShowVerticalLines(WRMDefaults.SHOW_VERTICAL_LINES); 464 wrmjTable.setRowHeight(WRMDefaults.WRM_ROW_HEIGHT); 465 wrmjTable.setFont(WRMDefaults.WRM_FONT); 466 467 wrmjTable.setTableHeader(new GroupableTableHeader( 468 (GroupableTableColumnModel) wrmjTable.getColumnModel())); 469 sorter.setTableHeader(wrmjTable.getTableHeader()); 470 471 // CellEditorListen on all header cells, on any editingStopped doSearch. 472 cellEditorListener = new CellEditorListener() { 473 @Override 474 public void editingCanceled(ChangeEvent e) { 475 } 476 477 @Override 478 public void editingStopped(ChangeEvent e) { 479 // System.out.println("editing stopped, calling WorkflowRunManagerPanel filterRuns()"); 480 filterRuns(); 481 } 482 }; 483 484 GroupableTableHeader header = (GroupableTableHeader) wrmjTable 485 .getTableHeader(); 486 TableCellEditor tmpTableCellEditor = null; 487 for (int i = 0; i < wrmDefaults.getColumnCount(); i++) { 488 tmpTableCellEditor = header.getCellEditor(i); 489 if (tmpTableCellEditor != null) { 490 tmpTableCellEditor.addCellEditorListener(cellEditorListener); 491 } else { 492 log.error("header cell editor is null"); 493 } 494 } 495 496 // try to populate by default, if another window hasn't already done so 497 if (workflowRunManager.getWorkflowRuns().isEmpty()) { 498 queryForAllRuns(); 499 } else { 500 filterRuns(); 501 } 502 503 // clean up the listener when the frame closes 504 final KeplerGraphFrameUpdater keplerGraphFrameUpdater = this; 505 final WorkflowRunManagerEventListener eventlistener = this; 506 _frame.addWindowListener(new WindowAdapter() { 507 @Override 508 public void windowClosed(WindowEvent e) { 509 execIdHeaderCellEditor.dispose(); 510 durationHeaderCellEditor.dispose(); 511 startTimeHeaderCellEditor.dispose(); 512 workflowRunManager.dispose(eventlistener); 513 KeplerGraphFrame.removeUpdater(keplerGraphFrameUpdater); 514 515 GroupableTableHeader header = (GroupableTableHeader) wrmjTable 516 .getTableHeader(); 517 TableCellEditor tmpTableCellEditor = null; 518 for (int i = 0; i < wrmDefaults.getColumnCount(); i++) { 519 tmpTableCellEditor = header.getCellEditor(i); 520 if (tmpTableCellEditor != null) { 521 tmpTableCellEditor.removeCellEditorListener(cellEditorListener); 522 } else { 523 log.error("header cell editor is null"); 524 } 525 } 526 } 527 }); 528 529 530 // doesn't seem to help: 531 // wrmjTable.putClientProperty("terminateEditOnFocusLost", 532 // Boolean.TRUE); 533 534 JScrollPane _workflowRunManagerPane = new JScrollPane(wrmjTable); 535 536 refreshButton.setText("Refresh"); 537 refreshButton.setActionCommand(REFRESH); 538 refreshButton.addActionListener(this); 539 refreshButton.setSize(180, 25); 540 refreshButton.setEnabled(false); 541 542 543 FlowLayout flowLayout = new FlowLayout(FlowLayout.RIGHT); 544 JPanel upperPanel = new JPanel(flowLayout); 545 JComboBox provenanceStoresComboBox = new JComboBox(wrmDefaults.getProvenanceStores()); 546 provenanceStoresComboBox.setRenderer(new ComboBoxRenderer()); 547 ComboBoxAction comboBoxAction = new ComboBoxAction(); 548 provenanceStoresComboBox.addActionListener(comboBoxAction); 549 550 if (workflowRunManager.usingSupportedRecordingType()){ 551 unsupportedRecordingTypeMsg.setVisible(false); 552 } 553 else{ 554 unsupportedRecordingTypeMsg.setVisible(true); 555 } 556 upperPanel.add(unsupportedRecordingTypeMsg); 557 upperPanel.add(refreshButton); 558 upperPanel.add(provenanceStoresComboBox); 559 560 // TODO: I like not having setMinimumSize, so I or Kepler can 561 // arbitrarily resize but this is a stopgap to partially deal w/ 562 // the "getting stuck" bug. Note settings for _eastSplitPane in 563 // DefaultViewPane.initializeView() when attempting to debug this. 564 _workflowRunManagerPane.setMinimumSize(new Dimension( 565 WRMDefaults.WRM_PANE_WIDTH, WRMDefaults.WRM_PANE_HEIGHT)); 566 567 _workflowRunManagerPane.setPreferredSize(new Dimension( 568 WRMDefaults.WRM_PANE_WIDTH, WRMDefaults.WRM_PANE_HEIGHT)); 569 this.add(upperPanel, BorderLayout.NORTH); 570 this.add(_workflowRunManagerPane); 571 this.revalidate(); 572 573 // sort by startTime DESCENDING by default 574 sorter.setSortingStatus(wrmDefaults 575 .getDefaultColIndex(WRMDefaults.START_TIME), 576 TableSorter.DESCENDING); 577 578 // restrict area in which clicking will cause sort to occur (currently 579 // the bottom half of header): 580 int heightRestriction = ((GroupableTableHeaderUI) header.getUI()) 581 .getCGroupHeight(); 582 sorter.setSortableHeightRestriction(heightRestriction); 583 584 wrmjTable.getSelectionModel().addListSelectionListener( 585 _listSelectionListener); 586 587 // System.out.println("wrmjTable.getAutoCreateColumnsFromModel():" 588 // +wrmjTable.getAutoCreateColumnsFromModel()); 589 590 KeplerGraphFrame.addUpdater(this); 591 } 592 593 // used for tagging 594 private static class ComponentFinder<T> { 595 public ComponentFinder(Component[] componentsArray, Class<T> cls) { 596 for (Component comp : componentsArray) { 597 try { 598 component = cls.cast(comp); 599 match = true; 600 } catch (ClassCastException ignored) { 601 } 602 } 603 } 604 605 public boolean matchFound() { 606 return match; 607 } 608 609 public T getComponent() { 610 return component; 611 } 612 613 private boolean match = false; 614 private T component; 615 } 616 617 // used for tagging 618 private int getWindowId() { 619 try { 620 JToolBar toolbar = kgf.getToolBar(); 621 if (toolbar == null){ 622 log.error("WorkflowRunManagerPanel.getWindowId() toolbar == null"); 623 return -1; 624 } 625 626 ComponentFinder<TaggingPanel> finder1 = new ComponentFinder<TaggingPanel>( 627 toolbar.getComponents(), TaggingPanel.class); 628 if (!finder1.matchFound()) { 629 log.error("TaggingPanel not found in toolbar"); 630 return -1; 631 } 632 ComponentFinder<TagBarInsertionUI> finder2 = new ComponentFinder<TagBarInsertionUI>( 633 finder1.getComponent().getComponents(), 634 TagBarInsertionUI.class); 635 int id = finder2.getComponent().getId(); 636 return id; 637 } catch (ClassCastException ex) { 638 log.error("The frame is not a KeplerGraphFrame, it's an " 639 + this._frame.getClass().getCanonicalName()); 640 } 641 return -1; 642 } 643 644 /* 645 * (non-Javadoc) 646 * 647 * @see 648 * org.kepler.gui.TabPane#setParentFrame(ptolemy.actor.gui.TableauFrame) 649 */ 650 @Override 651 public void setParentFrame(TableauFrame parent) { 652 _frame = parent; 653 } 654 655 /** 656 * A factory that creates a TabPane. 657 * 658 *@author Aaron Schultz 659 */ 660 public static class Factory extends TabPaneFactory { 661 /** 662 * Create a factory with the given name and container. 663 * 664 *@param container 665 * The container. 666 *@param name 667 * The name of the entity. 668 *@exception IllegalActionException 669 * If the container is incompatible with this attribute. 670 *@exception NameDuplicationException 671 * If the name coincides with an attribute already in the 672 * container. 673 */ 674 public Factory(NamedObj container, String name) 675 throws IllegalActionException, NameDuplicationException { 676 super(container, name); 677 } 678 679 /** 680 * Create a library pane that displays the given library of actors. 681 * 682 * @return A new LibraryPaneTab that displays the library 683 */ 684 @Override 685 public TabPane createTabPane(TableauFrame parent) { 686 WorkflowRunManagerPanel wrmp = new WorkflowRunManagerPanel(); 687 688 /* 689 * Optionally you can create a method called setTabName and use the 690 * "name" value from the configuration.xml file by calling 691 * this.getName(). For Example if you have <property 692 * name="randomTestTab" 693 * class="org.kepler.gui.TabPaneExtensionExample$Factory" /> in 694 * configuration.xml then the name of the tab in the GUI becomes 695 * randomTestTab 696 */ 697 wrmp.setTabName(this.getName()); 698 return wrmp; 699 } 700 } 701 702 /** 703 * Query provenance for all runs. 704 * This clears and sets in-memory runs. 705 * @throws AuthenticationException 706 */ 707 private void queryForAllRuns() throws AuthenticationException { 708 709 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 710 String percent_wildcard = "%"; 711 712 if (!workflowRunManager.isConnected()) { 713 log.debug("WorkflowRunManagerPanel queryForAllRuns !workflowRunManager.isConnected() call reconnect()"); 714 reconnect(); 715 } 716 if (workflowRunManager.isConnected()) { 717 log.debug("WorkflowRunManagerPanel queryForAllRuns workflowRunManager.isConnected() call wrmTableModel.updateDataUsingWRMQuery()"); 718 wrmTableModel.updateDataUsingWRMQuery(percent_wildcard, 719 percent_wildcard, percent_wildcard, 720 percent_wildcard, percent_wildcard, percent_wildcard, authenticate); 721 } 722 723 setCursor(Cursor.getDefaultCursor()); 724 } 725 726 727 private void clearAllRuns() { 728 ArrayList<WorkflowRun> emptyRuns = new ArrayList<WorkflowRun>(); 729 workflowRunManager.setWorkflowRuns(emptyRuns); 730 wrmTableModel.clearAllRuns(); 731 } 732 733 /** 734 * Filter all in memory runs for a particular WorkflowRunManager and 735 * update WRM table model with results. 736 */ 737 private void filterRuns() { 738 739 String tagsSearchString = getSearchString(WRMDefaults.TAGS); 740 String wfNameSearchString = getSearchString(WRMDefaults.WORKFLOW_NAME); 741 String startTimeSearchString = getSearchString(WRMDefaults.START_TIME); 742 String durationSearchString = getSearchString(WRMDefaults.DURATION); 743 String userSearchString = getSearchString(WRMDefaults.USER); 744 //String execIdSearchString = getSearchString(WRMDefaults.EXEC_ID); 745 String execIdSearchString = "%"; 746 747 wrmTableModel.filterRuns(wfNameSearchString, userSearchString, 748 startTimeSearchString, durationSearchString, 749 execIdSearchString, tagsSearchString); 750 } 751 752 /** 753 * Return user entered search string for soughtColumnName 754 * 755 * @param soughtColumnName 756 * @return 757 */ 758 private String getSearchString(String soughtColumnName) { 759 760 int modelColumnIndex = 0; 761 String searchString = "%"; 762 try { 763 modelColumnIndex = wrmDefaults.getDefaultColIndex(soughtColumnName); 764 } catch (Exception e) { 765 // TODO Auto-generated catch block 766 e.printStackTrace(); 767 } 768 int viewColIndex = wrmjTable.convertColumnIndexToView(modelColumnIndex); 769 770 GroupableTableColumnModel gtColumnModel = (GroupableTableColumnModel) wrmjTable 771 .getColumnModel(); 772 ColumnGroup cGroup = gtColumnModel.getColumnGroup(viewColIndex); 773 774 if (cGroup == null || !cGroup.isVisible()) { 775 return searchString; 776 } 777 778 TableColumn aColumn = gtColumnModel.getColumn(viewColIndex); 779 780 Iterator<ColumnGroup> iter = gtColumnModel.getColumnGroups(aColumn); 781 782 //FIXME should really fetch a precise cGroup, not last: 783 if (iter != null) { 784 while (iter.hasNext()) { 785 cGroup = iter.next(); 786 searchString = cGroup.getHeaderValue().toString(); 787 } 788 } 789 if (searchString.equals(wrmDefaults 790 .getDefaultSearchStringForColIndex(modelColumnIndex))) { 791 searchString = "%"; 792 } 793 if (searchString.equals("")) { 794 searchString = "%"; 795 } 796 797 return searchString; 798 } 799 800 /** 801 * TODO, sometimes the change shows in the gui, othertimes it doesn't. 802 * 803 * Manually set a column's search string 804 * @param soughtColumnName 805 * @param searchString 806 */ 807 private void setSearchStringAndFilter(String soughtColumnName, String searchString) { 808 809 int modelColumnIndex = 0; 810 try { 811 modelColumnIndex = wrmDefaults.getDefaultColIndex(soughtColumnName); 812 } catch (Exception e) { 813 // TODO Auto-generated catch block 814 e.printStackTrace(); 815 } 816 int viewColIndex = wrmjTable.convertColumnIndexToView(modelColumnIndex); 817 818 GroupableTableColumnModel gtColumnModel = (GroupableTableColumnModel) wrmjTable 819 .getColumnModel(); 820 ColumnGroup cGroup = gtColumnModel.getColumnGroup(viewColIndex); 821 822 if (cGroup == null || !cGroup.isVisible()) { 823 return; 824 } 825 826 TableColumn column = gtColumnModel.getColumn(viewColIndex); 827 Iterator<ColumnGroup> iter = gtColumnModel.getColumnGroups(column); 828 829 //FIXME should really fetch a precise cGroup, not last: 830 if (iter != null) { 831 while (iter.hasNext()) { 832 cGroup = iter.next(); 833 } 834 } 835 cGroup.setHeaderValue(searchString); 836 837 //now filter the runs. 838 filterRuns(); 839 } 840 841 842 /** 843 * Given a list of execution LSIDS, open them. Creates a temp KAR and then 844 * uses KARFile.openKARContents to open it. 845 * 846 * @param runLSIDs 847 * @throws QueryException 848 */ 849 private void openRuns(List<KeplerLSID> runLSIDs) throws QueryException { 850 851 // export run(s) for selected row(s) 852 try { 853 854 ArrayList<WorkflowRun> workflowRuns = wrmTableModel 855 .getWorkflowRunsForRows(getSorterSelectedRows()); 856 857 WorkflowRun wr = workflowRuns.get(0); 858 String runsModDeps = wr.getModuleDependencies(); 859 860 SaveKAR saveKAR = createTempKAR(runLSIDs, runsModDeps); 861 862 KARFile karf = new KARFile(saveKAR.getFile()); 863 karf.openKARContents(_frame, false); 864 karf.close(); 865 866 // immediately delete it, so user gets Save As... dialog 867 // instead of Save (since we don't show file path in title, they 868 // won't know they're saving it to temp file location). 869 saveKAR.getFile().delete(); 870 871 // now clear any runs added to the "selected" list 872 // in prep for any subsequent saves 873 workflowRunManager.clearSelectedRuns(); 874 875 // TODO this is too bold, if openKAR doesn't open a wf, 876 // and this is the only window open, kepler quits! 877 // check if this is last window. Also should probably 878 // only do this if it's the first default blank window. 879 // if (!kgf.isModified()) { 880 // kgf.close(); 881 // } 882 883 } catch (CacheException e) { 884 // TODO Auto-generated catch block 885 e.printStackTrace(); 886 } catch (Exception e) { 887 // TODO Auto-generated catch block 888 e.printStackTrace(); 889 } 890 } 891 892 893 /** 894 * Warning: this method clears and sets WorkflowRunManager selectedRuns 895 * you will almost definitely want to call wrm.clearSelectedRuns soon 896 * after calling this method. 897 * @param runLSIDs 898 * @return 899 */ 900 private SaveKAR createTempKAR(List<KeplerLSID> runLSIDs, String overrideModDeps){ 901 902 //ObjectManager om = ObjectManager.getInstance(); 903 CacheManager cman = null; 904 try { 905 cman = CacheManager.getInstance(); 906 } catch (CacheException e) { 907 // TODO Auto-generated catch block 908 e.printStackTrace(); 909 } 910 911 SaveKAR savekar = new SaveKAR(); 912 913 File tmpKARPath = cman.getTempFile(); 914 savekar.setFile(tmpKARPath); 915 916 // first clear any runs previously added to the "selected" list: 917 workflowRunManager.clearSelectedRuns(); 918 919 Iterator<KeplerLSID> runLsidItr = runLSIDs.iterator(); 920 while (runLsidItr.hasNext()){ 921 KeplerLSID runLSID = runLsidItr.next(); 922 try { 923 ComponentEntity<?> workflow = workflowRunManager.getAssociatedWorkflowForWorkflowRun(runLSID); 924 if (workflow != null) { 925 926 // Here we store the Run LSID in the Workflow Run Manager Singleton 927 // so the WorkflowRunEntryHandler can figure out which runs for which 928 // workflows to save 929 workflowRunManager.addRunToSelectedRuns(runLSID); 930 931 // Here we add the workflow the run is associated with as an initiator 932 // of the SaveKAR 933 savekar.addSaveInitiator(workflow); 934 } 935 } catch (Exception exc) { 936 exc.printStackTrace(); 937 } 938 } 939 940 // turn off saving PROV to the KAR since we won't use 941 // to open the the run. 942 final boolean saveValue = ProvKAREntryHandler.setSave(false); 943 try { 944 savekar.saveToDisk(_frame, overrideModDeps); 945 } finally { 946 // restore the previous save value. 947 ProvKAREntryHandler.setSave(saveValue); 948 } 949 return savekar; 950 } 951 952 953 private void resetProvenanceInfo(ProvenanceStore provenanceStore) { 954 955 if (provenanceStore == null){ 956 log.error("WorkflowRunManagerPanel resetProvenanceInfo provenanceStore == null!"); 957 } 958 else{ 959 // remove listener from old workflowRunManager list, add to new 960 if(workflowRunManager !=null){ 961 workflowRunManager.removeWorkflowRunManagerEventListener(this); 962 } 963 964 WorkflowRunManagerManager wrmm = WorkflowRunManagerManager.getInstance(); 965 workflowRunManager = wrmm.getWRM(_frame, provenanceStore); 966 workflowRunManager.addWorkflowRunManagerEventListener(this); 967 968 if (!workflowRunManager.isConnected()){ 969 reconnect(); 970 } 971 972 ProvenanceRecorder pr = workflowRunManager.getProvenanceRecorder(); 973 if (pr != null){ 974 pr.removeEnabledListener(this); 975 pr.addEnabledListener(this); 976 } 977 } 978 } 979 980 /** 981 * Reconnect workflowRunManager to provenance store. 982 */ 983 private void reconnect() { 984 985 if (workflowRunManager.isConnected()) { 986 try { 987 workflowRunManager.disconnect(); 988 } catch (IllegalActionException e) { 989 log.error("Unable to disconnect from provenance store." + e.getMessage()); 990 return; 991 } catch (QueryException e) { 992 log.error("Unable to disconnect from provenance store." + e.getMessage()); 993 return; 994 } 995 } 996 997 workflowRunManager.connect(); 998 999 if (workflowRunManager.usingSupportedRecordingType()){ 1000 unsupportedRecordingTypeMsg.setVisible(false); 1001 } 1002 else{ 1003 unsupportedRecordingTypeMsg.setVisible(true); 1004 } 1005 1006 if (!workflowRunManager.isConnected()) { 1007 log.error("WorkflowRunManagerPanel reconnect() unable to connect."); 1008 return; 1009 } 1010 1011 } 1012 1013 1014 /** 1015 * get KeplerLSIDs of workflowRuns for rows 1016 * 1017 * @param rows 1018 * @return KeplerLSIDs associated with rows 1019 */ 1020 private List<KeplerLSID> getWorkflowRunLSIDsForRows(int[] rows) { 1021 1022 ArrayList<KeplerLSID> lsids = new ArrayList<KeplerLSID>(); 1023 ArrayList<WorkflowRun> workflowRuns = wrmTableModel 1024 .getWorkflowRunsForRows(rows); 1025 ListIterator<WorkflowRun> wfRunItr = workflowRuns.listIterator(); 1026 while (wfRunItr.hasNext()) { 1027 lsids.add(wfRunItr.next().getExecLSID()); 1028 } 1029 1030 return lsids; 1031 } 1032 1033 /** 1034 * anonymous class to handle list selection events 1035 */ 1036 private ListSelectionListener _listSelectionListener = new ListSelectionListener() { 1037 1038 @Override 1039 public void valueChanged(ListSelectionEvent e) { 1040 1041 // no need to do this during multiple events 1042 if (!e.getValueIsAdjusting()) { 1043 1044 if (getSorterSelectedRows().length == 1 && _isProvenanceEnabled) { 1045 int sortedRow = getSorterSelectedRows()[0]; 1046 WorkflowRun selectedRun = wrmTableModel 1047 .getWorkflowRunForRow(sortedRow); 1048 StateChangeEvent stateEvent = new StateChangeEvent(kgf, 1049 WorkflowRun.WORKFLOWRUN_SELECTED, selectedRun); 1050 StateChangeMonitor.getInstance().notifyStateChange( 1051 stateEvent); 1052 } 1053 1054 } 1055 } 1056 }; 1057 1058 /** 1059 * Set the tagging target to WorkflowRun and set the objects we're tagging to the 1060 * currently selected rows (skipping preview runs). 1061 */ 1062 private synchronized void setTagContextToCurrentlySelectedRows() { 1063 // Set the tagging indicator to a workflow run 1064 WindowIdentifier windowIdentifier = new WindowIdentifier("test" 1065 + getWindowId(), kgf); 1066 TaggingContextManager.getInstance(windowIdentifier).setTaggingContext( 1067 TaggingContext.WORKFLOW_RUN); 1068 1069 // Set the object we're currently tagging. 1070 // Load the new tags from that target 1071 Collection<WorkflowRun> workflowRuns = wrmTableModel 1072 .getWorkflowRunsForRows(getSorterSelectedRows()); 1073 _lastSelectedRows = getSorterSelectedRows(); 1074 Collection<NamedObj> nos = new ArrayList<NamedObj>(); 1075 1076 for (WorkflowRun run: workflowRuns) { 1077 if (!run.getType().equals(WorkflowRun.type.Preview.toString())&& 1078 !run.getType().equals(WorkflowRun.type.Preview_Error.toString())){ 1079 nos.add(run); 1080 } 1081 } 1082 TaggingContextManager.getInstance(windowIdentifier).setTagTarget(nos); 1083 } 1084 1085 /** 1086 * Set the tagging target to WorkflowRun and set the objects we're tagging to the 1087 * currently selected rows. 1088 */ 1089 private synchronized void setTagContextToRows(int[] rows) { 1090 1091 // Set the tagging indicator to a workflow run 1092 WindowIdentifier windowIdentifier = new WindowIdentifier("test" 1093 + getWindowId(), kgf); 1094 TaggingContextManager.getInstance(windowIdentifier).setTaggingContext( 1095 TaggingContext.WORKFLOW_RUN); 1096 1097 // Set the object we're currently tagging. 1098 // Load the new tags from that target 1099 Collection<WorkflowRun> workflowRuns = wrmTableModel 1100 .getWorkflowRunsForRows(rows); 1101 Collection<NamedObj> nos = new ArrayList<NamedObj>(); 1102 1103 Iterator<WorkflowRun> itr = workflowRuns.iterator(); 1104 while (itr.hasNext()) { 1105 nos.add(itr.next()); 1106 } 1107 TaggingContextManager.getInstance(windowIdentifier).setTagTarget(nos); 1108 } 1109 1110 private synchronized void setTagContextToWorkflow(){ 1111 // Change the tagging indicator to the workflow 1112 WindowIdentifier windowIdentifier = new WindowIdentifier( 1113 "test" + getWindowId(), kgf); 1114 TaggingContextManager.getInstance(windowIdentifier) 1115 .setTaggingContext(TaggingContext.WORKFLOW); 1116 if (model == null){ 1117 return; 1118 } 1119 if (model.toplevel() == null){ 1120 return; 1121 } 1122 1123 CompositeActor toplevel = (CompositeActor) model.toplevel(); 1124 TaggingContextManager.getInstance(windowIdentifier) 1125 .setTagTarget(toplevel, 1126 TaggingContextManager.getInstance( 1127 windowIdentifier) 1128 .getTagBarInsertionUI() 1129 .getExistingTagsPanel()); 1130 } 1131 1132 1133 @Override 1134 public void actionPerformed(ActionEvent e) { 1135 1136 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 1137 1138 if (e.getActionCommand().equals(OPEN_RUNS)) { 1139 // open run(s) for selected row(s) 1140 int openResponse = 0; 1141 try { 1142 List<KeplerLSID> rowLsids = getWorkflowRunLSIDsForRows(getSorterSelectedRows()); 1143 if (rowLsids.size() > openWarningLimit) { 1144 openResponse = JOptionPane.showConfirmDialog(_frame, 1145 "Do you really want to open " + rowLsids.size() 1146 + " runs?", "Open many runs?", 1147 JOptionPane.YES_NO_OPTION); 1148 if (openResponse == JOptionPane.NO_OPTION) { 1149 return; 1150 } 1151 } 1152 1153 // String currentModDeps = 1154 // ModuleDependencyUtil.buildModuleDependenciesString(); 1155 1156 // determine module dependencies of selected runs. In order to 1157 // get here, all runs should have same mod deps, so just use 1158 // the first's 1159 ArrayList<WorkflowRun> workflowRuns = wrmTableModel 1160 .getWorkflowRunsForRows(getSorterSelectedRows()); 1161 WorkflowRun wr = workflowRuns.get(0); 1162 String runModDepsStr = wr.getModuleDependencies(); 1163 Vector<String> runModDeps = ModuleDependencyUtil 1164 .parseDependencyString(runModDepsStr); 1165 1166 if (!ModuleDependencyUtil 1167 .checkIfModuleDependenciesSatisfied(runModDeps)) { 1168 log.debug("run module dependencies are NOT satisfied, calling ImportModuleDependenciesAction..."); 1169 1170 // module-dependencies aren't satisfied, invoke 1171 // ImportModuleDependenciesAction 1172 ImportModuleDependenciesAction imda = new ImportModuleDependenciesAction( 1173 _frame); 1174 1175 List<KeplerLSID> runLSIDs = getWorkflowRunLSIDsForRows(getSorterSelectedRows()); 1176 SaveKAR saveKAR = createTempKAR(runLSIDs, runModDepsStr); 1177 1178 imda.setArchiveFile(saveKAR.getFile()); 1179 imda.updateHistoryAndLastDirectory(false); 1180 imda.setDependencies(runModDeps); 1181 imda.actionPerformed(e); 1182 1183 // now clear any runs added to the "selected" list 1184 // in prep for any subsequent saves 1185 workflowRunManager.clearSelectedRuns(); 1186 } else { 1187 log.debug("run module dependencies are satisfied, calling openRuns..."); 1188 openRuns(getWorkflowRunLSIDsForRows(getSorterSelectedRows())); 1189 } 1190 1191 } catch (QueryException e1) { 1192 // TODO Auto-generated catch block 1193 e1.printStackTrace(); 1194 } 1195 1196 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1197 1198 } else if (e.getActionCommand().equals(EXPORT_ARCHIVE) 1199 || e.getActionCommand().equals(UPLOAD_TO_REPOSITORY)) { 1200 // export and possibly upload runs for selected row(s). 1201 1202 List<KeplerLSID> runRowLSIDs = getWorkflowRunLSIDsForRows(getSorterSelectedRows()); 1203 1204 // determine module dependencies of selected runs. In order to get 1205 // here, all runs should have same mod deps, so just use the first's 1206 ArrayList<WorkflowRun> workflowRuns = wrmTableModel 1207 .getWorkflowRunsForRows(getSorterSelectedRows()); 1208 WorkflowRun wr = workflowRuns.get(0); 1209 String runModDepsStr = wr.getModuleDependencies(); 1210 Vector<String> runModDeps = ModuleDependencyUtil 1211 .parseDependencyString(runModDepsStr); 1212 1213 if (!ModuleDependencyUtil 1214 .checkIfModuleDependenciesSatisfied(runModDeps)) { 1215 // module-dependencies aren't satisfied, invoke 1216 // ImportModuleDependenciesAction 1217 ImportModuleDependenciesAction imda = new ImportModuleDependenciesAction( 1218 _frame); 1219 1220 List<KeplerLSID> runLSIDs = getWorkflowRunLSIDsForRows(getSorterSelectedRows()); 1221 SaveKAR saveKAR = createTempKAR(runLSIDs, runModDepsStr); 1222 1223 imda.setExportMode(true); 1224 imda.updateHistoryAndLastDirectory(false); 1225 imda.setArchiveFile(saveKAR.getFile()); 1226 imda.setDependencies(runModDeps); 1227 imda.actionPerformed(e); 1228 if (imda.getNeedToDoAForceExport()){ 1229 // since a force export can fail to include artifacts from inactive modules 1230 // do not override the module dependency list, 1231 ExportRunsArchiveAction eraa = new ExportRunsArchiveAction( 1232 getParentFrame(), runRowLSIDs, null); 1233 if (e.getActionCommand().equals(EXPORT_ARCHIVE)) { 1234 eraa.setUpload(false); 1235 } else if (e.getActionCommand().equals(UPLOAD_TO_REPOSITORY)) { 1236 try { 1237 RepositoryManager repoManager = RepositoryManager 1238 .getInstance(); 1239 Repository saveRepository = repoManager 1240 .getSaveRepository(); 1241 if (saveRepository == null) { 1242 // MessageHandler.error("To upload to a remote repository, select one from the " 1243 // + "component search preferences"); 1244 JOptionPane.showMessageDialog(_frame, 1245 "To upload to a remote repository, select one from the " 1246 + "component search preferences", 1247 "Cannot Save", JOptionPane.ERROR_MESSAGE); 1248 return; 1249 } 1250 } catch (IOException e1) { 1251 // TODO Auto-generated catch block 1252 e1.printStackTrace(); 1253 } catch (Exception e1) { 1254 // TODO Auto-generated catch block 1255 e1.printStackTrace(); 1256 } 1257 1258 } 1259 eraa.actionPerformed(e); 1260 } 1261 1262 // now clear any runs added to the "selected" list 1263 // in prep for any subsequent saves 1264 workflowRunManager.clearSelectedRuns(); 1265 } else { 1266 1267 ExportRunsArchiveAction eraa = new ExportRunsArchiveAction( 1268 getParentFrame(), runRowLSIDs, runModDepsStr); 1269 if (e.getActionCommand().equals(EXPORT_ARCHIVE)) { 1270 eraa.setUpload(false); 1271 } else if (e.getActionCommand().equals(UPLOAD_TO_REPOSITORY)) { 1272 try { 1273 RepositoryManager repoManager = RepositoryManager 1274 .getInstance(); 1275 Repository saveRepository = repoManager 1276 .getSaveRepository(); 1277 if (saveRepository == null) { 1278 // MessageHandler.error("To upload to a remote repository, select one from the " 1279 // + "component search preferences"); 1280 JOptionPane.showMessageDialog(_frame, 1281 "To upload to a remote repository, select one from the " 1282 + "component search preferences", 1283 "Cannot Save", JOptionPane.ERROR_MESSAGE); 1284 return; 1285 } 1286 } catch (IOException e1) { 1287 // TODO Auto-generated catch block 1288 e1.printStackTrace(); 1289 } catch (Exception e1) { 1290 // TODO Auto-generated catch block 1291 e1.printStackTrace(); 1292 } 1293 1294 } 1295 eraa.actionPerformed(e); 1296 1297 // now clear any runs added to the "selected" list 1298 // in prep for any subsequent saves 1299 workflowRunManager.clearSelectedRuns(); 1300 } 1301 1302 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1303 1304 } else if (e.getActionCommand().equals(DELETE_RUN)) { 1305 // delete run(s) for selected row(s) 1306 1307 int deleteResponse = 0; 1308 1309 if (isIncompleteRunSelected()) { 1310 deleteResponse = JOptionPane 1311 .showConfirmDialog( 1312 _frame, 1313 "WARNING! An incomplete run is selected, deleting " 1314 + "a run that is still executing\n may corrupt your provenance store, " 1315 + "are you sure you would like to proceed?", 1316 "WARNING Possible corruption!", JOptionPane.YES_NO_OPTION); 1317 } else if (getSorterSelectedRows().length == 1) { 1318 deleteResponse = JOptionPane.showConfirmDialog(_frame, 1319 "Do you want to delete " 1320 + getSorterSelectedRows().length + " run?", 1321 "Delete runs?", JOptionPane.YES_NO_OPTION); 1322 } else { 1323 deleteResponse = JOptionPane.showConfirmDialog(_frame, 1324 "Do you want to delete " 1325 + getSorterSelectedRows().length + " runs?", 1326 "Delete runs?", JOptionPane.YES_NO_OPTION); 1327 } 1328 if (deleteResponse == JOptionPane.YES_OPTION) { 1329 ProvenanceRecorder pr = workflowRunManager 1330 .getProvenanceRecorder(); 1331 Recording recording = pr.getRecording(); 1332 1333 List<KeplerLSID> runsToDelete = getWorkflowRunLSIDsForRows(getSorterSelectedRows()); 1334 if (!runsToDelete.isEmpty()) { 1335 1336 DeleteRunsSwingWorker drsw = new DeleteRunsSwingWorker( 1337 recording, runsToDelete, authenticate); 1338 drsw.execute(); 1339 drsw.addPropertyChangeListener(this); 1340 1341 } else { 1342 log.error("WorkflowRunManagerPanel " + 1343 "_actionListener ERROR, no runs to delete!"); 1344 setCursor(Cursor.getDefaultCursor()); 1345 } 1346 1347 setTagContextToWorkflow(); 1348 }else{ 1349 setCursor(Cursor.getDefaultCursor()); 1350 } 1351 1352 } else if (e.getActionCommand().equals(VIEW_RUN_LSID)) { 1353 1354 int[] rows = getSorterSelectedRows(); 1355 if (rows.length == 1) { 1356 List<KeplerLSID> rowLsids = getWorkflowRunLSIDsForRows(rows); 1357 KeplerLSID lsid = rowLsids.get(0); 1358 try { 1359 WorkflowRun wr = workflowRunManager.getRun(lsid 1360 .toStringWithoutRevision()); 1361 if (wr != null) { 1362 1363 LSIDViewer lv = new LSIDViewer(); 1364 lv.setEditingEnabled(false); 1365 lv.initialize(wr); 1366 lv.setSize(new Dimension(400, 300)); 1367 lv.setLocationRelativeTo(_frame); 1368 lv.setVisible(true); 1369 } 1370 } catch (Exception exc) { 1371 exc.printStackTrace(); 1372 } 1373 } 1374 1375 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1376 1377 } else if (e.getActionCommand().equals(VIEW_WORKFLOW_LSID)) { 1378 1379 int[] rows = getSorterSelectedRows(); 1380 if (rows.length == 1) { 1381 1382 List<KeplerLSID> rowLsids = getWorkflowRunLSIDsForRows(rows); 1383 KeplerLSID runLSID = rowLsids.get(0); 1384 try { 1385 ComponentEntity<?> workflow = workflowRunManager 1386 .getAssociatedWorkflowForWorkflowRun(runLSID); 1387 if (workflow != null) { 1388 LSIDViewer lv = new LSIDViewer(); 1389 lv.setEditingEnabled(false); 1390 lv.initialize(workflow); 1391 lv.setSize(new Dimension(400, 300)); 1392 lv.setLocationRelativeTo(_frame); 1393 lv.setVisible(true); 1394 } 1395 } catch (Exception exc) { 1396 exc.printStackTrace(); 1397 } 1398 } 1399 1400 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1401 1402 } else if (e.getActionCommand().equals(DOWNLOAD_KAR)) { 1403 1404 ArrayList<WorkflowRun> selectedRuns = wrmTableModel 1405 .getWorkflowRunsForRows(getSorterSelectedRows()); 1406 ArrayList<KeplerLSID> failedDownloads = new ArrayList<KeplerLSID>(); 1407 for (WorkflowRun run : selectedRuns) { 1408 // only attempt to download preview runs. 1409 if (run.getType().equals(WorkflowRun.type.Preview.toString()) 1410 || run.getType().equals( 1411 WorkflowRun.type.Preview_Error.toString())) { 1412 boolean downloadSuccess = false; 1413 try { 1414 downloadSuccess = workflowRunManager.downloadRunKAR( 1415 run.getExecLSID(), authenticate); 1416 } catch (AuthenticationException e1) { 1417 // TODO Auto-generated catch block 1418 e1.printStackTrace(); 1419 } 1420 if (!downloadSuccess) { 1421 failedDownloads.add(run.getExecLSID()); 1422 } 1423 } 1424 } 1425 if (!failedDownloads.isEmpty()) { 1426 JOptionPane.showMessageDialog(_frame, 1427 "" + failedDownloads.size() 1428 + " KAR(s) failed to download.", 1429 "Download Error", JOptionPane.ERROR_MESSAGE); 1430 } 1431 1432 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1433 1434 } else if (e.getActionCommand().equals(REFRESH)) { 1435 // set runs 1436 try { 1437 queryForAllRuns(); 1438 filterRuns(); 1439 } catch (AuthenticationException e1) { 1440 // TODO Auto-generated catch block 1441 e1.printStackTrace(); 1442 } 1443 1444 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1445 1446 } else if (e.getActionCommand().equals(CHANGE_COL_VISIBLE)) { 1447 // TODO under construction and not currently used. 1448 1449 // FIXME hardcode etc, temp test to toggle a col 1450 // visible/invisible 1451 /* 1452 * try { 1453 * 1454 * int startTimeColumn; startTimeColumn = wrmjTable 1455 * .convertColumnIndexToView(wrmDefaults 1456 * .getDefaultColIndex(WRMDefaults.START_TIME)); 1457 * System.out.println("trying to toggle colgroup:" + startTimeColumn 1458 * + " visibility"); 1459 * 1460 * GroupableTableColumnModel cm = (GroupableTableColumnModel) 1461 * wrmjTable .getColumnModel(); if (tempVisibleToggle == true) { 1462 * tempVisibleToggle = false; } else { tempVisibleToggle = true; } 1463 * 1464 * if (tempVisibleToggle) { // set it visible in default location cm 1465 * .setColumnGroupVisible( wrmDefaults 1466 * .getDefaultColIndex(WRMDefaults.START_TIME), cm 1467 * .getColumnGroup(wrmDefaults 1468 * .getDefaultColIndex(WRMDefaults.START_TIME)), tempVisibleToggle); 1469 * } else { // remove it from current location 1470 * cm.setColumnGroupVisible(startTimeColumn, cm 1471 * .getColumnGroup(startTimeColumn), tempVisibleToggle); } 1472 * 1473 * if (tempVisibleToggle) { 1474 * 1475 * wrmjTable .getColumnModel() .getColumn( wrmDefaults 1476 * .getDefaultColIndex(WRMDefaults.START_TIME)) .setCellRenderer( 1477 * new WRMDefaultTableCellRenderer()); wrmjTable .getColumnModel() 1478 * .getColumn( wrmDefaults 1479 * .getDefaultColIndex(WRMDefaults.START_TIME)) 1480 * .setHeaderValue(WRMDefaults.START_TIME); 1481 * 1482 * // wrmjTable.setTableHeader(new // 1483 * GroupableTableHeader((GroupableTableColumnModel 1484 * )wrmjTable.getColumnModel())); // 1485 * sorter.setTableHeader(wrmjTable.getTableHeader()); } 1486 * 1487 * // refresh table so search string of hidden column which // went 1488 * // away goes into effect // /queryDBforRuns(); } catch (Exception 1489 * e1) { // TODO Auto-generated catch block e1.printStackTrace(); } 1490 */ 1491 1492 //setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1493 } else if (e.getActionCommand().equals(SHOW_GRAPHICAL_ACTORS_OUTPUTS)) { 1494 1495 try { 1496 // FIXME copied from OPEN_RUNS 1497 1498 // open run(s) for selected row(s) 1499 int openResponse = 0; 1500 List<KeplerLSID> rowLsids = getWorkflowRunLSIDsForRows(getSorterSelectedRows()); 1501 if (rowLsids.size() > openWarningLimit) { 1502 openResponse = JOptionPane.showConfirmDialog(_frame, 1503 "Do you really want to show outputs for " + rowLsids.size() 1504 + " runs?", "Show many runs?", 1505 JOptionPane.YES_NO_OPTION); 1506 if (openResponse == JOptionPane.NO_OPTION) { 1507 return; 1508 } 1509 } 1510 1511 ArrayList<WorkflowRun> workflowRuns = wrmTableModel 1512 .getWorkflowRunsForRows(getSorterSelectedRows()); 1513 1514 Queryable queryable = workflowRunManager.getQueryable(); 1515 1516 for(WorkflowRun run : workflowRuns) { 1517 String runModDepsStr = run.getModuleDependencies(); 1518 Vector<String> runModDeps = ModuleDependencyUtil 1519 .parseDependencyString(runModDepsStr); 1520 1521 if (!ModuleDependencyUtil 1522 .checkIfModuleDependenciesSatisfied(runModDeps)) { 1523 StringBuilder buf = new StringBuilder("Current Kepler suite " + 1524 "does not include modules used in run:\n"); 1525 for(Map.Entry<String, Version> entry : 1526 ModuleDependencyUtil.getUnsatisfiedDependencies(runModDeps).entrySet()) { 1527 String versionStr; 1528 Version version = entry.getValue(); 1529 if(version == null) { 1530 versionStr = "svn trunk"; 1531 } else { 1532 versionStr = version.getVersionString(); 1533 } 1534 buf.append(entry.getKey()) 1535 .append(" ") 1536 .append(versionStr) 1537 .append("\n"); 1538 } 1539 buf.append("Try to show graphical actor outputs anyway?"); 1540 if(!MessageHandler.yesNoQuestion(buf.toString())) { 1541 continue; 1542 } 1543 } 1544 1545 Integer execId = null; 1546 try { 1547 execId = queryable.getExecutionForExecutionLSID(run.getExecLSID()); 1548 } catch (QueryException ex) { 1549 MessageHandler.error("Error querying execution id for run.", ex); 1550 continue; 1551 } 1552 1553 if(execId == null) { 1554 MessageHandler.error("Could not get execution id for run."); 1555 continue; 1556 } 1557 1558 RecordPlayer player = new RecordPlayer(queryable, null); 1559 player.setExecuteGraphicalActors(true); 1560 try { 1561 player.play(execId); 1562 } catch (QueryException | RecordingException ex) { 1563 MessageHandler.error("Error replaying run.", ex); 1564 continue; 1565 } 1566 } 1567 } finally { 1568 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1569 } 1570 1571 } 1572 } 1573 1574 1575 /** 1576 * Show WRM context menu if mouseEvent.isPopupTrigger 1577 */ 1578 private void jTableShowContextMenu(java.awt.event.MouseEvent mouseEvent) { 1579 1580 if (mouseEvent.isPopupTrigger() || mouseEvent.isControlDown()) { 1581 int row = wrmjTable.rowAtPoint(mouseEvent.getPoint()); 1582 int sorterRow = sorter.modelIndex(row); 1583 int[] sorterSelectedRows = getSorterSelectedRows(); 1584 1585 if (sorterRow != -1) { 1586 1587 boolean clickWasOnASelectedRow = false; 1588 for (int i = 0; i < sorterSelectedRows.length; i++) { 1589 if (sorterRow == sorterSelectedRows[i]) { 1590 clickWasOnASelectedRow = true; 1591 break; 1592 } 1593 } 1594 if (!clickWasOnASelectedRow) { 1595 wrmjTable.setRowSelectionInterval(row, row); 1596 sorterSelectedRows = getSorterSelectedRows(); 1597 } 1598 1599 // only show the context menu if at least one row 1600 // is selected. 1601 if (sorterSelectedRows.length > 0) { 1602 1603 if (_isProvenanceEnabled) { 1604 1605 popupMenu.removeAll(); 1606 1607 if (isPreviewRunSelected()) { 1608 popupMenu.add(downloadMenuItem); 1609 popupMenu.add(viewRunLsidMenuItem); 1610 downloadMenuItem.setEnabled(true); 1611 viewRunLsidMenuItem.setEnabled(true); 1612 if (sorterSelectedRows.length > 1) { 1613 viewRunLsidMenuItem.setEnabled(false); 1614 } 1615 } else { 1616 popupMenu.add(openMenuItem); 1617 popupMenu.addSeparator(); 1618 popupMenu.add(showGraphicalActorsOutputsMenuItem); 1619 popupMenu.addSeparator(); 1620 popupMenu.add(exportMenuItem); 1621 popupMenu.add(uploadMenuItem); 1622 popupMenu.add(viewRunLsidMenuItem); 1623 popupMenu.add(viewWorkflowLSIDMenuItem); 1624 popupMenu.addSeparator(); 1625 popupMenu.add(deleteMenuItem); 1626 //popupMenu.add(changeColVisibleMenuItem); 1627 1628 openMenuItem.setEnabled(true); 1629 exportMenuItem.setEnabled(true); 1630 uploadMenuItem.setEnabled(true); 1631 deleteMenuItem.setEnabled(true); 1632 viewRunLsidMenuItem.setEnabled(true); 1633 viewWorkflowLSIDMenuItem.setEnabled(true); 1634 1635 // disallow export, upload, open (any kar creation) 1636 // of kars with multiple runs. see bug#5175 1637 if (sorterSelectedRows.length > 1) { 1638 openMenuItem.setEnabled(false); 1639 exportMenuItem.setEnabled(false); 1640 uploadMenuItem.setEnabled(false); 1641 viewRunLsidMenuItem.setEnabled(false); 1642 viewWorkflowLSIDMenuItem.setEnabled(false); 1643 } 1644 1645 // disallow export and upload when an 1646 // incomplete run is selected 1647 if (isIncompleteRunSelected()){ 1648 exportMenuItem.setEnabled(false); 1649 uploadMenuItem.setEnabled(false); 1650 } 1651 1652 // disallow open, export and upload when runs have incompatible 1653 // module dependencies (since kar's mod deps get set to run(s') 1654 // mod deps) 1655 if (areRunsWithIncompatibleModuleDependenciesSelected()) { 1656 openMenuItem.setEnabled(false); 1657 exportMenuItem.setEnabled(false); 1658 uploadMenuItem.setEnabled(false); 1659 1660 ///TODO once bug#5175 is fixed, this warning becomes relevant again. 1661 // until then it doesn't make sense to show. 1662 ///popupMenu.addSeparator(); 1663 ///popupMenu.add(runsIncompatModDepsWarningMenuItem); 1664 ///runsIncompatModDepsWarningMenuItem.setEnabled(false); 1665 } 1666 } 1667 1668 popupMenu.show(mouseEvent.getComponent(), mouseEvent 1669 .getX(), mouseEvent.getY()); 1670 } else { 1671 popupMenu.removeAll(); 1672 popupMenu.add(provWarningMenuItem); 1673 provWarningMenuItem.setEnabled(false); 1674 1675 popupMenu.show(mouseEvent.getComponent(), mouseEvent 1676 .getX(), mouseEvent.getY()); 1677 } 1678 } 1679 } 1680 } 1681 } 1682 1683 1684 /** 1685 * Return the TableSorter selected rows translated from the table selected 1686 * rows. 1687 * 1688 * @return sorterSelectedRows 1689 */ 1690 private int[] getSorterSelectedRows() { 1691 int[] selectedRows = wrmjTable.getSelectedRows(); 1692 // initialize to the proper length 1693 int[] sorterSelectedRows = selectedRows; 1694 1695 for (int i = 0; i < selectedRows.length; i++) { 1696 sorterSelectedRows[i] = sorter.modelIndex(selectedRows[i]); 1697 } 1698 return sorterSelectedRows; 1699 } 1700 1701 1702 private boolean isPreviewRunSelected(){ 1703 1704 int[] sorterSelectedRows = getSorterSelectedRows(); 1705 1706 if (sorterSelectedRows.length > 0) { 1707 for (int i=0; i<sorterSelectedRows.length; i++){ 1708 WorkflowRun selectedRun = wrmTableModel 1709 .getWorkflowRunForRow(sorterSelectedRows[i]); 1710 1711 if (selectedRun.getType().equals(WorkflowRun.type.Preview.toString()) 1712 || selectedRun.getType().equals(WorkflowRun.type.Preview_Error.toString())){ 1713 return true; 1714 } 1715 } 1716 } 1717 return false; 1718 } 1719 1720 private boolean isIncompleteRunSelected(){ 1721 1722 int[] sorterSelectedRows = getSorterSelectedRows(); 1723 1724 if (sorterSelectedRows.length > 0) { 1725 for (int i=0; i<sorterSelectedRows.length; i++){ 1726 WorkflowRun selectedRun = wrmTableModel 1727 .getWorkflowRunForRow(sorterSelectedRows[i]); 1728 1729 if (selectedRun.getDuration() < 0){ 1730 return true; 1731 } 1732 } 1733 } 1734 return false; 1735 } 1736 1737 private boolean areRunsWithIncompatibleModuleDependenciesSelected(){ 1738 1739 int[] sorterSelectedRows = getSorterSelectedRows(); 1740 1741 if (sorterSelectedRows.length > 1) { 1742 1743 String run0ModDeps = null; 1744 String runXModDeps = null; 1745 for (int i=0; i<sorterSelectedRows.length; i++){ 1746 WorkflowRun selectedRun = wrmTableModel 1747 .getWorkflowRunForRow(sorterSelectedRows[i]); 1748 1749 if (i == 0){ 1750 run0ModDeps = selectedRun.getModuleDependencies(); 1751 } 1752 runXModDeps = selectedRun.getModuleDependencies(); 1753 if (runXModDeps == null){ 1754 log.error("WorkflowRunManagerPanel jTableShowContextMenu runXModDeps == null "); 1755 } 1756 if (run0ModDeps == null){ 1757 log.error("WorkflowRunManagerPanel jTableShowContextMenu run0ModDeps == null "); 1758 } 1759 if (!runXModDeps.equals(run0ModDeps)){ 1760 return true; 1761 } 1762 } 1763 } 1764 return false; 1765 } 1766 1767 1768 /** 1769 * Setup the WRM context menu. 1770 */ 1771 private void setupContextMenu() { 1772 1773 openMenuItem.removeActionListener(this); 1774 openMenuItem.addActionListener(this); 1775 openMenuItem.setActionCommand(OPEN_RUNS); 1776 exportMenuItem.removeActionListener(this); 1777 exportMenuItem.addActionListener(this); 1778 exportMenuItem.setActionCommand(EXPORT_ARCHIVE); 1779 uploadMenuItem.removeActionListener(this); 1780 uploadMenuItem.addActionListener(this); 1781 uploadMenuItem.setActionCommand(UPLOAD_TO_REPOSITORY); 1782 deleteMenuItem.removeActionListener(this); 1783 deleteMenuItem.addActionListener(this); 1784 deleteMenuItem.setActionCommand(DELETE_RUN); 1785 changeColVisibleMenuItem.removeActionListener(this); 1786 changeColVisibleMenuItem.addActionListener(this); 1787 changeColVisibleMenuItem.setActionCommand(CHANGE_COL_VISIBLE); 1788 viewRunLsidMenuItem.removeActionListener(this); 1789 viewRunLsidMenuItem.addActionListener(this); 1790 viewRunLsidMenuItem.setActionCommand(VIEW_RUN_LSID); 1791 viewWorkflowLSIDMenuItem.removeActionListener(this); 1792 viewWorkflowLSIDMenuItem.addActionListener(this); 1793 viewWorkflowLSIDMenuItem.setActionCommand(VIEW_WORKFLOW_LSID); 1794 downloadMenuItem.removeActionListener(this); 1795 downloadMenuItem.addActionListener(this); 1796 downloadMenuItem.setActionCommand(DOWNLOAD_KAR); 1797 showGraphicalActorsOutputsMenuItem.removeActionListener(this); 1798 showGraphicalActorsOutputsMenuItem.addActionListener(this); 1799 showGraphicalActorsOutputsMenuItem.setActionCommand(SHOW_GRAPHICAL_ACTORS_OUTPUTS); 1800 1801 popupMenu.add(openMenuItem); 1802 popupMenu.addSeparator(); 1803 popupMenu.add(showGraphicalActorsOutputsMenuItem); 1804 popupMenu.addSeparator(); 1805 popupMenu.add(exportMenuItem); 1806 popupMenu.add(uploadMenuItem); 1807 popupMenu.add(viewRunLsidMenuItem); 1808 popupMenu.add(viewWorkflowLSIDMenuItem); 1809 popupMenu.addSeparator(); 1810 popupMenu.add(deleteMenuItem); 1811 // popupMenu.add(changeColVisibleMenuItem); 1812 1813 1814 Font currentFont = runsIncompatModDepsWarningMenuItem.getFont(); 1815 Font italicFont = new Font(currentFont.getName(), Font.ITALIC, currentFont.getSize()); 1816 runsIncompatModDepsWarningMenuItem.setFont(italicFont); 1817 } 1818 1819 1820 @Override 1821 public void workflowRunManagerEventOccurred(WorkflowRunManagerEvent evt) { 1822 1823 if (evt.getEventName().equals(WorkflowRunManagerEvent.PROGRAMATIC_FILTER)){ 1824 HashMap<String,String> columnsAndFilters = (HashMap<String, String>) evt.getEventData(); 1825 Iterator<String> itr = columnsAndFilters.keySet().iterator(); 1826 while (itr.hasNext()){ 1827 String columnName = itr.next(); 1828 String columnFilter = columnsAndFilters.get(columnName); 1829 log.debug("WorkflowRunManagerPanel workflowRunManagerEventOccurred PROGRAMATIC_FILTER calling setSearchStringAndFilter("+columnName+","+columnFilter+")"); 1830 setSearchStringAndFilter(columnName, columnFilter); 1831 } 1832 } 1833 else{ 1834 filterRuns(); 1835 } 1836 1837 /* 1838 Iterator<KeplerLSID> lsidItr = evt.getEventLSIDs().iterator(); 1839 while (lsidItr.hasNext()){ 1840 KeplerLSID lsid = lsidItr.next(); 1841 WorkflowRun run = workflowRunManager.getWorkflowRuns().get(lsid.toStringWithoutRevision()); 1842 if (run != null){ 1843 System.out.println("run with lsid: " + lsid + " has execId:"+ run.getExecId()); 1844 } 1845 } 1846 */ 1847 1848 // since run execLSIDs now change revision on tag events, this is here to 1849 // ensure tagging context stays up to date with the latest WorkflowRun objects 1850 if (evt.getEventName().equals(WorkflowRunManagerEvent.TAG_ADDED) || 1851 evt.getEventName().equals(WorkflowRunManagerEvent.TAG_REMOVED)){ 1852 if (_lastSelectedRows != null && wrmjTable.getRowCount() > 0 1853 && evt.isLastEvent() && _isProvenanceEnabled){ 1854 setTagContextToRows(_lastSelectedRows); 1855 } 1856 } 1857 1858 } 1859 1860 /* 1861 * (non-Javadoc) 1862 * @see org.kepler.provenance.ProvenanceEnabledListener#toggle(boolean) 1863 */ 1864 @Override 1865 public void toggle(boolean enabled) { 1866 _isProvenanceEnabled = enabled; 1867 if (!_isProvenanceEnabled){ 1868 setTagContextToWorkflow(); 1869 } 1870 } 1871 1872 @Override 1873 public void updateFrameComponents(Components components) { 1874 //KeplerGraphFrame frame = components.getFrame(); 1875 1876 model = ((PtolemyFrame) _frame).getModel(); 1877 ProvenanceRecorder pr = ProvenanceRecorder.getDefaultProvenanceRecorder(model); 1878 1879 if (pr != null){ 1880 pr.removeEnabledListener(this); 1881 pr.addEnabledListener(this); 1882 } 1883 } 1884 1885 @Override 1886 public void dispose(KeplerGraphFrame frame) { 1887 1888 } 1889 1890 @Override 1891 public int compareTo(KeplerGraphFrameUpdater o) { 1892 if (this == o) 1893 return 0; 1894 else 1895 //must be greater than provenance 1896 return 1; 1897 } 1898 1899 1900 1901 private static class ComboBoxRenderer extends JLabel implements ListCellRenderer { 1902 1903 public ComboBoxRenderer() { 1904 setOpaque(true); 1905 } 1906 1907 @Override 1908 public Component getListCellRendererComponent(JList list, Object value, 1909 int index, boolean isSelected, boolean cellHasFocus) { 1910 if (isSelected) { 1911 setBackground(list.getSelectionBackground()); 1912 setForeground(list.getSelectionForeground()); 1913 } else { 1914 setBackground(list.getBackground()); 1915 setForeground(list.getForeground()); 1916 } 1917 1918 ProvenanceStore provenanceStore = (ProvenanceStore) value; 1919 if (provenanceStore != null) { 1920 setText(provenanceStore.getName()); 1921 } 1922 1923 return this; 1924 } 1925 1926 } 1927 1928 1929 /** 1930 * ComboBox for choosing a different provenance store 1931 * for this Workflow Run Manager. 1932 */ 1933 private class ComboBoxAction implements ActionListener { 1934 1935 Object oldItem; 1936 1937 @Override 1938 public void actionPerformed(ActionEvent e) { 1939 1940 final JComboBox cb = (JComboBox) e.getSource(); 1941 Object newItem = cb.getSelectedItem(); 1942 boolean same = newItem.equals(oldItem); 1943 oldItem = newItem; 1944 1945 //no need to update if same store selected again 1946 if (!same) { 1947 Executors.newSingleThreadExecutor().execute(new Runnable() { 1948 @Override 1949 public void run() { 1950 try { 1951 changeProvenanceStore(cb); 1952 } catch (Exception e) { 1953 // TODO Auto-generated catch block 1954 e.printStackTrace(); 1955 } 1956 } 1957 }); 1958 } 1959 } 1960 1961 private void changeProvenanceStore(JComboBox cb){ 1962 1963 WorkflowRunManagerPanel wrmPanel = (WorkflowRunManagerPanel) cb 1964 .getParent().getParent(); 1965 wrmPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 1966 1967 ProvenanceStore selectedProvStore = (ProvenanceStore) cb 1968 .getSelectedItem(); 1969 1970 synchronized (selectedProvStore) { 1971 1972 resetProvenanceInfo(selectedProvStore); 1973 1974 // clear out the old while fetching new runs 1975 // this must be after resetProvenanceInfo, so it occurs on the 1976 // right WRM 1977 clearAllRuns(); 1978 1979 if (selectedProvStore.isRemoteKarStore()) { 1980 refreshButton.setEnabled(true); 1981 } else { 1982 refreshButton.setEnabled(false); 1983 } 1984 1985 // TODO is this really the appropriate place to reset 1986 // tagEventListener? 1987 WindowIdentifier windowIdentifier = new WindowIdentifier("test" 1988 + getWindowId(), kgf); 1989 ProvenanceRecorder pr = workflowRunManager 1990 .getProvenanceRecorder(); 1991 TagBarUI tagBarUI = TaggingContextManager 1992 .getInstance(windowIdentifier).getTagBarInsertionUI() 1993 .getTagBarUI(); 1994 tagBarUI.removeTagEventListener(pr); 1995 1996 // WorkflowRunManagerManager.getInstance().printDebug(); 1997 // set runs 1998 try { 1999 queryForAllRuns(); 2000 } catch (AuthenticationException e) { 2001 // TODO Auto-generated catch block 2002 e.printStackTrace(); 2003 } 2004 filterRuns(); 2005 2006 // TODO is this really the appropriate place to reset 2007 // tagEventListener? 2008 pr = workflowRunManager.getProvenanceRecorder(); 2009 tagBarUI.addTagEventListener(pr); 2010 2011 } 2012 2013 wrmPanel.setCursor(Cursor.getDefaultCursor()); 2014 } 2015 2016 } 2017 2018 private class DeleteRunsSwingWorker extends SwingWorker<Integer, Void> { 2019 2020 private Recording _recording = null; 2021 private List<KeplerLSID> _runsToDelete = null; 2022 private boolean _authenticate = false; 2023 2024 public DeleteRunsSwingWorker(Recording recording, 2025 List<KeplerLSID>runsToDelete, boolean authenticate){ 2026 _recording = recording; 2027 _runsToDelete = runsToDelete; 2028 _authenticate = authenticate; 2029 } 2030 2031 @Override 2032 protected Integer doInBackground() throws Exception { 2033 return workflowRunManager.deleteRuns(_recording, _runsToDelete, 2034 _authenticate); 2035 } 2036 2037 @Override 2038 protected void done() { 2039 //if (isCancelled()){ 2040 } 2041 2042 } 2043 2044 @Override 2045 public void propertyChange(PropertyChangeEvent evt) { 2046 if (evt.getNewValue().equals( 2047 SwingWorker.StateValue.STARTED)) { 2048 setCursor(Cursor 2049 .getPredefinedCursor(Cursor.WAIT_CURSOR)); 2050 }else if (evt.getNewValue().equals( 2051 SwingWorker.StateValue.DONE)){ 2052 setCursor(Cursor.getDefaultCursor()); 2053 } 2054 } 2055 2056} 2057 2058