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}