taskjuggler 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (545) hide show
  1. data/CHANGELOG +160 -0
  2. data/benchmarks/UTF-8-Strings.rb +58 -0
  3. data/data/css/tjreport.css +7 -2
  4. data/doc/AppConfig.html +10 -4
  5. data/doc/Arguments.html +10 -4
  6. data/doc/CHANGELOG.html +171 -5
  7. data/doc/COPYING.html +10 -4
  8. data/doc/Object.html +11 -107
  9. data/doc/README.html +10 -4
  10. data/doc/RuntimeConfig.html +10 -4
  11. data/doc/String.html +16 -11
  12. data/doc/StringIO.html +10 -4
  13. data/doc/TaskJuggler.html +506 -435
  14. data/doc/TaskJuggler/Account.html +10 -4
  15. data/doc/TaskJuggler/AccountAttribute.html +10 -4
  16. data/doc/TaskJuggler/AccountScenario.html +10 -4
  17. data/doc/TaskJuggler/Allocation.html +69 -60
  18. data/doc/TaskJuggler/AllocationAttribute.html +10 -4
  19. data/doc/TaskJuggler/AttributeBase.html +10 -4
  20. data/doc/TaskJuggler/AttributeDefinition.html +10 -4
  21. data/doc/TaskJuggler/BatchProcessor.html +202 -192
  22. data/doc/TaskJuggler/Booking.html +10 -4
  23. data/doc/TaskJuggler/BookingListAttribute.html +10 -4
  24. data/doc/TaskJuggler/BooleanAttribute.html +10 -4
  25. data/doc/TaskJuggler/CSVFile.html +10 -4
  26. data/doc/TaskJuggler/CellSettingPattern.html +10 -4
  27. data/doc/TaskJuggler/CellSettingPatternList.html +10 -4
  28. data/doc/TaskJuggler/Charge.html +10 -4
  29. data/doc/TaskJuggler/ChargeListAttribute.html +10 -4
  30. data/doc/TaskJuggler/ChargeSet.html +10 -4
  31. data/doc/TaskJuggler/ChargeSetListAttribute.html +10 -4
  32. data/doc/TaskJuggler/ColumnListAttribute.html +10 -4
  33. data/doc/TaskJuggler/ColumnTable.html +10 -4
  34. data/doc/TaskJuggler/Daemon.html +71 -52
  35. data/doc/TaskJuggler/DateAttribute.html +10 -4
  36. data/doc/TaskJuggler/DefinitionListAttribute.html +10 -4
  37. data/doc/TaskJuggler/DependencyListAttribute.html +10 -4
  38. data/doc/TaskJuggler/DurationAttribute.html +10 -4
  39. data/doc/TaskJuggler/{MacroParser.html → FileList.html} +58 -173
  40. data/doc/TaskJuggler/{RichTextException.html → FileRecord.html} +59 -80
  41. data/doc/TaskJuggler/FixnumAttribute.html +10 -4
  42. data/doc/TaskJuggler/FlagListAttribute.html +10 -4
  43. data/doc/TaskJuggler/FloatAttribute.html +10 -4
  44. data/doc/TaskJuggler/FormatListAttribute.html +10 -4
  45. data/doc/TaskJuggler/GanttChart.html +10 -4
  46. data/doc/TaskJuggler/GanttContainer.html +14 -8
  47. data/doc/TaskJuggler/GanttHeader.html +10 -4
  48. data/doc/TaskJuggler/GanttHeaderScaleItem.html +10 -4
  49. data/doc/TaskJuggler/GanttLine.html +29 -24
  50. data/doc/TaskJuggler/GanttLoadStack.html +10 -4
  51. data/doc/TaskJuggler/GanttMilestone.html +10 -4
  52. data/doc/TaskJuggler/GanttRouter.html +10 -4
  53. data/doc/TaskJuggler/GanttTaskBar.html +20 -10
  54. data/doc/TaskJuggler/HTMLDocument.html +10 -4
  55. data/doc/TaskJuggler/HTMLGraphics.html +10 -4
  56. data/doc/TaskJuggler/Interval.html +10 -4
  57. data/doc/TaskJuggler/IntervalListAttribute.html +10 -4
  58. data/doc/TaskJuggler/JobInfo.html +10 -4
  59. data/doc/TaskJuggler/Journal.html +227 -160
  60. data/doc/TaskJuggler/JournalEntry.html +10 -4
  61. data/doc/TaskJuggler/JournalEntryList.html +158 -72
  62. data/doc/TaskJuggler/KeywordArray.html +21 -9
  63. data/doc/TaskJuggler/KeywordDocumentation.html +612 -475
  64. data/doc/TaskJuggler/Limits.html +13 -8
  65. data/doc/TaskJuggler/Limits/Limit.html +10 -4
  66. data/doc/TaskJuggler/LimitsAttribute.html +10 -4
  67. data/doc/TaskJuggler/ListAttributeBase.html +10 -4
  68. data/doc/TaskJuggler/Log.html +10 -4
  69. data/doc/TaskJuggler/LogFile.html +10 -4
  70. data/doc/TaskJuggler/LogicalAttribute.html +10 -4
  71. data/doc/TaskJuggler/LogicalExpression.html +11 -5
  72. data/doc/TaskJuggler/LogicalExpressionAttribute.html +10 -4
  73. data/doc/TaskJuggler/LogicalFlag.html +10 -4
  74. data/doc/TaskJuggler/LogicalFunction.html +132 -124
  75. data/doc/TaskJuggler/LogicalOperation.html +10 -4
  76. data/doc/TaskJuggler/Macro.html +16 -10
  77. data/doc/TaskJuggler/MacroTable.html +44 -38
  78. data/doc/TaskJuggler/ManagerResponsibilities.html +10 -4
  79. data/doc/TaskJuggler/ManagerStatusRecord.html +10 -4
  80. data/doc/TaskJuggler/Message.html +92 -68
  81. data/doc/TaskJuggler/MessageHandler.html +349 -28
  82. data/doc/TaskJuggler/Navigator.html +10 -4
  83. data/doc/TaskJuggler/NavigatorElement.html +10 -4
  84. data/doc/TaskJuggler/NikuProject.html +10 -4
  85. data/doc/TaskJuggler/NikuReport.html +10 -4
  86. data/doc/TaskJuggler/NikuResource.html +10 -4
  87. data/doc/TaskJuggler/NodeListAttribute.html +10 -4
  88. data/doc/TaskJuggler/OnShiftCache.html +10 -4
  89. data/doc/TaskJuggler/ProcessIntercom.html +118 -111
  90. data/doc/TaskJuggler/ProcessIntercomIface.html +75 -22
  91. data/doc/TaskJuggler/Project.html +886 -913
  92. data/doc/TaskJuggler/ProjectBroker.html +442 -331
  93. data/doc/TaskJuggler/ProjectBrokerIface.html +95 -38
  94. data/doc/TaskJuggler/ProjectFileParser.html +320 -317
  95. data/doc/TaskJuggler/ProjectFileScanner.html +336 -339
  96. data/doc/TaskJuggler/ProjectRecord.html +119 -56
  97. data/doc/TaskJuggler/ProjectServer.html +282 -237
  98. data/doc/TaskJuggler/ProjectServerIface.html +45 -39
  99. data/doc/TaskJuggler/PropertyAttribute.html +10 -4
  100. data/doc/TaskJuggler/PropertyList.html +177 -173
  101. data/doc/TaskJuggler/PropertySet.html +11 -5
  102. data/doc/TaskJuggler/PropertyTreeNode.html +194 -191
  103. data/doc/TaskJuggler/Query.html +280 -256
  104. data/doc/TaskJuggler/RTFHandlers.html +10 -4
  105. data/doc/TaskJuggler/RTFNavigator.html +33 -26
  106. data/doc/TaskJuggler/RTFQuery.html +135 -169
  107. data/doc/TaskJuggler/RTFReport.html +63 -56
  108. data/doc/TaskJuggler/RTFReportLink.html +58 -47
  109. data/doc/TaskJuggler/RTFWithQuerySupport.html +666 -0
  110. data/doc/TaskJuggler/RealFormat.html +10 -4
  111. data/doc/TaskJuggler/RealFormatAttribute.html +10 -4
  112. data/doc/TaskJuggler/ReferenceAttribute.html +10 -4
  113. data/doc/TaskJuggler/Report.html +333 -290
  114. data/doc/TaskJuggler/ReportBase.html +182 -174
  115. data/doc/TaskJuggler/ReportContext.html +10 -4
  116. data/doc/TaskJuggler/ReportServer.html +144 -126
  117. data/doc/TaskJuggler/ReportServerIface.html +50 -44
  118. data/doc/TaskJuggler/ReportServerRecord.html +38 -32
  119. data/doc/TaskJuggler/ReportServlet.html +144 -137
  120. data/doc/TaskJuggler/ReportTable.html +10 -4
  121. data/doc/TaskJuggler/ReportTableCell.html +169 -164
  122. data/doc/TaskJuggler/ReportTableColumn.html +10 -4
  123. data/doc/TaskJuggler/ReportTableLegend.html +10 -4
  124. data/doc/TaskJuggler/ReportTableLine.html +10 -4
  125. data/doc/TaskJuggler/Resource.html +121 -115
  126. data/doc/TaskJuggler/ResourceListAttribute.html +10 -4
  127. data/doc/TaskJuggler/ResourceListRE.html +10 -4
  128. data/doc/TaskJuggler/ResourceScenario.html +13 -7
  129. data/doc/TaskJuggler/RichText.html +61 -37
  130. data/doc/TaskJuggler/RichTextAttribute.html +10 -4
  131. data/doc/TaskJuggler/RichTextDocument.html +91 -81
  132. data/doc/TaskJuggler/RichTextElement.html +378 -317
  133. data/doc/TaskJuggler/RichTextFunctionExample.html +10 -4
  134. data/doc/TaskJuggler/RichTextFunctionHandler.html +16 -11
  135. data/doc/TaskJuggler/RichTextImage.html +10 -4
  136. data/doc/TaskJuggler/RichTextIntermediate.html +138 -70
  137. data/doc/TaskJuggler/RichTextParser.html +48 -40
  138. data/doc/TaskJuggler/RichTextScanner.html +328 -906
  139. data/doc/TaskJuggler/RichTextSnip.html +59 -57
  140. data/doc/TaskJuggler/RichTextSyntaxRules.html +458 -369
  141. data/doc/TaskJuggler/Scenario.html +10 -4
  142. data/doc/TaskJuggler/ScenarioData.html +33 -30
  143. data/doc/TaskJuggler/ScenarioListAttribute.html +10 -4
  144. data/doc/TaskJuggler/Scoreboard.html +10 -4
  145. data/doc/TaskJuggler/SheetHandlerBase.html +315 -191
  146. data/doc/TaskJuggler/SheetReceiver.html +334 -313
  147. data/doc/TaskJuggler/SheetSender.html +10 -4
  148. data/doc/TaskJuggler/Shift.html +10 -4
  149. data/doc/TaskJuggler/ShiftAssignment.html +10 -4
  150. data/doc/TaskJuggler/ShiftAssignments.html +10 -4
  151. data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +10 -4
  152. data/doc/TaskJuggler/ShiftScenario.html +10 -4
  153. data/doc/TaskJuggler/SimpleQueryExpander.html +697 -0
  154. data/doc/TaskJuggler/SortListAttribute.html +10 -4
  155. data/doc/TaskJuggler/SourceFileInfo.html +10 -4
  156. data/doc/TaskJuggler/StatusSheetReceiver.html +10 -4
  157. data/doc/TaskJuggler/StatusSheetReport.html +10 -4
  158. data/doc/TaskJuggler/StatusSheetSender.html +10 -4
  159. data/doc/TaskJuggler/StringAttribute.html +10 -4
  160. data/doc/TaskJuggler/SymbolAttribute.html +10 -4
  161. data/doc/TaskJuggler/SyntaxReference.html +260 -230
  162. data/doc/TaskJuggler/TOCEntry.html +99 -42
  163. data/doc/TaskJuggler/TSResourceRecord.html +10 -4
  164. data/doc/TaskJuggler/TSTaskRecord.html +10 -4
  165. data/doc/TaskJuggler/TableColumnDefinition.html +10 -4
  166. data/doc/TaskJuggler/TableOfContents.html +54 -12
  167. data/doc/TaskJuggler/TableReport.html +877 -872
  168. data/doc/TaskJuggler/Task.html +117 -68
  169. data/doc/TaskJuggler/TaskDependency.html +10 -4
  170. data/doc/TaskJuggler/TaskListAttribute.html +10 -4
  171. data/doc/TaskJuggler/TaskListRE.html +10 -4
  172. data/doc/TaskJuggler/TaskScenario.html +1681 -1563
  173. data/doc/TaskJuggler/TextFormatter.html +10 -4
  174. data/doc/TaskJuggler/TextParser.html +567 -534
  175. data/doc/TaskJuggler/TextParser/Pattern.html +128 -118
  176. data/doc/TaskJuggler/TextParser/Rule.html +26 -15
  177. data/doc/TaskJuggler/TextParser/StackElement.html +10 -4
  178. data/doc/TaskJuggler/TextParser/TextParserResultArray.html +22 -16
  179. data/doc/TaskJuggler/TextParser/TokenDoc.html +10 -4
  180. data/doc/TaskJuggler/TextReport.html +15 -6
  181. data/doc/TaskJuggler/TextScanner.html +319 -287
  182. data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +16 -10
  183. data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +23 -17
  184. data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +17 -11
  185. data/doc/TaskJuggler/TextScanner/StreamHandle.html +102 -96
  186. data/doc/TaskJuggler/TimeSheet.html +138 -175
  187. data/doc/TaskJuggler/TimeSheetReceiver.html +10 -4
  188. data/doc/TaskJuggler/TimeSheetRecord.html +65 -58
  189. data/doc/TaskJuggler/TimeSheetReport.html +47 -42
  190. data/doc/TaskJuggler/TimeSheetSender.html +10 -4
  191. data/doc/TaskJuggler/TimeSheetSummary.html +91 -83
  192. data/doc/TaskJuggler/TimeSheets.html +22 -16
  193. data/doc/TaskJuggler/Tj3AppBase.html +10 -4
  194. data/doc/TaskJuggler/Tj3Client.html +399 -365
  195. data/doc/TaskJuggler/Tj3Daemon.html +107 -94
  196. data/doc/TaskJuggler/Tj3SheetAppBase.html +10 -4
  197. data/doc/TaskJuggler/Tj3SsReceiver.html +10 -4
  198. data/doc/TaskJuggler/Tj3SsSender.html +10 -4
  199. data/doc/TaskJuggler/Tj3TsReceiver.html +10 -4
  200. data/doc/TaskJuggler/Tj3TsSender.html +10 -4
  201. data/doc/TaskJuggler/Tj3TsSummary.html +10 -4
  202. data/doc/TaskJuggler/TjException.html +10 -4
  203. data/doc/TaskJuggler/TjTime.html +145 -140
  204. data/doc/TaskJuggler/TjpExample.html +10 -4
  205. data/doc/TaskJuggler/TjpExportRE.html +122 -118
  206. data/doc/TaskJuggler/TjpSyntaxRules.html +4065 -4052
  207. data/doc/TaskJuggler/URLParameter.html +10 -4
  208. data/doc/TaskJuggler/UserManual.html +162 -155
  209. data/doc/TaskJuggler/VimSyntax.html +1028 -0
  210. data/doc/TaskJuggler/WebServer.html +45 -27
  211. data/doc/TaskJuggler/WorkingHours.html +10 -4
  212. data/doc/TaskJuggler/WorkingHoursAttribute.html +10 -4
  213. data/doc/TaskJuggler/XMLBlob.html +10 -4
  214. data/doc/TaskJuggler/XMLComment.html +10 -4
  215. data/doc/TaskJuggler/XMLDocument.html +10 -4
  216. data/doc/TaskJuggler/XMLElement.html +10 -4
  217. data/doc/TaskJuggler/XMLNamedText.html +10 -4
  218. data/doc/TaskJuggler/XMLText.html +10 -4
  219. data/doc/index.html +735 -677
  220. data/doc/lib/AccountScenario_rb.html +1 -1
  221. data/doc/lib/Account_rb.html +1 -1
  222. data/doc/lib/Allocation_rb.html +1 -1
  223. data/doc/lib/AppConfig_rb.html +1 -1
  224. data/doc/lib/AttributeBase_rb.html +1 -1
  225. data/doc/lib/AttributeDefinition_rb.html +1 -1
  226. data/doc/lib/Attributes_rb.html +1 -1
  227. data/doc/lib/BatchProcessor_rb.html +1 -1
  228. data/doc/lib/Booking_rb.html +1 -1
  229. data/doc/lib/ChargeSet_rb.html +1 -1
  230. data/doc/lib/Charge_rb.html +1 -1
  231. data/doc/lib/{Message_rb.html → FileList_rb.html} +3 -5
  232. data/doc/lib/HTMLDocument_rb.html +1 -1
  233. data/doc/lib/Interval_rb.html +1 -1
  234. data/doc/lib/Journal_rb.html +1 -1
  235. data/doc/lib/KeywordArray_rb.html +1 -1
  236. data/doc/lib/KeywordDocumentation_rb.html +1 -1
  237. data/doc/lib/Limits_rb.html +1 -1
  238. data/doc/lib/LogFile_rb.html +1 -1
  239. data/doc/lib/Log_rb.html +1 -1
  240. data/doc/lib/LogicalExpression_rb.html +1 -1
  241. data/doc/lib/LogicalFunction_rb.html +1 -1
  242. data/doc/lib/LogicalOperation_rb.html +1 -1
  243. data/doc/lib/MacroTable_rb.html +1 -3
  244. data/doc/lib/MessageHandler_rb.html +1 -1
  245. data/doc/lib/ProjectFileParser_rb.html +1 -1
  246. data/doc/lib/ProjectFileScanner_rb.html +1 -1
  247. data/doc/lib/Project_rb.html +4 -2
  248. data/doc/lib/PropertyList_rb.html +1 -1
  249. data/doc/lib/PropertySet_rb.html +1 -1
  250. data/doc/lib/PropertyTreeNode_rb.html +1 -1
  251. data/doc/lib/Query_rb.html +1 -1
  252. data/doc/lib/RTFHandlers_rb.html +1 -1
  253. data/doc/lib/RTFNavigator_rb.html +1 -1
  254. data/doc/lib/RTFQuery_rb.html +2 -2
  255. data/doc/lib/RTFReportLink_rb.html +4 -2
  256. data/doc/lib/RTFReport_rb.html +1 -1
  257. data/doc/lib/{MacroParser_rb.html → RTFWithQuerySupport_rb.html} +4 -6
  258. data/doc/lib/RealFormat_rb.html +1 -1
  259. data/doc/lib/ResourceScenario_rb.html +1 -1
  260. data/doc/lib/Resource_rb.html +1 -1
  261. data/doc/lib/RichTextDocument_rb.html +1 -1
  262. data/doc/lib/RichTextElement_rb.html +1 -1
  263. data/doc/lib/RichTextFunctionExample_rb.html +1 -1
  264. data/doc/lib/RichTextFunctionHandler_rb.html +1 -1
  265. data/doc/lib/RichTextParser_rb.html +1 -1
  266. data/doc/lib/RichTextScanner_rb.html +3 -1
  267. data/doc/lib/RichTextSnip_rb.html +1 -1
  268. data/doc/lib/RichTextSyntaxRules_rb.html +1 -1
  269. data/doc/lib/RichText_rb.html +3 -1
  270. data/doc/lib/RuntimeConfig_rb.html +1 -1
  271. data/doc/lib/ScenarioData_rb.html +2 -2
  272. data/doc/lib/Scenario_rb.html +1 -1
  273. data/doc/lib/Scoreboard_rb.html +1 -1
  274. data/doc/lib/SheetHandlerBase_rb.html +5 -1
  275. data/doc/lib/SheetReceiver_rb.html +3 -1
  276. data/doc/lib/SheetSender_rb.html +1 -1
  277. data/doc/lib/ShiftAssignments_rb.html +1 -1
  278. data/doc/lib/ShiftScenario_rb.html +1 -1
  279. data/doc/lib/Shift_rb.html +1 -1
  280. data/doc/lib/SimpleQueryExpander_rb.html +67 -0
  281. data/doc/lib/SourceFileInfo_rb.html +1 -1
  282. data/doc/lib/StatusSheetReceiver_rb.html +1 -1
  283. data/doc/lib/StatusSheetSender_rb.html +1 -1
  284. data/doc/lib/SyntaxReference_rb.html +1 -1
  285. data/doc/lib/TOCEntry_rb.html +1 -1
  286. data/doc/lib/TableColumnDefinition_rb.html +1 -1
  287. data/doc/lib/TableOfContents_rb.html +1 -1
  288. data/doc/lib/TaskDependency_rb.html +1 -1
  289. data/doc/lib/TaskJuggler_rb.html +1 -1
  290. data/doc/lib/TaskScenario_rb.html +1 -1
  291. data/doc/lib/Task_rb.html +1 -1
  292. data/doc/lib/TextFormatter_rb.html +1 -1
  293. data/doc/lib/TextParser/Pattern_rb.html +1 -1
  294. data/doc/lib/TextParser/Rule_rb.html +1 -1
  295. data/doc/lib/TextParser/StackElement_rb.html +1 -1
  296. data/doc/lib/TextParser/TokenDoc_rb.html +1 -1
  297. data/doc/lib/TextParser_rb.html +3 -1
  298. data/doc/lib/TextScanner_rb.html +1 -3
  299. data/doc/lib/TimeSheetReceiver_rb.html +1 -1
  300. data/doc/lib/TimeSheetSender_rb.html +1 -1
  301. data/doc/lib/TimeSheetSummary_rb.html +1 -1
  302. data/doc/lib/TimeSheets_rb.html +1 -1
  303. data/doc/lib/Tj3AppBase_rb.html +1 -1
  304. data/doc/lib/Tj3Config_rb.html +1 -1
  305. data/doc/lib/Tj3SheetAppBase_rb.html +1 -1
  306. data/doc/lib/TjException_rb.html +1 -1
  307. data/doc/lib/TjTime_rb.html +1 -1
  308. data/doc/lib/TjpExample_rb.html +1 -1
  309. data/doc/lib/TjpSyntaxRules_rb.html +1 -1
  310. data/doc/lib/URLParameter_rb.html +1 -1
  311. data/doc/lib/UTF8String_rb.html +1 -1
  312. data/doc/lib/UserManual_rb.html +1 -1
  313. data/doc/lib/{ruby-signal-bug_rb.html → VimSyntax_rb.html} +17 -4
  314. data/doc/lib/WorkingHours_rb.html +1 -1
  315. data/doc/lib/XMLDocument_rb.html +1 -1
  316. data/doc/lib/XMLElement_rb.html +1 -1
  317. data/doc/lib/daemon/Daemon_rb.html +1 -1
  318. data/doc/lib/daemon/ProcessIntercom_rb.html +1 -1
  319. data/doc/lib/daemon/ProjectBroker_rb.html +1 -1
  320. data/doc/lib/daemon/ProjectServer_rb.html +1 -1
  321. data/doc/lib/daemon/ReportServer_rb.html +1 -3
  322. data/doc/lib/daemon/WebServer_rb.html +1 -1
  323. data/doc/lib/deep_copy_rb.html +1 -1
  324. data/doc/lib/reports/CSVFile_rb.html +1 -1
  325. data/doc/lib/reports/ColumnTable_rb.html +1 -1
  326. data/doc/lib/reports/GanttChart_rb.html +1 -1
  327. data/doc/lib/reports/GanttContainer_rb.html +1 -1
  328. data/doc/lib/reports/GanttHeaderScaleItem_rb.html +1 -1
  329. data/doc/lib/reports/GanttHeader_rb.html +1 -1
  330. data/doc/lib/reports/GanttLine_rb.html +1 -1
  331. data/doc/lib/reports/GanttLoadStack_rb.html +1 -1
  332. data/doc/lib/reports/GanttMilestone_rb.html +1 -1
  333. data/doc/lib/reports/GanttRouter_rb.html +1 -1
  334. data/doc/lib/reports/GanttTaskBar_rb.html +1 -1
  335. data/doc/lib/reports/HTMLGraphics_rb.html +1 -1
  336. data/doc/lib/reports/Navigator_rb.html +1 -1
  337. data/doc/lib/reports/NikuReport_rb.html +1 -1
  338. data/doc/lib/reports/ReportBase_rb.html +1 -1
  339. data/doc/lib/reports/ReportContext_rb.html +1 -1
  340. data/doc/lib/reports/ReportTableCell_rb.html +1 -1
  341. data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
  342. data/doc/lib/reports/ReportTableLegend_rb.html +1 -1
  343. data/doc/lib/reports/ReportTableLine_rb.html +1 -1
  344. data/doc/lib/reports/ReportTable_rb.html +1 -1
  345. data/doc/lib/reports/Report_rb.html +1 -1
  346. data/doc/lib/reports/ResourceListRE_rb.html +1 -1
  347. data/doc/lib/reports/StatusSheetReport_rb.html +1 -1
  348. data/doc/lib/reports/TableReport_rb.html +1 -1
  349. data/doc/lib/reports/TaskListRE_rb.html +1 -1
  350. data/doc/lib/reports/TextReport_rb.html +1 -1
  351. data/doc/lib/reports/TimeSheetReport_rb.html +1 -1
  352. data/doc/lib/reports/TjpExportRE_rb.html +1 -1
  353. data/doc/lib/taskjuggler3_rb.html +1 -1
  354. data/doc/lib/tj3client_rb.html +1 -1
  355. data/doc/lib/tj3d_rb.html +1 -1
  356. data/doc/lib/tj3man_rb.html +1 -1
  357. data/doc/lib/tj3ss_receiver_rb.html +1 -1
  358. data/doc/lib/tj3ss_sender_rb.html +1 -1
  359. data/doc/lib/tj3ts_receiver_rb.html +1 -1
  360. data/doc/lib/tj3ts_sender_rb.html +1 -1
  361. data/doc/lib/tj3ts_summary_rb.html +1 -1
  362. data/lib/Allocation.rb +8 -5
  363. data/lib/BatchProcessor.rb +7 -3
  364. data/lib/FileList.rb +58 -0
  365. data/lib/Journal.rb +73 -33
  366. data/lib/KeywordArray.rb +4 -0
  367. data/lib/KeywordDocumentation.rb +45 -11
  368. data/lib/Limits.rb +0 -1
  369. data/lib/LogicalExpression.rb +1 -1
  370. data/lib/LogicalFunction.rb +14 -12
  371. data/lib/MacroTable.rb +3 -4
  372. data/lib/MessageHandler.rb +136 -7
  373. data/lib/Project.rb +72 -86
  374. data/lib/ProjectFileParser.rb +30 -33
  375. data/lib/ProjectFileScanner.rb +7 -16
  376. data/lib/PropertyList.rb +25 -27
  377. data/lib/PropertySet.rb +1 -1
  378. data/lib/PropertyTreeNode.rb +9 -12
  379. data/lib/Query.rb +5 -4
  380. data/lib/RTFNavigator.rb +2 -1
  381. data/lib/RTFQuery.rb +4 -11
  382. data/lib/RTFReport.rb +2 -1
  383. data/lib/RTFReportLink.rb +10 -4
  384. data/lib/RTFWithQuerySupport.rb +45 -0
  385. data/lib/Resource.rb +20 -20
  386. data/lib/ResourceScenario.rb +3 -3
  387. data/lib/RichText.rb +15 -7
  388. data/lib/RichTextDocument.rb +8 -4
  389. data/lib/RichTextElement.rb +35 -12
  390. data/lib/RichTextFunctionHandler.rb +11 -12
  391. data/lib/RichTextParser.rb +5 -3
  392. data/lib/RichTextScanner.rb +144 -565
  393. data/lib/RichTextSnip.rb +3 -7
  394. data/lib/RichTextSyntaxRules.rb +51 -32
  395. data/lib/ScenarioData.rb +16 -25
  396. data/lib/SheetHandlerBase.rb +59 -2
  397. data/lib/SheetReceiver.rb +36 -18
  398. data/lib/SimpleQueryExpander.rb +58 -0
  399. data/lib/SyntaxReference.rb +9 -5
  400. data/lib/TOCEntry.rb +2 -0
  401. data/lib/TableOfContents.rb +4 -0
  402. data/lib/Task.rb +23 -12
  403. data/lib/TaskJuggler.rb +72 -33
  404. data/lib/TaskScenario.rb +131 -53
  405. data/lib/TextParser.rb +43 -30
  406. data/lib/TextParser/Pattern.rb +17 -13
  407. data/lib/TextParser/Rule.rb +5 -0
  408. data/lib/TextScanner.rb +46 -25
  409. data/lib/TimeSheetSummary.rb +9 -7
  410. data/lib/TimeSheets.rb +14 -23
  411. data/lib/Tj3Config.rb +1 -1
  412. data/lib/TjTime.rb +1 -2
  413. data/lib/TjpSyntaxRules.rb +128 -104
  414. data/lib/UTF8String.rb +0 -1
  415. data/lib/UserManual.rb +5 -4
  416. data/lib/VimSyntax.rb +223 -0
  417. data/lib/daemon/Daemon.rb +9 -0
  418. data/lib/daemon/ProcessIntercom.rb +19 -4
  419. data/lib/daemon/ProjectBroker.rb +149 -68
  420. data/lib/daemon/ProjectServer.rb +119 -79
  421. data/lib/daemon/ReportServer.rb +42 -31
  422. data/lib/daemon/WebServer.rb +21 -2
  423. data/lib/deep_copy.rb +1 -1
  424. data/lib/reports/GanttContainer.rb +2 -2
  425. data/lib/reports/GanttLine.rb +2 -3
  426. data/lib/reports/GanttTaskBar.rb +7 -3
  427. data/lib/reports/Report.rb +62 -57
  428. data/lib/reports/ReportBase.rb +6 -4
  429. data/lib/reports/ReportTableCell.rb +13 -14
  430. data/lib/reports/TableReport.rb +2 -1
  431. data/lib/reports/TextReport.rb +3 -0
  432. data/lib/reports/TimeSheetReport.rb +2 -3
  433. data/lib/reports/TjpExportRE.rb +0 -2
  434. data/lib/tj3client.rb +31 -3
  435. data/lib/tj3d.rb +8 -1
  436. data/manual/Day_To_Day_Juggling +2 -95
  437. data/manual/How_To_Contribute +2 -1
  438. data/manual/Rich_Text_Attributes +37 -3
  439. data/manual/Software +203 -0
  440. data/test/MessageChecker.rb +4 -4
  441. data/test/TestSuite/HTML-Reports/Alerts.html +172 -0
  442. data/test/TestSuite/HTML-Reports/CellText.html +758 -0
  443. data/test/TestSuite/HTML-Reports/ColumnPeriods.html +156 -0
  444. data/test/TestSuite/HTML-Reports/IsOngoing.html +172 -0
  445. data/test/TestSuite/HTML-Reports/LogicalFunctions.html +245 -0
  446. data/test/TestSuite/HTML-Reports/Query.html +31 -0
  447. data/test/TestSuite/HTML-Reports/css/tjmanual.css +14 -0
  448. data/test/TestSuite/HTML-Reports/css/tjreport.css +233 -21
  449. data/test/TestSuite/HTML-Reports/depArrows.html +842 -0
  450. data/test/TestSuite/HTML-Reports/scripts/scripts/wz_tooltip.js +1301 -0
  451. data/test/TestSuite/HTML-Reports/scripts/wz_tooltip.js +20 -20
  452. data/test/TestSuite/ReportGenerator/Correct/Alerts.tjp +48 -0
  453. data/test/TestSuite/ReportGenerator/Correct/Macros.tjp +57 -0
  454. data/test/TestSuite/ReportGenerator/Correct/refs/Alerts-1.csv +386 -0
  455. data/test/TestSuite/ReportGenerator/Correct/refs/Macros-1.csv +6 -0
  456. data/test/TestSuite/ReportGenerator/{Correct → Errors}/css/tjmanual.css +0 -0
  457. data/test/TestSuite/ReportGenerator/{Correct → Errors}/css/tjreport.css +0 -0
  458. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/details.png +0 -0
  459. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-green.png +0 -0
  460. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-red.png +0 -0
  461. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-yellow.png +0 -0
  462. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/resource.png +0 -0
  463. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/resourcegroup.png +0 -0
  464. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/task.png +0 -0
  465. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/taskgroup.png +0 -0
  466. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-down.png +0 -0
  467. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-flat.png +0 -0
  468. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-up.png +0 -0
  469. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.html +26 -0
  470. data/test/TestSuite/ReportGenerator/{Correct → Errors}/scripts/wz_tooltip.js +0 -0
  471. data/test/TestSuite/Scheduler/Correct/Allocate.html +3210 -0
  472. data/test/TestSuite/Scheduler/Correct/Allocate.tjp +19 -0
  473. data/test/TestSuite/Scheduler/Correct/Container.html +22 -22
  474. data/test/TestSuite/Scheduler/Correct/Limits.html +4964 -0
  475. data/test/TestSuite/Scheduler/Correct/Shift.html +1707 -417
  476. data/test/TestSuite/Scheduler/Correct/Shift2.html +9 -9
  477. data/test/TestSuite/Scheduler/Correct/css/tjreport.css +6 -2
  478. data/test/TestSuite/Scheduler/Errors/css/tjmanual.css +66 -0
  479. data/test/TestSuite/Scheduler/Errors/css/tjreport.css +407 -0
  480. data/test/TestSuite/Scheduler/Errors/icons/details.png +0 -0
  481. data/test/TestSuite/Scheduler/Errors/icons/flag-green.png +0 -0
  482. data/test/TestSuite/Scheduler/Errors/icons/flag-red.png +0 -0
  483. data/test/TestSuite/Scheduler/Errors/icons/flag-yellow.png +0 -0
  484. data/test/TestSuite/Scheduler/Errors/icons/resource.png +0 -0
  485. data/test/TestSuite/Scheduler/Errors/icons/resourcegroup.png +0 -0
  486. data/test/TestSuite/Scheduler/Errors/icons/task.png +0 -0
  487. data/test/TestSuite/Scheduler/Errors/icons/taskgroup.png +0 -0
  488. data/test/TestSuite/Scheduler/Errors/icons/trend-down.png +0 -0
  489. data/test/TestSuite/Scheduler/Errors/icons/trend-flat.png +0 -0
  490. data/test/TestSuite/Scheduler/Errors/icons/trend-up.png +0 -0
  491. data/test/TestSuite/Scheduler/Errors/loop_detected_1.tjp +1 -1
  492. data/test/TestSuite/Scheduler/Errors/loop_detected_10.tjp +1 -1
  493. data/test/TestSuite/Scheduler/Errors/loop_detected_11.tjp +1 -1
  494. data/test/TestSuite/Scheduler/Errors/loop_detected_12.tjp +1 -1
  495. data/test/TestSuite/Scheduler/Errors/loop_detected_13.tjp +1 -1
  496. data/test/TestSuite/Scheduler/Errors/loop_detected_14.tjp +1 -1
  497. data/test/TestSuite/Scheduler/Errors/loop_detected_2.tjp +1 -1
  498. data/test/TestSuite/Scheduler/Errors/loop_detected_3.tjp +1 -1
  499. data/test/TestSuite/Scheduler/Errors/loop_detected_4.tjp +1 -1
  500. data/test/TestSuite/Scheduler/Errors/loop_detected_5.tjp +1 -1
  501. data/test/TestSuite/Scheduler/Errors/loop_detected_6.tjp +1 -1
  502. data/test/TestSuite/Scheduler/Errors/loop_detected_7.tjp +1 -1
  503. data/test/TestSuite/Scheduler/Errors/loop_detected_8.tjp +1 -1
  504. data/test/TestSuite/Scheduler/Errors/loop_detected_9.tjp +1 -1
  505. data/test/TestSuite/Scheduler/Errors/scripts/wz_tooltip.js +1301 -0
  506. data/test/TestSuite/Scheduler/Errors/task_pred_before.tjp +11 -0
  507. data/test/TestSuite/Scheduler/Errors/task_pred_before_gd.tjp +11 -0
  508. data/test/TestSuite/Scheduler/Errors/task_pred_before_gl.tjp +11 -0
  509. data/test/TestSuite/Scheduler/Errors/task_succ_after.tjp +12 -0
  510. data/test/TestSuite/Scheduler/Errors/task_succ_after_gd.tjp +12 -0
  511. data/test/TestSuite/Scheduler/Errors/task_succ_after_gl.tjp +12 -0
  512. data/test/TestSuite/StatusSheets/dev2.tji +22 -0
  513. data/test/TestSuite/StatusSheets/resrep.tji +7 -0
  514. data/test/TestSuite/StatusSheets/run +6 -4
  515. data/test/TestSuite/StatusSheets/tj3d.log +312 -0
  516. data/test/TestSuite/Syntax/Correct/Managers.html +263 -0
  517. data/test/TestSuite/Syntax/Correct/tutorial.tjp +1 -2
  518. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
  519. data/test/TestSuite/Syntax/Errors/macro_stack_overflow.tjp +1 -1
  520. data/test/TestSuite/TimeSheets/acceptable_intervals +1 -0
  521. data/test/TestSuite/TimeSheets/resrep.tji +7 -0
  522. data/test/TestSuite/TimeSheets/run +6 -5
  523. data/test/TestSuite/TimeSheets/statussheets.log +1 -0
  524. data/test/TestSuite/TimeSheets/ts.tji +351 -0
  525. data/test/TestSuite/TimeSheets/tsdef.tji +2 -0
  526. data/test/test_PropertySet.rb +2 -2
  527. data/test/test_RichText.rb +178 -387
  528. data/test/test_SimpleQueryExpander.rb +55 -0
  529. data/test/test_deep_copy.rb +2 -2
  530. metadata +854 -834
  531. data/lib/MacroParser.rb +0 -77
  532. data/lib/Message.rb +0 -56
  533. data/lib/ruby-signal-bug.rb +0 -43
  534. data/test/TestSuite/HTML-Reports/TimeSheet.html +0 -79
  535. data/test/TestSuite/HTML-Reports/reference.html +0 -51
  536. data/test/TestSuite/ReportGenerator/Correct/Journal.html +0 -63
  537. data/test/TestSuite/ReportGenerator/Correct/LogicalFunctions2.csv +0 -3
  538. data/test/TestSuite/ReportGenerator/Correct/opennodes.csv +0 -2
  539. data/test/TestSuite/ReportGenerator/Correct/opennodes.tjp +0 -26
  540. data/test/TestSuite/ReportGenerator/Correct/refs/opennodes-1.csv +0 -2
  541. data/test/TestSuite/Scheduler/Correct/Booking2.html +0 -603
  542. data/test/TestSuite/Scheduler/Correct/TimeSheet2.html +0 -108
  543. data/test/TestSuite/StatusSheetTemplates/project.tji +0 -35
  544. data/test/TestSuite/StatusSheetTemplates/project.tjp +0 -56
  545. data/test/TestSuite/Syntax/Correct/ResourcePrefix.html +0 -32
@@ -37,7 +37,7 @@ class TaskJuggler
37
37
 
38
38
  attr_reader :authKey, :uri
39
39
 
40
- def initialize(projectData = nil)
40
+ def initialize(projectData = nil, logConsole = false)
41
41
  @projectData = projectData
42
42
  # Since we are still in the ProjectBroker process, the current DRb
43
43
  # server is still the ProjectBroker DRb server.
@@ -46,6 +46,7 @@ class TaskJuggler
46
46
  @daemon = nil
47
47
  initIntercom
48
48
 
49
+ @logConsole = logConsole
49
50
  @pid = nil
50
51
  @uri = nil
51
52
 
@@ -79,34 +80,45 @@ class TaskJuggler
79
80
  @log.fatal('ProjectServer fork failed')
80
81
  elsif @pid.nil?
81
82
  # This is the child
82
- $SAFE = 1
83
- DRb.install_acl(ACL.new(%w[ deny all
84
- allow 127.0.0.1 ]))
85
- DRb.start_service
86
- iFace = ProjectServerIface.new(self)
83
+ if @logConsole
84
+ # If the Broker wasn't daemonized, log stdout and stderr to PID
85
+ # specific files.
86
+ $stderr.reopen("tj3d.ps.#{$$}.stderr", 'w')
87
+ $stdout.reopen("tj3d.ps.#{$$}.stdout", 'w')
88
+ end
87
89
  begin
88
- @uri = DRb.start_service('druby://127.0.0.1:0', iFace).uri
89
- @log.debug("Project server is listening on #{@uri}")
90
+ $SAFE = 1
91
+ DRb.install_acl(ACL.new(%w[ deny all allow 127.0.0.1 ]))
92
+ DRb.start_service
93
+ iFace = ProjectServerIface.new(self)
94
+ begin
95
+ @uri = DRb.start_service('druby://127.0.0.1:0', iFace).uri
96
+ @log.debug("Project server is listening on #{@uri}")
97
+ rescue
98
+ @log.fatal("ProjectServer can't start DRb: #{$!}")
99
+ end
100
+
101
+ # Send the URI of the newly started DRb server to the parent process.
102
+ rd.close
103
+ wr.write @uri
104
+ wr.close
105
+
106
+ # Start a Thread that waits for the @terminate flag to be set and does
107
+ # other background tasks.
108
+ startTerminator
109
+ # Start another Thread that will be used to fork-off ReportServer
110
+ # processes.
111
+ startHousekeeping
112
+
113
+ # Cleanup the DRb threads
114
+ DRb.thread.join
115
+ @log.debug('Project server terminated')
116
+ exit 0
90
117
  rescue
118
+ $stderr.print $!.to_s
119
+ $stderr.print $!.backtrace.join("\n")
91
120
  @log.fatal("ProjectServer can't start DRb: #{$!}")
92
121
  end
93
-
94
- # Send the URI of the newly started DRb server to the parent process.
95
- rd.close
96
- wr.write @uri
97
- wr.close
98
-
99
- # Start a Thread that waits for the @terminate flag to be set and does
100
- # other background tasks.
101
- startTerminator
102
- # Start another Thread that will be used to fork-off ReportServer
103
- # processes.
104
- startHousekeeping
105
-
106
- # Cleanup the DRb threads
107
- DRb.thread.join
108
- @log.debug('Project server terminated')
109
- exit 0
110
122
  else
111
123
  # This is the parent
112
124
  Process.detach(@pid)
@@ -122,16 +134,20 @@ class TaskJuggler
122
134
  # directory. The second one is the master project file (.tjp file).
123
135
  # Additionally a list of optional .tji files can be provided.
124
136
  def loadProject(args)
137
+ dirAndFiles = args.dup.untaint
125
138
  # The first argument is the working directory
126
139
  Dir.chdir(args.shift.untaint)
127
140
 
128
- updateState(:loading, File.basename(args[0]))
141
+ # Save a time stamp of when the project file loading started.
142
+ @modifiedCheck = TjTime.now
143
+
144
+ updateState(:loading, dirAndFiles, false)
129
145
  @tj = TaskJuggler.new(true)
130
146
 
131
147
  # Parse all project files
132
148
  unless @tj.parse(args, true)
133
149
  @log.error("Parsing of #{args.join(' ')} failed")
134
- updateState(:failed, File.basename(args[0]))
150
+ updateState(:failed, nil, false)
135
151
  @terminate = true
136
152
  return false
137
153
  end
@@ -139,14 +155,14 @@ class TaskJuggler
139
155
  # Then schedule the project
140
156
  unless @tj.schedule
141
157
  @log.error("Scheduling of project #{@tj.projectId} failed")
142
- updateState(:failed, @tj.projectId)
158
+ updateState(:failed, @tj.projectId, false)
143
159
  Log.exit('scheduler')
144
160
  @terminate = true
145
161
  return false
146
162
  end
147
163
 
148
164
  # Great, everything went fine. We've got a project to work with.
149
- updateState(:ready, @tj.projectId)
165
+ updateState(:ready, @tj.projectId, false)
150
166
  @log.info("Project #{@tj.projectId} loaded")
151
167
  restartTimer
152
168
  true
@@ -164,7 +180,7 @@ class TaskJuggler
164
180
  return [] unless @tj && (project = @tj.project)
165
181
  list = []
166
182
  project.reports.each do |report|
167
- if report.get('formats').include?(:html)
183
+ unless report.get('formats').empty?
168
184
  list << [ report.fullId, report.name ]
169
185
  end
170
186
  end
@@ -198,7 +214,8 @@ class TaskJuggler
198
214
  sleep 0.1 if reportServer.nil?
199
215
  end
200
216
 
201
- @log.debug("Got report server with URI #{reportServer.uri} for tag #{tag}")
217
+ @log.debug("Got report server with URI #{reportServer.uri} for " +
218
+ "tag #{tag}")
202
219
  restartTimer
203
220
  [ reportServer.uri, reportServer.authKey ]
204
221
  end
@@ -225,67 +242,90 @@ class TaskJuggler
225
242
 
226
243
  private
227
244
 
228
- # Update the _state_ and _id_ of the project locally and remotely.
229
- def updateState(state, id)
245
+ # Update the _state_, _id_ and _modified_ state of the project locally and
246
+ # remotely.
247
+ def updateState(state, filesOrId, modified)
230
248
  begin
231
249
  @daemon = DRbObject.new(nil, @daemonURI) unless @daemon
232
- @daemon.updateState(@authKey, id, state)
250
+ @daemon.updateState(@authKey, filesOrId, state, modified)
233
251
  rescue
234
252
  @log.fatal("Can't update state with daemon: #{$!}")
235
253
  end
236
254
  @stateLock.synchronize do
237
255
  @state = state
238
256
  @stateUpdated = TjTime.now
257
+ @modified = modified
258
+ @modifiedCheck = TjTime.now
239
259
  end
240
260
  end
241
261
 
242
262
  def startHousekeeping
243
263
  Thread.new do
244
- loop do
245
- # Was the project data provided during object creation?
246
- # Then we load the data here.
247
- if @projectData
248
- loadProject(@projectData)
249
- @projectData = nil
250
- end
264
+ begin
265
+ loop do
266
+ # Was the project data provided during object creation?
267
+ # Then we load the data here.
268
+ if @projectData
269
+ loadProject(@projectData)
270
+ @projectData = nil
271
+ end
251
272
 
252
- # Check for pending requests for new ReportServers.
253
- unless @reportServerRequests.empty?
254
- tag = @reportServerRequests.pop
255
- @log.debug("Popped #{tag}")
256
- # Create an new entry for the @reportServers list.
257
- rsr = ReportServerRecord.new(tag)
258
- @log.debug("RSR created")
259
- # Create a new ReportServer object that runs as a separate
260
- # process. The constructor will tell us the URI and authentication
261
- # key of the new ReportServer.
262
- rs = ReportServer.new(@tj)
263
- rsr.uri = rs.uri
264
- rsr.authKey = rs.authKey
265
- @log.debug("Adding ReportServer with URI #{rsr.uri} to list")
266
- # Add the new ReportServer to our list.
267
- @reportServers.synchronize do
268
- @reportServers << rsr
273
+ # Check every 60 seconds if the input files have been modified.
274
+ # Don't check if we already know it has been modified.
275
+ if @stateLock.synchronize { @state == :ready && !@modified &&
276
+ @modifiedCheck + 60 < TjTime.now }
277
+ # Reset the timer
278
+ @stateLock.synchronize { @modifiedCheck = TjTime.now }
279
+
280
+ if @tj.project.inputFiles.modified?
281
+ @log.info("Project #{@tj.projectId} has been modified")
282
+ updateState(:ready, @tj.projectId, true)
283
+ end
269
284
  end
270
- end
271
285
 
272
- # Some state changing operations are not atomic. Since the client
273
- # can die during the transaction, the server might hang in some
274
- # states. Here we define timeout for each state. If the timeout is
275
- # not 0 and exceeded, we immediately terminate the process.
276
- timeouts = { :new => 10, :loading => 15 * 60, :failed => 60,
277
- :ready => 0 }
278
- if timeouts[@state] > 0 &&
279
- TjTime.now - @stateUpdated > timeouts[@state]
280
- @log.fatal("Reached timeout for state #{@state}. Terminating.")
281
- end
286
+ # Check for pending requests for new ReportServers.
287
+ unless @reportServerRequests.empty?
288
+ tag = @reportServerRequests.pop
289
+ @log.debug("Popped #{tag}")
290
+ # Create an new entry for the @reportServers list.
291
+ rsr = ReportServerRecord.new(tag)
292
+ @log.debug("RSR created")
293
+ # Create a new ReportServer object that runs as a separate
294
+ # process. The constructor will tell us the URI and authentication
295
+ # key of the new ReportServer.
296
+ rs = ReportServer.new(@tj, @logConsole)
297
+ rsr.uri = rs.uri
298
+ rsr.authKey = rs.authKey
299
+ @log.debug("Adding ReportServer with URI #{rsr.uri} to list")
300
+ # Add the new ReportServer to our list.
301
+ @reportServers.synchronize do
302
+ @reportServers << rsr
303
+ end
304
+ end
282
305
 
283
- # If we have not received a ping from the ProjectBroker for 2
284
- # minutes, we assume it has died and terminate as well.
285
- if TjTime.now - @lastPing > 180
286
- @log.fatal('Heartbeat from daemon lost. Terminating.')
306
+ # Some state changing operations are not atomic. Since the client
307
+ # can die during the transaction, the server might hang in some
308
+ # states. Here we define timeout for each state. If the timeout is
309
+ # not 0 and exceeded, we immediately terminate the process.
310
+ timeouts = { :new => 10, :loading => 15 * 60, :failed => 60,
311
+ :ready => 0 }
312
+ if timeouts[@state] > 0 &&
313
+ TjTime.now - @stateUpdated > timeouts[@state]
314
+ @log.fatal("Reached timeout for state #{@state}. Terminating.")
315
+ end
316
+
317
+ # If we have not received a ping from the ProjectBroker for 2
318
+ # minutes, we assume it has died and terminate as well.
319
+ if TjTime.now - @lastPing > 180
320
+ @log.fatal('Heartbeat from daemon lost. Terminating.')
321
+ end
322
+ sleep 1
287
323
  end
288
- sleep 1
324
+ rescue
325
+ # Make sure we get a backtrace for this thread.
326
+ $stderr.print $!.to_s
327
+ $stderr.print $!.backtrace.join("\n")
328
+ @log.fatal("ProjectServer housekeeping error: #{$!}")
289
329
  end
290
330
  end
291
331
  end
@@ -305,31 +345,31 @@ class TaskJuggler
305
345
  def loadProject(authKey, args)
306
346
  return false unless @server.checkKey(authKey, 'loadProject')
307
347
 
308
- @server.loadProject(args)
348
+ trap { @server.loadProject(args) }
309
349
  end
310
350
 
311
351
  def getProjectName(authKey)
312
352
  return false unless @server.checkKey(authKey, 'getReportServer')
313
353
 
314
- @server.getProjectName
354
+ trap { @server.getProjectName }
315
355
  end
316
356
 
317
357
  def getReportList(authKey)
318
358
  return false unless @server.checkKey(authKey, 'getReportServer')
319
359
 
320
- @server.getReportList
360
+ trap { @server.getReportList }
321
361
  end
322
362
 
323
363
  def getReportServer(authKey)
324
364
  return false unless @server.checkKey(authKey, 'getReportServer')
325
365
 
326
- @server.getReportServer
366
+ trap { @server.getReportServer }
327
367
  end
328
368
 
329
369
  def ping(authKey)
330
370
  return false unless @server.checkKey(authKey, 'ping')
331
371
 
332
- @server.ping
372
+ trap { @server.ping }
333
373
  true
334
374
  end
335
375
 
@@ -12,7 +12,6 @@
12
12
 
13
13
  require 'daemon/ProcessIntercom'
14
14
  require 'TjException'
15
- require 'Message'
16
15
  require 'TjTime'
17
16
 
18
17
  class TaskJuggler
@@ -23,7 +22,7 @@ class TaskJuggler
23
22
 
24
23
  attr_reader :uri, :authKey
25
24
 
26
- def initialize(tj)
25
+ def initialize(tj, logConsole = false)
27
26
  initIntercom
28
27
 
29
28
  @pid = nil
@@ -45,33 +44,45 @@ class TaskJuggler
45
44
  if (@pid = fork) == -1
46
45
  @log.fatal('ReportServer fork failed')
47
46
  elsif @pid.nil?
48
- # This is the child
49
- $SAFE = 1
50
- DRb.install_acl(ACL.new(%w[ deny all
51
- allow 127.0.0.1 ]))
52
- DRb.start_service
53
- iFace = ReportServerIface.new(self)
54
- begin
55
- uri = DRb.start_service('druby://127.0.0.1:0', iFace).uri
56
- @log.debug("Report server is listening on #{uri}")
57
- rescue
58
- @log.fatal("ReportServer can't start DRb: #{$!}")
47
+ if logConsole
48
+ # If the Broker wasn't daemonized, log stdout and stderr to PID
49
+ # specific files.
50
+ $stderr.reopen("tj3d.rs.#{$$}.stderr", 'w')
51
+ $stdout.reopen("tj3d.rs.#{$$}.stdout", 'w')
59
52
  end
53
+ begin
54
+ # This is the child
55
+ $SAFE = 1
56
+ DRb.install_acl(ACL.new(%w[ deny all
57
+ allow 127.0.0.1 ]))
58
+ DRb.start_service
59
+ iFace = ReportServerIface.new(self)
60
+ begin
61
+ uri = DRb.start_service('druby://127.0.0.1:0', iFace).uri
62
+ @log.debug("Report server is listening on #{uri}")
63
+ rescue
64
+ @log.fatal("ReportServer can't start DRb: #{$!}")
65
+ end
60
66
 
61
- # Send the URI of the newly started DRb server to the parent process.
62
- rd.close
63
- wr.write uri
64
- wr.close
67
+ # Send the URI of the newly started DRb server to the parent process.
68
+ rd.close
69
+ wr.write uri
70
+ wr.close
65
71
 
66
- # Start a Thread that waits for the @terminate flag to be set and does
67
- # other background tasks.
68
- startTerminator
69
- startWatchDog
72
+ # Start a Thread that waits for the @terminate flag to be set and does
73
+ # other background tasks.
74
+ startTerminator
75
+ startWatchDog
70
76
 
71
- # Cleanup the DRb threads
72
- DRb.thread.join
73
- @log.debug('Report server terminated')
74
- exit 0
77
+ # Cleanup the DRb threads
78
+ DRb.thread.join
79
+ @log.debug('Report server terminated')
80
+ exit 0
81
+ rescue
82
+ $stderr.print $!.to_s
83
+ $stderr.print $!.backtrace.join("\n")
84
+ @log.fatal("ReportServer caught unexpected exception: #{$!}")
85
+ end
75
86
  else
76
87
  Process.detach(@pid)
77
88
  # This is the parent
@@ -159,38 +170,38 @@ class TaskJuggler
159
170
  def ping(authKey)
160
171
  return false unless @server.checkKey(authKey, 'addFile')
161
172
 
162
- @server.ping
173
+ trap { @server.ping }
163
174
  end
164
175
 
165
176
  def addFile(authKey, file)
166
177
  return false unless @server.checkKey(authKey, 'addFile')
167
178
 
168
- @server.addFile(file)
179
+ trap { @server.addFile(file) }
169
180
  end
170
181
 
171
182
  def generateReport(authKey, reportId, regExpMode, dynamicAttributes)
172
183
  return false unless @server.checkKey(authKey, 'generateReport')
173
184
 
174
- @server.generateReport(reportId, regExpMode, dynamicAttributes)
185
+ trap { @server.generateReport(reportId, regExpMode, dynamicAttributes) }
175
186
  end
176
187
 
177
188
 
178
189
  def listReports(authKey, reportId, regExpMode)
179
190
  return false unless @server.checkKey(authKey, 'generateReport')
180
191
 
181
- @server.listReports(reportId, regExpMode)
192
+ trap { @server.listReports(reportId, regExpMode) }
182
193
  end
183
194
 
184
195
  def checkTimeSheet(authKey, sheet)
185
196
  return false unless @server.checkKey(authKey, 'checkTimeSheet')
186
197
 
187
- @server.checkTimeSheet(sheet)
198
+ trap { @server.checkTimeSheet(sheet) }
188
199
  end
189
200
 
190
201
  def checkStatusSheet(authKey, sheet)
191
202
  return false unless @server.checkKey(authKey, 'checkStatusSheet')
192
203
 
193
- @server.checkStatusSheet(sheet)
204
+ trap { @server.checkStatusSheet(sheet) }
194
205
  end
195
206
 
196
207
  end
@@ -32,6 +32,7 @@ class TaskJuggler
32
32
 
33
33
  # Create a web server object that runs in a separate thread.
34
34
  def initialize(broker, port)
35
+ @log = LogFile.instance
35
36
  @broker = broker
36
37
 
37
38
  config = { :Port => port }
@@ -40,12 +41,29 @@ class TaskJuggler
40
41
 
41
42
  # Serve some directories via the FileHandler servlet.
42
43
  %w( css icons scripts ).each do |dir|
43
- fullDir = AppConfig.dataDirs("data/#{dir}")[0]
44
+ unless (fullDir = AppConfig.dataDirs("data/#{dir}")[0])
45
+ @log.fatal(<<"EOT"
46
+ Cannot find the #{dir} directory. This is usually the result of an
47
+ improper TaskJuggler installation. If you know the directory, you can use the
48
+ TASKJUGGLER_DATA_PATH environment variable to specify the location. The
49
+ variable should be set to the path without the /data at the end. Multiple
50
+ directories must be separated by colons.
51
+ EOT
52
+ )
53
+ end
44
54
  @server.mount("/#{dir}", WEBrick::HTTPServlet::FileHandler, fullDir)
45
55
  end
46
56
 
47
57
  # Start the web server in a new thread so we don't block this thread.
48
- @thread = Thread.new { @server.start }
58
+ @thread = Thread.new do
59
+ begin
60
+ @server.start
61
+ rescue
62
+ $stderr.print $!.to_s
63
+ $stderr.print $!.backtrace.join("\n")
64
+ @log.fatal("Web server error: #{$!}")
65
+ end
66
+ end
49
67
  end
50
68
 
51
69
  # Stop the web server.
@@ -79,6 +97,7 @@ class TaskJuggler
79
97
  generateWelcomePage(projectId)
80
98
  else
81
99
  attributes = req.query['attributes'] || ''
100
+ attributes = URLParameter.decode(attributes) unless attributes.empty?
82
101
  generateReport(projectId, reportId, attributes)
83
102
  end
84
103
  rescue