Class Index [+]

Quicksearch

TaskJuggler::TjpExportRE

This specialization of ReportBase implements an export of the project data in the TJP syntax format.

Public Class Methods

new(report) click to toggle source

Create a new object and set some default values.

    # File lib/reports/TjpExportRE.rb, line 23
23:     def initialize(report)
24:       super(report)
25: 
26:       @supportedTaskAttrs = %( booking complete depends flags maxend
27:                                 maxstart minend minstart note priority
28:                                 responsible )
29:       @supportedResourceAttrs = %( vacation workinghours )
30:       @report.set('scenarios', [ 0 ])
31: 
32:       # Show all tasks, sorted by seqno-up.
33:       @report.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
34:       @report.set('sortTasks', [ [ 'seqno', true, 1 ] ])
35:       # Show all resources, sorted by seqno-up.
36:       @report.set('hideResource',
37:                   LogicalExpression.new(LogicalOperation.new(0)))
38:       @report.set('sortResources', [ [ 'seqno', true, 1 ] ])
39:     end

Public Instance Methods

generateIntermediateFormat() click to toggle source
    # File lib/reports/TjpExportRE.rb, line 41
41:     def generateIntermediateFormat
42:       super
43:     end
to_tjp() click to toggle source

Return the project data in TJP syntax format.

    # File lib/reports/TjpExportRE.rb, line 46
46:     def to_tjp
47:       # Prepare the resource list.
48:       @resourceList = PropertyList.new(@project.resources)
49:       @resourceList.setSorting(a('sortResources'))
50:       @resourceList = filterResourceList(@resourceList, nil, a('hideResource'),
51:                                          a('rollupResource'), a('openNodes'))
52:       @resourceList.sort!
53: 
54:       # Prepare the task list.
55:       @taskList = PropertyList.new(@project.tasks)
56:       @taskList.setSorting(a('sortTasks'))
57:       @taskList = filterTaskList(@taskList, nil, a('hideTask'), a('rollupTask'),
58:                                  a('openNodes'))
59:       @taskList.sort!
60: 
61:       getBookings
62: 
63:       @file = ''
64: 
65:       generateProjectProperty if a('definitions').include?('project')
66: 
67:       generateFlagDeclaration if a('definitions').include?('flags')
68:       generateProjectIDs if a('definitions').include?('projectids')
69:       generateResourceList if a('definitions').include?('resources')
70:       generateTaskList if a('definitions').include?('tasks')
71: 
72:       generateTaskAttributes unless a('taskAttributes').empty?
73:       generateResourceAttributes unless a('resourceAttributes').empty?
74: 
75:       @file
76:     end

Private Instance Methods

generateAttribute(property, attrId, indent, scenarioIdx = nil) click to toggle source
     # File lib/reports/TjpExportRE.rb, line 317
317:     def generateAttribute(property, attrId, indent, scenarioIdx = nil)
318:       val = scenarioIdx.nil? ? property.getAttr(attrId) :
319:                                property[attrId, scenarioIdx]
320:       return if val.nil? || (val.is_a?(Array) && val.empty?)
321: 
322:       generateAttributeText(property.getAttr(attrId, scenarioIdx).to_tjp,
323:                             indent, scenarioIdx)
324:     end
generateAttributeText(text, indent, scenarioIdx) click to toggle source
     # File lib/reports/TjpExportRE.rb, line 326
326:     def generateAttributeText(text, indent, scenarioIdx)
327:       @file << ' ' * indent
328:       tag = ''
329:       if !scenarioIdx.nil? && scenarioIdx != 0
330:         tag = @project.scenario(scenarioIdx).id
331:         @file << "#{tag}:"
332:       end
333:       @file << "#{indentBlock(text, indent + tag.length + 2)}\n"
334:     end
generateBooking(task, indent, scenarioIdx) click to toggle source
     # File lib/reports/TjpExportRE.rb, line 362
362:     def generateBooking(task, indent, scenarioIdx)
363:       return unless @bookings[scenarioIdx].include?(task)
364: 
365:       @bookings[scenarioIdx][task].each_value do |booking|
366:         generateAttributeText('booking ' + booking.to_tjp, indent, scenarioIdx)
367:       end
368:     end
generateCustomAttributeDeclarations(tag, propertySet, attributes) click to toggle source
     # File lib/reports/TjpExportRE.rb, line 91
 91:     def generateCustomAttributeDeclarations(tag, propertySet, attributes)
 92:       # First we search the attribute definitions for any user defined
 93:       # attributes and count them.
 94:       customAttributes = 0
 95:       propertySet.eachAttributeDefinition do |ad|
 96:         customAttributes += 1 if ad.userDefined
 97:       end
 98:       # Return if there are no user defined attributes.
 99:       return if customAttributes == 0
100: 
101:       # Generate definitions for each user defined attribute that is in the
102:       # taskAttributes list.
103:       @file << '  extend ' + tag + "{\n"
104:         propertySet.eachAttributeDefinition do |ad|
105:           next unless ad.userDefined && attributes.include?(ad.id)
106: 
107:           @file << "    #{ad.objClass.tjpId} #{ad.id} \"#{ad.name}\"\n"
108:         end
109:       @file << "  }\n"
110:     end
generateFlagDeclaration() click to toggle source
     # File lib/reports/TjpExportRE.rb, line 112
112:     def generateFlagDeclaration
113:       flags = []
114: 
115:       properties = @resourceList + @taskList
116: 
117:       properties.each do |property|
118:         a('scenarios').each do |scenarioIdx|
119:           property['flags', scenarioIdx].each do |flag|
120:             flags << flag unless flags.include?(flag)
121:           end
122:         end
123:       end
124:       flags.sort
125:       unless flags.empty?
126:         @file << "flags #{flags.join(', ')}\n\n"
127:       end
128:     end
generateProjectIDs() click to toggle source
     # File lib/reports/TjpExportRE.rb, line 130
130:     def generateProjectIDs
131:       # Compile a list of all projectIDs from the tasks in the taskList.
132:       projectIDs = []
133:       a('scenarios').each do |scenarioIdx|
134:         @taskList.each do |task|
135:           pid = task['projectid', scenarioIdx]
136:           projectIDs << pid unless pid.nil? || projectIDs.include?(pid)
137:         end
138:       end
139: 
140:       @file << "projectids #{projectIDs.join(', ')}\n\n" unless projectIDs.empty?
141:     end
generateProjectProperty() click to toggle source
    # File lib/reports/TjpExportRE.rb, line 80
80:     def generateProjectProperty
81:       @file << "project #{@project['projectid']} \"#{@project['name']}\" " +
82:                "\"#{@project['version']}\" #{@project['start']} - " +
83:                "#{@project['end']} {\n"
84:       generateCustomAttributeDeclarations('resource', @project.resources,
85:                                           a('resourceAttributes'))
86:       generateCustomAttributeDeclarations('task', @project.tasks,
87:                                           a('taskAttributes'))
88:       @file << "}\n\n"
89:     end
generateResource(resource, indent) click to toggle source
     # File lib/reports/TjpExportRE.rb, line 154
154:     def generateResource(resource, indent)
155:       Log.activity if resource.sequenceNo % 100 == 0
156: 
157:       @file << ' ' * indent + "resource #{resource.id} \"#{resource.name}\""
158:       @file << ' {' unless resource.children.empty?
159:       @file << "\n"
160: 
161:       # Call this function recursively for all children that are included in the
162:       # resource list as well.
163:       resource.children.each do |subresource|
164:         if @resourceList.include?(subresource)
165:           generateResource(subresource, indent + 2)
166:         end
167:       end
168: 
169:       @file << ' ' * indent + "}\n" unless resource.children.empty?
170:     end
generateResourceAttributes() click to toggle source

Generate a list of resource supplement statements that include the rest of the attributes.

     # File lib/reports/TjpExportRE.rb, line 260
260:     def generateResourceAttributes
261:       @resourceList.each do |resource|
262:         Log.activity if resource.sequenceNo % 100 == 0
263: 
264:         @file << "supplement resource #{resource.fullId} {\n"
265:         @project.resources.eachAttributeDefinition do |attrDef|
266:           id = attrDef.id
267:           next if (!@supportedResourceAttrs.include?(id) &&
268:                    ! attrDef.userDefined) ||
269:                    !a('resourceAttributes').include?(id)
270: 
271:           if attrDef.scenarioSpecific
272:             a('scenarios').each do |scenarioIdx|
273:               generateAttribute(resource, id, 2, scenarioIdx)
274:             end
275:           else
276:             generateAttribute(resource, id, 2)
277:           end
278:         end
279: 
280:         @file << "}\n"
281:       end
282:     end
generateResourceList() click to toggle source
     # File lib/reports/TjpExportRE.rb, line 143
143:     def generateResourceList
144:       # The resource definitions are generated recursively. So we only need to
145:       # start it for the top-level resources.
146:       @resourceList.each do |resource|
147:         if resource.parent.nil?
148:           generateResource(resource, 0)
149:         end
150:       end
151:       @file << "\n"
152:     end
generateTask(task, indent) click to toggle source

Generate a task definition. It only contains a very small set of attributes that have to be passed on the the nested tasks at creation time. All other attributes are declared in subsequent supplement statements.

     # File lib/reports/TjpExportRE.rb, line 186
186:     def generateTask(task, indent)
187:       Log.activity if task.sequenceNo % 100 == 0
188: 
189:       @file << ' ' * indent + "task #{task.id} \"#{task.name}\" {\n"
190: 
191:       if a('taskAttributes').include?('depends')
192:         a('scenarios').each do |scenarioIdx|
193:           generateTaskDependency(scenarioIdx, task, 'depends', indent + 2)
194:           generateTaskDependency(scenarioIdx, task, 'precedes', indent + 2)
195:         end
196:       end
197: 
198:       # Call this function recursively for all children that are included in the
199:       # task list as well.
200:       task.children.each do |subtask|
201:         if @taskList.include?(subtask)
202:           generateTask(subtask, indent + 2)
203:         end
204:       end
205: 
206:       # Determine whether this task has subtasks that are included in the
207:       # report or whether this is a leaf task for the report.
208:       isLeafTask = true
209:       task.children.each do |subtask|
210:         if @taskList.include?(subtask)
211:           isLeafTask = false
212:           break
213:         end
214:       end
215: 
216:       # For leaf tasks we put some attributes right here.
217:       if isLeafTask
218:         a('scenarios').each do |scenarioIdx|
219:           generateAttribute(task, 'start', indent + 2, scenarioIdx)
220:           if task['milestone', scenarioIdx]
221:             generateAttributeText('milestone', indent + 2, scenarioIdx)
222:           else
223:             generateAttribute(task, 'end', indent + 2, scenarioIdx)
224:             generateAttributeText('scheduling ' +
225:                                   (task['forward', scenarioIdx] ?
226:                                    'asap' : 'alap'),
227:                                   indent + 2, scenarioIdx)
228:           end
229:           if task['scheduled', scenarioIdx]
230:             generateAttributeText('scheduled', indent + 2, scenarioIdx)
231:           end
232:         end
233:       end
234: 
235:       @file << ' ' * indent + "}\n"
236:     end
generateTaskAttributes() click to toggle source

Generate a list of task supplement statements that include the rest of the attributes.

     # File lib/reports/TjpExportRE.rb, line 286
286:     def generateTaskAttributes
287:       @taskList.each do |task|
288:         Log.activity if task.sequenceNo % 100 == 0
289: 
290:         @file << "supplement task #{task.fullId} {\n"
291:         @project.tasks.eachAttributeDefinition do |attrDef|
292:           id = attrDef.id
293:           next if (!@supportedTaskAttrs.include?(id) && !attrDef.userDefined) ||
294:                   !a('taskAttributes').include?(id)
295: 
296:           if attrDef.scenarioSpecific
297:             a('scenarios').each do |scenarioIdx|
298:               # Some attributes need special treatment.
299:               case id
300:               when 'depends'
301:                 next     # already taken care of
302:               when 'booking'
303:                 generateBooking(task, 2, scenarioIdx)
304:               else
305:                 generateAttribute(task, id, 2, scenarioIdx)
306:               end
307:             end
308:           else
309:             generateAttribute(task, id, 2)
310:           end
311:         end
312: 
313:         @file << "}\n"
314:       end
315:     end
generateTaskDependency(scenarioIdx, task, tag, indent) click to toggle source

Generate ‘depends’ or ‘precedes’ attributes for a task.

     # File lib/reports/TjpExportRE.rb, line 239
239:     def generateTaskDependency(scenarioIdx, task, tag, indent)
240:       return unless a('taskAttributes').include?('depends')
241: 
242:       taskDeps = task[tag, scenarioIdx]
243:       unless taskDeps.empty?
244:         @file << ' ' * indent + tag + ' '
245:         first = true
246:         taskDeps.each do |dep|
247:           if first
248:             first = false
249:           else
250:             @file << ', '
251:           end
252:           @file << dep.task.fullId
253:         end
254:         @file << "\n"
255:       end
256:     end
generateTaskList() click to toggle source
     # File lib/reports/TjpExportRE.rb, line 172
172:     def generateTaskList
173:       # The task definitions are generated recursively. So we only need to start
174:       # it for the top-level tasks.
175:       @taskList.each do |task|
176:         if task.parent.nil?
177:           generateTask(task, 0)
178:         end
179:       end
180:     end
getBookings() click to toggle source

Get the booking data for all resources that should be included in the report.

     # File lib/reports/TjpExportRE.rb, line 338
338:     def getBookings
339:       @bookings = {}
340:       if a('taskAttributes').include?('booking')
341:         a('scenarios').each do |scenarioIdx|
342:           @bookings[scenarioIdx] = {}
343:           @resourceList.each do |resource|
344:             # Get the bookings for this resource hashed by task.
345:             bookings = resource.getBookings(scenarioIdx,
346:                                             Interval.new(a('start'), a('end')))
347:             next if bookings.nil?
348: 
349:             # Now convert/add them to a tripple-stage hash by scenarioIdx, task
350:             # and then resource.
351:             bookings.each do |task, booking|
352:               if !@bookings[scenarioIdx].include?(task)
353:                 @bookings[scenarioIdx][task] = {}
354:               end
355:               @bookings[scenarioIdx][task][resource] = booking
356:             end
357:           end
358:         end
359:       end
360:     end
indentBlock(text, indent) click to toggle source

This utility function is used to indent multi-line attributes. All attributes should be filtered through this function. Attributes that contain line breaks will be indented properly. In addition to the indentation specified by indent all but the first line will be indented after the first word of the first line. The text may not end with a line break.

     # File lib/reports/TjpExportRE.rb, line 376
376:     def indentBlock(text, indent)
377:       out = ''
378:       firstSpace = 0
379:       text.length.times do |i|
380:         if firstSpace == 0 && text[i] == \ \# There must be a space after ?
381:           firstSpace = i
382:         end
383:         out << text[i]
384:         if text[i] == \n\
385:           out += ' ' * (indent + firstSpace)
386:         end
387:       end
388:       out
389:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.