A PropertySet is a collection of properties of the same kind. Properties can be Task, Resources, Scenario, Shift or Accounts objects. All properties of the same kind belong to the same PropertySet. A property may only belong to one PropertySet in the Project. The PropertySet holds the definitions for the attributes. All Properties of the set will have a set of these attributes.
# File lib/PropertySet.rb, line 30 30: def initialize(project, flatNamespace) 31: if $DEBUG && project.nil? 32: raise "project parameter may not be NIL" 33: end 34: # Indicates whether the namespace of this PropertySet is flat or not. In a 35: # flat namespace all property IDs must be unique. Otherwise only the IDs 36: # within a group of siblings must be unique. The full ID of the Property 37: # is then composed of the siblings ID prefixed by the parent ID. ID fields 38: # are separated by dots. 39: @flatNamespace = flatNamespace 40: # The main Project data structure reference. 41: @project = project 42: # This is the blueprint for PropertyTreeNode attribute sets. Whever a new 43: # PropertTreeNode is created, an attribute is created for each definition 44: # in this list. 45: @attributeDefinitions = Hash.new 46: # A list of all PropertyTreeNodes in this set. 47: @properties = Array.new 48: # A hash of all PropertyTreeNodes in this set, hashed by their ID. This is 49: # the same data as in @properties, but hashed by ID for faster access. 50: @propertyMap = Hash.new 51: 52: # IDs and names of the built-in attributes. TODO: Check performance impact 53: # when making them normal attributes. 54: @@fixedAttributeNames = { 55: 'id' => 'ID', 56: 'name' => 'Name', 57: 'seqno' => 'Seq. No.' 58: } 59: # And their types. 60: @@fixedAttributesTypes = { 61: 'id' => :String, 62: 'name' => :String, 63: 'seqno' => :Fixnum 64: } 65: end
Return the PropertyTreeNode object with ID id from the set or nil if not present.
# File lib/PropertySet.rb, line 247 247: def [](id) 248: @propertyMap[id] 249: end
Use the function to declare the various attributes that properties of this PropertySet can have. The attributes must be declared before the first property is added to the set.
# File lib/PropertySet.rb, line 70 70: def addAttributeType(attributeType) 71: if !@properties.empty? 72: raise "Fatal Error: Attribute types must be defined before " + 73: "properties are added." 74: end 75: 76: @attributeDefinitions[attributeType.id] = attributeType 77: end
Add the new PropertyTreeNode object property to the set. The set is indexed by ID. In case an object with the same ID already exists in the set it will be overwritten.
Whenever the set has been extended, the ‘wbs’ and ‘tree’ attributes of the properties are no longer up-to-date. You must call index() before using these attributes.
# File lib/PropertySet.rb, line 196 196: def addProperty(property) 197: # The PropertySet defines the set of attribute that each PropertyTreeNode 198: # in this set has. Create these attributes with their default values. 199: @attributeDefinitions.each_value do |attributeType| 200: property.declareAttribute(attributeType) 201: end 202: 203: # The PropertyTreeNode objects are indexed by ID or hierachical ID 204: # depending on the name space setting of this set. 205: if @flatNamespace 206: @propertyMap[property.id] = property 207: else 208: @propertyMap[property.fullId] = property 209: end 210: @properties << property 211: end
Returns the name (human readable description) of the attribute with the Id specified by attrId.
# File lib/PropertySet.rb, line 161 161: def attributeName(attrId) 162: # Some attributes are hardwired into the properties. These need to be 163: # treated separately. 164: if @@fixedAttributeNames[attrId].nil? 165: if @attributeDefinitions.include?(attrId) 166: return @attributeDefinitions[attrId].name 167: end 168: else 169: return @@fixedAttributeNames[attrId] 170: end 171: 172: nil 173: end
Return the type of the attribute with the Id specified by attrId.
# File lib/PropertySet.rb, line 176 176: def attributeType(attrId) 177: # Hardwired attributes need special treatment. 178: if @@fixedAttributesTypes[attrId].nil? 179: if @attributeDefinitions.has_key?(attrId) 180: @attributeDefinitions[attrId].objClass 181: else 182: nil 183: end 184: else 185: @@fixedAttributesTypes[attrId] 186: end 187: end
Call this function to delete all registered properties.
# File lib/PropertySet.rb, line 240 240: def clearProperties 241: @properties.clear 242: @propertyMap.clear 243: end
Return the default value of the attribute.
# File lib/PropertySet.rb, line 153 153: def defaultValue(attrId) 154: return nil if @attributeDefinitions[attrId].nil? 155: 156: @attributeDefinitions[attrId].default 157: end
Iterator over all PropertyTreeNode objects in this set.
# File lib/PropertySet.rb, line 313 313: def each 314: @properties.each do |value| 315: yield(value) 316: end 317: end
Iterate over all attribute definitions.
# File lib/PropertySet.rb, line 80 80: def eachAttributeDefinition 81: @attributeDefinitions.each do |key, value| 82: yield(value) 83: end 84: end
Return true if the set is empty.
# File lib/PropertySet.rb, line 298 298: def empty? 299: @properties.empty? 300: end
Check whether the PropertyTreeNode has a calculated attribute with the ID attrId. For scenarioSpecific attributes scenarioIdx needs to be provided.
# File lib/PropertySet.rb, line 95 95: def hasQuery?(attrId, scenarioIdx = nil) 96: return false if @properties.empty? 97: 98: property = @properties.first 99: methodName = 'query_' + attrId 100: # First we check for non-scenario-specific query functions. 101: if property.respond_to?(methodName) 102: return true 103: elsif scenarioIdx 104: # Then we check for scenario-specific ones via the @data member. 105: return property.data[scenarioIdx].respond_to?(methodName) 106: end 107: false 108: end
Update the work-breakdown-structure (wbs) indicies. This method needs to be called whenever the set has been modified.
# File lib/PropertySet.rb, line 253 253: def index 254: each do |p| 255: wbsIdcs = p.getWBSIndicies 256: wbs = "" 257: first = true 258: wbsIdcs.each do |idx| 259: if first 260: first = false 261: else 262: wbs += '.' 263: end 264: wbs += idx.to_s 265: end 266: p.set('wbs', wbs) 267: end 268: end
Return whether the attribute with attrId is inherited from parent.
# File lib/PropertySet.rb, line 138 138: def inheritedFromParent?(attrId) 139: # All hardwired attributes are not inherited. 140: return false if @attributeDefinitions[attrId].nil? 141: 142: @attributeDefinitions[attrId].inheritedFromParent 143: end
Return whether the attribute with attrId is inherited from the global scope.
# File lib/PropertySet.rb, line 130 130: def inheritedFromProject?(attrId) 131: # All hardwired attributes are not inherited. 132: return false if @attributeDefinitions[attrId].nil? 133: 134: @attributeDefinitions[attrId].inheritedFromProject 135: end
Return the number of PropertyTreeNode objects in this set.
# File lib/PropertySet.rb, line 293 293: def items 294: @properties.length 295: end
Return true if there is an AttributeDefinition for attrId.
# File lib/PropertySet.rb, line 87 87: def knownAttribute?(attrId) 88: @@fixedAttributeNames.include?(attrId) || 89: @attributeDefinitions.include?(attrId) 90: end
Return the index of the top-level property in the set.
# File lib/PropertySet.rb, line 271 271: def levelSeqNo(property) 272: seqNo = 1 273: @properties.each do |p| 274: unless p.parent 275: return seqNo if p == property 276: seqNo += 1 277: end 278: end 279: raise "Fatal Error: Unknow property #{property}" 280: end
Return the maximum used number of breakdown levels. A flat list has a maxDepth of 1. A list with one sub level has a maxDepth of 2 and so on.
# File lib/PropertySet.rb, line 284 284: def maxDepth 285: md = 0 286: each do |p| 287: md = p.level if p.level > md 288: end 289: md + 1 290: end
Remove the PropertyTreeNode (and all its children) object from the set. prop can either be a property ID or a reference to the PropertyTreeNode.
TODO: This function does not take care of references to this PTN!
# File lib/PropertySet.rb, line 217 217: def removeProperty(prop) 218: if prop.is_a?(String) 219: property = @propertyMap[prop] 220: else 221: property = prop 222: end 223: 224: # Recursively remove all sub-nodes. The children list is modified during 225: # the call, so we can't use an iterator here. 226: until property.children.empty? do 227: removeProperty(property.children.first) 228: end 229: 230: @properties.delete(property) 231: @propertyMap.delete(property.fullId) 232: 233: # Remove this node from the child list of the parent node. 234: property.parent.children.delete(property) if property.parent 235: 236: property 237: end
Return whether the attribute with attrId is scenario specific or not.
# File lib/PropertySet.rb, line 111 111: def scenarioSpecific?(attrId) 112: if @attributeDefinitions[attrId] 113: # Check the 'scenarioSpecific' flag of the attribute definition. 114: @attributeDefinitions[attrId].scenarioSpecific 115: elsif (property = @properties.first) && 116: property && property.data && 117: property.data[0].respond_to?("query_#{attrId}") 118: # We've found a query_ function for the attrId that is scenario 119: # specific. 120: true 121: else 122: # All hardwired, non-existing and non-scenario-specific query_ 123: # candidates. 124: false 125: end 126: end
Return the set of PropertyTreeNode objects as flat Array.
# File lib/PropertySet.rb, line 320 320: def to_ary 321: @properties.dup 322: end
# File lib/PropertySet.rb, line 324 324: def to_s 325: PropertyList.new(self).to_s 326: end
Return the number of top-level PropertyTreeNode objects. Top-Level items are no children.
# File lib/PropertySet.rb, line 304 304: def topLevelItems 305: items = 0 306: @properties.each do |p| 307: items += 1 unless p.parent 308: end 309: items 310: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.