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:05:00 +0000 (Mon, 22 Jun 2015) $' 
007 * '$Revision: 33499 $'
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.util.Map;
032
033import org.kepler.moml.NamedObjId;
034import org.kepler.objectmanager.lsid.KeplerLSID;
035import org.kepler.provenance.ProvenanceRecorder;
036import org.kepler.provenance.QueryException;
037import org.kepler.provenance.Queryable;
038import org.kepler.provenance.RecordingException;
039
040import ptolemy.kernel.CompositeEntity;
041import ptolemy.kernel.util.NamedObj;
042import ptolemy.vergil.tree.ClassAndEntityTreeModel;
043
044/** A TreeModel for a workflow outline showing actor firing information.
045 *  If includeFires is true, each atomic actor in the tree has a child
046 *  for each execution of that actor.
047 * 
048 *  @author Daniel Crawl
049 *  @version $Id: WorkflowOutlineTreeActorFireModel.java 33499 2015-06-22 21:05:00Z crawl $
050 */
051public class WorkflowOutlineTreeActorFireModel extends ClassAndEntityTreeModel {
052        
053        public WorkflowOutlineTreeActorFireModel(CompositeEntity root) {
054                super(root);
055        }
056
057    /** Get the child of the given parent at the given index.
058     *  If the child does not exist, then return null.
059     *  In this base class, a child is a contained entity.
060     *  @param parent A node in the tree.
061     *  @param index The index of the desired child.
062     *  @return A node, or null if there is no such child.
063     */
064    @Override
065    public Object getChild(Object parent, int index) {
066        
067        if(!includeFires || (parent instanceof CompositeEntity)) {
068            return super.getChild(parent, index);
069        }
070        
071        if (index > getChildCount(parent)) {
072            return null;
073        }
074
075        String name = ((NamedObj)parent).getFullName();
076        try  {
077            Map<String,Long> map = _query.getExecutionTimesForActor(_lsid, null, name);
078            int i = 0;
079            for(Map.Entry<String, Long> entry : map.entrySet()) {
080                if(i == index) {
081                    return entry;
082                }
083                i++;
084            }
085        } catch (QueryException e) {
086            // TODO Auto-generated catch block
087            e.printStackTrace();
088        }
089        return null;
090    }
091
092    /** Return the number of children of the given parent, which in
093     *  this base class is the number of contained entities.
094     *  @param parent A parent node.
095     *  @return The number of contained entities.
096     */
097    @Override
098    public int getChildCount(Object parent) {
099        
100        if(!includeFires || (parent instanceof CompositeEntity)) {
101            return super.getChildCount(parent);
102        }
103    
104        String name = ((NamedObj)parent).getFullName();
105        try {
106            Map<String,Long> map = _query.getExecutionTimesForActor(_lsid, null, name);
107            return map.size();
108        } catch (QueryException e) {
109            // TODO Auto-generated catch block
110            e.printStackTrace();
111        }
112   
113        return 0;
114    }
115
116    /** Return the index of the given child within the given parent.
117     *  If the parent is not contained in the child or is not an instance
118     *  of CompositeEntity return -1.
119     *  @param parent The parent, which is usually a CompositeEntity.
120     *  @param child The child.
121     *  @return The index of the specified child.
122     */
123    @Override
124    public int getIndexOfChild(Object parent, Object child) {
125        
126        if(!includeFires || (parent instanceof CompositeEntity)) {
127            return super.getIndexOfChild(parent, child);
128        }
129        
130        String name = ((NamedObj)parent).getFullName();
131        try {
132            Map<String,Long> map = _query.getExecutionTimesForActor(_lsid, null, name);
133            int index = 0;
134            for(String fireId : map.keySet()) {
135                if(fireId.equals(child)) {
136                    return index;
137                }
138                index++;
139            }
140        } catch (QueryException e) {
141            // TODO Auto-generated catch block
142            e.printStackTrace();
143        }
144
145        return -1;
146    }
147
148    /** Return true if the object is a leaf node.  In this base class,
149     *  an object is a leaf node if it is not an instance of CompositeEntity.
150     *  @param object The object in question.
151     *  @return True if the node has no children.
152     */
153    @Override
154    public boolean isLeaf(Object object) {
155        
156        if(!includeFires || (object instanceof CompositeEntity)) {
157            return super.isLeaf(object);
158        } else if(!(object instanceof NamedObj)) {
159            return true;
160        }
161        
162        String name = ((NamedObj)object).getFullName();
163        try {
164            Map<String,Long> map = _query.getExecutionTimesForActor(_lsid, null, name);
165            if(map.size() > 0) {
166                return false;
167            }
168        } catch (QueryException e) {
169            // TODO Auto-generated catch block
170            e.printStackTrace();
171        }
172        
173        return true;
174    }
175 
176    /** Set the object that this tree model looks at.
177     *  @param root The root NamedObj
178     *  @see #getRoot()
179     */
180    @Override
181    public void setRoot(NamedObj root) {
182
183        if(root != null && root != _root)
184        {
185            try {
186                _query = ProvenanceRecorder.getDefaultQueryable(root);
187                _lsid = NamedObjId.getIdFor(root);
188            } catch (QueryException|RecordingException e) {
189                // TODO Auto-generated catch block
190                e.printStackTrace();
191            }
192        }
193        
194        super.setRoot(root);
195    }
196    
197    public boolean includeFires = false;    
198
199    private Queryable _query;
200    private KeplerLSID _lsid;
201}