taskjuggler 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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