class TaskJuggler::PropertySet
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.
Attributes
Public Class Methods
# File lib/taskjuggler/PropertySet.rb, line 29 def initialize(project, flatNamespace) if $DEBUG && project.nil? raise "project parameter may not be NIL" end # Indicates whether the namespace of this PropertySet is flat or not. In a # flat namespace all property IDs must be unique. Otherwise only the IDs # within a group of siblings must be unique. The full ID of the Property # is then composed of the siblings ID prefixed by the parent ID. ID fields # are separated by dots. @flatNamespace = flatNamespace # The main Project data structure reference. @project = project # A list of all PropertyTreeNodes in this set. @properties = Array.new # A hash of all PropertyTreeNodes in this set, hashed by their ID. This is # the same data as in @properties, but hashed by ID for faster access. @propertyMap = Hash.new # This is the blueprint for PropertyTreeNode attribute sets. Whever a new # PropertTreeNode is created, an attribute is created for each definition # in this list. @attributeDefinitions = Hash.new [ [ 'id', 'ID', StringAttribute, false, false, false, '' ], [ 'name', 'Name', StringAttribute, false, false, false, '' ], [ 'seqno', 'Seq. No', IntegerAttribute, false, false, false, 0 ] ].each { |a| addAttributeType(AttributeDefinition.new(*a)) } end
Public Instance Methods
Return the PropertyTreeNode
object with ID id from the set or nil if not present.
# File lib/taskjuggler/PropertySet.rb, line 230 def [](id) @propertyMap[id] 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/taskjuggler/PropertySet.rb, line 61 def addAttributeType(attributeType) if !@properties.empty? raise "Fatal Error: Attribute types must be defined before " + "properties are added." end @attributeDefinitions[attributeType.id] = attributeType 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 ‘bsi’ and ‘tree’ attributes of the properties are no longer up-to-date. You must call index() before using these attributes.
# File lib/taskjuggler/PropertySet.rb, line 182 def addProperty(property) # The PropertyTreeNode objects are indexed by ID or hierachical ID # depending on the name space setting of this set. @propertyMap[property.id] = property @properties << property end
Returns the name (human readable description) of the attribute with the Id specified by attrId.
# File lib/taskjuggler/PropertySet.rb, line 155 def attributeName(attrId) # Some attributes are hardwired into the properties. These need to be # treated separately. if @attributeDefinitions.include?(attrId) return @attributeDefinitions[attrId].name end nil end
Return the type of the attribute with the Id specified by attrId.
# File lib/taskjuggler/PropertySet.rb, line 166 def attributeType(attrId) # Hardwired attributes need special treatment. if @attributeDefinitions.has_key?(attrId) @attributeDefinitions[attrId].objClass else nil end end
Call this function to delete all registered properties.
# File lib/taskjuggler/PropertySet.rb, line 223 def clearProperties @properties.clear @propertyMap.clear end
Return the default value of the attribute.
# File lib/taskjuggler/PropertySet.rb, line 147 def defaultValue(attrId) return nil if @attributeDefinitions[attrId].nil? @attributeDefinitions[attrId].default end
Iterator over all PropertyTreeNode
objects in this set.
# File lib/taskjuggler/PropertySet.rb, line 299 def each @properties.each do |value| yield(value) end end
Iterate over all attribute definitions.
# File lib/taskjuggler/PropertySet.rb, line 71 def eachAttributeDefinition @attributeDefinitions.sort.each do |key, value| yield(value) end end
Return true if the set is empty.
# File lib/taskjuggler/PropertySet.rb, line 284 def empty? @properties.empty? end
Check whether the PropertyTreeNode
has a calculated attribute with the ID attrId. For scenarioSpecific attributes scenarioIdx needs to be provided.
# File lib/taskjuggler/PropertySet.rb, line 85 def hasQuery?(attrId, scenarioIdx = nil) return false if @properties.empty? property = @properties.first methodName = 'query_' + attrId # First we check for non-scenario-specific query functions. if property.respond_to?(methodName) return true elsif scenarioIdx # Then we check for scenario-specific ones via the @data member. return property.data[scenarioIdx].respond_to?(methodName) end false end
Update the breakdown structure indicies (bsi). This method needs to be called whenever the set has been modified.
# File lib/taskjuggler/PropertySet.rb, line 236 def index each do |p| bsIdcs = p.getBSIndicies bsi = "" first = true bsIdcs.each do |idx| if first first = false else bsi += '.' end bsi += idx.to_s end p.force('bsi', bsi) end end
Return whether the attribute with attrId is inherited from parent.
# File lib/taskjuggler/PropertySet.rb, line 128 def inheritedFromParent?(attrId) # All hardwired attributes are not inherited. return false if @attributeDefinitions[attrId].nil? @attributeDefinitions[attrId].inheritedFromParent end
Return whether the attribute with attrId is inherited from the global scope.
# File lib/taskjuggler/PropertySet.rb, line 120 def inheritedFromProject?(attrId) # All hardwired attributes are not inherited. return false if @attributeDefinitions[attrId].nil? @attributeDefinitions[attrId].inheritedFromProject end
Return the number of PropertyTreeNode
objects in this set.
# File lib/taskjuggler/PropertySet.rb, line 276 def items @properties.length end
Return true if there is an AttributeDefinition
for attrId.
# File lib/taskjuggler/PropertySet.rb, line 78 def knownAttribute?(attrId) @attributeDefinitions.include?(attrId) end
Return the index of the top-level property in the set.
# File lib/taskjuggler/PropertySet.rb, line 254 def levelSeqNo(property) seqNo = 1 @properties.each do |p| unless p.parent return seqNo if p == property seqNo += 1 end end raise "Fatal Error: Unknow property #{property}" end
# File lib/taskjuggler/PropertySet.rb, line 142 def listAttribute?(attrId) (ad = @attributeDefinitions[attrId]) && ad.objClass.isList? 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/taskjuggler/PropertySet.rb, line 267 def maxDepth md = 0 each do |p| md = p.level if p.level > md end md + 1 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/taskjuggler/PropertySet.rb, line 193 def removeProperty(prop) if prop.is_a?(String) property = @propertyMap[prop] else property = prop end # Iterate over all properties and eliminate references to this the # PropertyTreeNode to be removed. @properties.each do |p| p.removeReferences(p) end # Recursively remove all sub-nodes. The children list is modified during # the call, so we can't use an iterator here. until property.children.empty? do removeProperty(property.children.first) end @properties.delete(property) @propertyMap.delete(property.fullId) # Remove this node from the child list of the parent node. property.parent.children.delete(property) if property.parent property end
Return whether the attribute with attrId is scenario specific or not.
# File lib/taskjuggler/PropertySet.rb, line 101 def scenarioSpecific?(attrId) if @attributeDefinitions[attrId] # Check the 'scenarioSpecific' flag of the attribute definition. @attributeDefinitions[attrId].scenarioSpecific elsif (property = @properties.first) && property && property.data && property.data[0].respond_to?("query_#{attrId}") # We've found a query_ function for the attrId that is scenario # specific. true else # All hardwired, non-existing and non-scenario-specific query_ # candidates. false end end
Return the set of PropertyTreeNode
objects as flat Array.
# File lib/taskjuggler/PropertySet.rb, line 306 def to_ary @properties.dup end
# File lib/taskjuggler/PropertySet.rb, line 310 def to_s PropertyList.new(self).to_s end
Return the number of top-level PropertyTreeNode
objects. Top-Level items are no children.
# File lib/taskjuggler/PropertySet.rb, line 290 def topLevelItems items = 0 @properties.each do |p| items += 1 unless p.parent end items end
Return whether or not the attribute was user defined.
# File lib/taskjuggler/PropertySet.rb, line 136 def userDefined?(attrId) return false if @attributeDefinitions[attrId].nil? @attributeDefinitions[attrId].userDefined end