001/* 002 * Copyright (c) 2009-2015 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2015-06-22 21:06:18 +0000 (Mon, 22 Jun 2015) $' 007 * '$Revision: 33500 $' 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.Component; 032import java.awt.Font; 033import java.util.Date; 034import java.util.HashMap; 035import java.util.Map; 036 037import javax.swing.JTree; 038import javax.swing.tree.DefaultTreeCellRenderer; 039import javax.swing.tree.TreeModel; 040 041import org.kepler.gui.AnnotatedPTree; 042import org.kepler.gui.OntologyTreeCellRenderer; 043import org.kepler.moml.NamedObjId; 044import org.kepler.objectmanager.lsid.KeplerLSID; 045import org.kepler.provenance.ProvenanceRecorder; 046import org.kepler.provenance.QueryException; 047import org.kepler.provenance.Queryable; 048 049import ptolemy.actor.Actor; 050import ptolemy.kernel.util.NamedObj; 051import ptolemy.util.MessageHandler; 052 053/** A annotated tree and tree cell renderer showing actor execution times. 054 * 055 * @author Daniel Crawl 056 * @version $Id: AnnotatedActorFirePTree.java 33500 2015-06-22 21:06:18Z crawl $ 057 */ 058public class AnnotatedActorFirePTree extends AnnotatedPTree { 059 060 public AnnotatedActorFirePTree(TreeModel model, Component parent, 061 boolean showRootIcon, NamedObj root) { 062 063 super(model, parent, showRootIcon); 064 065 super.initAnotatedPTree(); 066 setCellRenderer(new ActorFireTreeCellRenderer(showRootIcon, root)); 067 Font font = getFont(); 068 setFont(new Font(font.getName(), font.getStyle(), 069 ExecutionMonitorPanel.FONT_SIZE)); 070 } 071} 072 073class ActorFireTreeCellRenderer extends OntologyTreeCellRenderer { 074 075 public ActorFireTreeCellRenderer(NamedObj root) { 076 this(true, root); 077 } 078 079 public ActorFireTreeCellRenderer(boolean useRootIcon, NamedObj root) { 080 super(useRootIcon); 081 _top = root; 082 try { 083 ProvenanceRecorder pr = ProvenanceRecorder.getDefaultProvenanceRecorder(_top); 084 _query = pr.getRecording().getQueryable(true); 085 } catch (Exception e) { 086 System.err.println("Exception getting default queryable: " + e.getMessage()); 087 } 088 089 _wfLSID = NamedObjId.getIdFor(_top); 090 try { 091 Integer lastExecId = _query.getLastExecutionForWorkflow(_wfLSID); 092 Date[] lastExecDates = _query.getTimestampsForExecution(lastExecId); 093 _topFiringMap.put("", lastExecDates[1].getTime() - lastExecDates[0].getTime()); 094 } catch(QueryException e) { 095 MessageHandler.error("Error querying execution times for workflow.", e); 096 } 097 } 098 099 @Override 100 public Component getTreeCellRendererComponent(JTree tree, Object value, 101 boolean selected, boolean expanded, boolean leaf, int row, 102 boolean hasFocus) { 103 104 // System.out.println("in AnnotatedActorFirePtree.getTreeCellRendererComponent"); 105 106 DefaultTreeCellRenderer component = 107 (DefaultTreeCellRenderer)super.getTreeCellRendererComponent(tree, 108 value, selected, expanded, leaf, row, hasFocus); 109 110 if(value instanceof Actor) { 111 Actor actor = (Actor)value; 112 113 if(_query != null) { 114 115 Map<String,Long> map = null; 116 117 try { 118 if(actor == _top) { 119 map = _topFiringMap; 120 } else { 121 map = _query.getExecutionTimesForActor(_wfLSID, 122 null, actor.getFullName()); 123 } 124 } catch (QueryException e) { 125 System.err.println("QueryException: " + e.getMessage()); 126 return component; 127 } 128 129 int firings = map.size(); 130 long totalTime = 0; 131 for(Long time : map.values()) { 132 totalTime += time.longValue(); 133 } 134 135 if(actor == _top) { 136 _topMilliseconds = totalTime; 137 //System.out.println("top ms = " + _topMilliseconds); 138 } 139 140 double relativeTime = 0; 141 if(_topMilliseconds > 0) { 142 relativeTime = totalTime * 100; 143 relativeTime /= _topMilliseconds; 144 } 145 146 String relativeStr = String.format("%5.2f", relativeTime); 147 String str; 148 if(firings == 1) { 149 str = relativeStr + "% - " + 150 totalTime + " ms - " + 151 firings + " execution " + 152 actor.getName(); 153 } else { 154 str = relativeStr + "% - " + 155 totalTime + " ms - " + 156 firings + " executions " + 157 actor.getName(); 158 } 159 component.setText(str); 160 //System.out.println(actor.getFullName() + " " + str); 161 } 162 } 163 else if(value instanceof Map.Entry) { 164 Map.Entry<Integer,Long> entry = (Map.Entry<Integer,Long>)value; 165 component.setText(entry.getValue().toString() + " ms"); 166 } 167 else { 168 System.err.println("WARNING: unknown value type: " + value); 169 } 170 171 return component; 172 } 173 174 private NamedObj _top; 175 private KeplerLSID _wfLSID; 176 private Map<String,Long> _topFiringMap = new HashMap<String,Long>(); 177 private Queryable _query; 178 private long _topMilliseconds; 179}