001/* A tree model for Ptolemy II objects, for use with JTree. 002 003 Copyright (c) 2000-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.vergil.tree; 029 030import java.util.Collections; 031import java.util.List; 032 033import ptolemy.kernel.CompositeEntity; 034import ptolemy.kernel.Entity; 035import ptolemy.kernel.util.NamedObj; 036 037/////////////////////////////////////////////////////////////////// 038//// FullTreeModel 039 040/** 041 A tree model for Ptolemy II models. Nodes in this tree contain 042 the following child elements, in this order: 043 <ul> 044 <li> attributes 045 <li> ports 046 <li> relations 047 <li> class definitions 048 <li> contained entities 049 </ul> 050 The indexes of the attributes are 0 to a-1, where a is the 051 number of attributes. The indexes of the ports are a to a+p-1, 052 where p is the number of ports, and so on. 053 Subclasses may return a subset of the attributes, ports, and 054 relations by overriding the protected methods that list these 055 contained objects. 056 057 @author Steve Neuendorffer and Edward A. Lee 058 @version $Id$ 059 @since Ptolemy II 1.0 060 @Pt.ProposedRating Red (eal) 061 @Pt.AcceptedRating Red (johnr) 062 */ 063public class FullTreeModel extends ClassAndEntityTreeModel { 064 /** Create a new tree model with the specified root. 065 * @param root The root of the tree. 066 */ 067 public FullTreeModel(CompositeEntity root) { 068 super(root); 069 } 070 071 /////////////////////////////////////////////////////////////////// 072 //// public methods //// 073 074 /** Get the child of the given parent at the given index. 075 * If the child does not exist, then return null. 076 * @param parent A node in the tree. 077 * @param index The index of the desired child. 078 * @return A node, or null if there is no such child. 079 */ 080 @Override 081 public Object getChild(Object parent, int index) { 082 List attributes = _attributes(parent); 083 int numAttributes = attributes.size(); 084 085 List ports = _ports(parent); 086 int numPorts = ports.size(); 087 088 List relations = _relations(parent); 089 int numRelations = relations.size(); 090 091 if (index >= numAttributes + numPorts + numRelations) { 092 return super.getChild(parent, 093 index - numAttributes - numPorts - numRelations); 094 } else if (index >= numAttributes + numPorts) { 095 return relations.get(index - numAttributes - numPorts); 096 } else if (index >= numAttributes) { 097 return ports.get(index - numAttributes); 098 } else if (index >= 0) { 099 return attributes.get(index); 100 } else { 101 return null; 102 } 103 } 104 105 /** Return the number of children of the given parent. 106 * This is the number attributes, ports, relations, and contained 107 * entities, filtered by the filter specified by setFilter(), 108 * if any has been specified. 109 * @param parent A parent node. 110 * @return The number of children. 111 */ 112 @Override 113 public int getChildCount(Object parent) { 114 List attributes = _attributes(parent); 115 int numAttributes = attributes.size(); 116 117 List ports = _ports(parent); 118 int numPorts = ports.size(); 119 120 List relations = _relations(parent); 121 int numRelations = relations.size(); 122 123 return numAttributes + numPorts + numRelations 124 + super.getChildCount(parent); 125 } 126 127 /** Return the index of the given child within the given parent. 128 * If the parent is not contained in the child, return -1. 129 * @param parent The parent. 130 * @param child The child. 131 * @return The index of the specified child. 132 */ 133 @Override 134 public int getIndexOfChild(Object parent, Object child) { 135 List attributes = _attributes(parent); 136 137 int index = attributes.indexOf(child); 138 139 if (index >= 0) { 140 return index; 141 } else { 142 // Object is not an attribute. See whether it's a port. 143 List ports = _ports(parent); 144 145 index = ports.indexOf(child); 146 147 int numAttributes = attributes.size(); 148 149 if (index >= 0) { 150 return index + numAttributes; 151 } else { 152 // Not an attribute or port. Try relation. 153 List relations = _relations(parent); 154 155 index = relations.indexOf(child); 156 157 int numPorts = ports.size(); 158 159 if (index >= 0) { 160 return index + numAttributes + numPorts; 161 } else { 162 // Not an attribute, port, or relation. Defer to base 163 // class. 164 index = super.getIndexOfChild(parent, child); 165 166 if (index >= 0) { 167 int numRelations = relations.size(); 168 return index + numAttributes + numPorts + numRelations; 169 } 170 } 171 } 172 } 173 174 return -1; 175 } 176 177 /** Return true if the object is a leaf node. An object is a leaf 178 * node if it has no children that are instances of one of the classes 179 * specified by setFilter(), if a filter has been specified. 180 * @param object The object. 181 * @return True if the node has no children. 182 */ 183 @Override 184 public boolean isLeaf(Object object) { 185 // FIXME: Ignoring setFilter for now. 186 if (_attributes(object).size() > 0) { 187 return false; 188 } 189 190 if (_ports(object).size() > 0) { 191 return false; 192 } 193 194 if (_relations(object).size() > 0) { 195 return false; 196 } 197 198 return super.isLeaf(object); 199 } 200 201 /////////////////////////////////////////////////////////////////// 202 //// protected methods //// 203 204 /** Return the list of attributes, or an empty list if there are none. 205 * Override this method if you wish to show only a subset of the 206 * attributes. 207 * @param object The object. 208 * @return A list of attributes. 209 */ 210 protected List _attributes(Object object) { 211 if (!(object instanceof NamedObj)) { 212 return Collections.EMPTY_LIST; 213 } 214 215 return ((NamedObj) object).attributeList(); 216 } 217 218 /** Return the list of ports, or an empty list if there are none. 219 * Override this method if you wish to show only a subset of the 220 * ports. 221 * @param object The object. 222 * @return A list of ports. 223 */ 224 protected List _ports(Object object) { 225 if (!(object instanceof Entity)) { 226 return Collections.EMPTY_LIST; 227 } 228 229 return ((Entity) object).portList(); 230 } 231 232 /** Return the list of relations, or an empty list if there are none. 233 * Override this method if you wish to show only a subset of the 234 * relations. 235 * @param object The object. 236 * @return A list of relations. 237 */ 238 protected List _relations(Object object) { 239 if (!(object instanceof CompositeEntity)) { 240 return Collections.EMPTY_LIST; 241 } 242 243 return ((CompositeEntity) object).relationList(); 244 } 245}