ribit 0.3.0

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 (650) hide show
  1. data/INSTALL +52 -0
  2. data/LICENSE +343 -0
  3. data/README +42 -0
  4. data/bin/ribit +26 -0
  5. data/bin/ribit-setup +153 -0
  6. data/bin/ribitd +18 -0
  7. data/doc/TODO.txt +207 -0
  8. data/doc/devdiary.txt +258 -0
  9. data/doc/diagrams/content-classes.dia +0 -0
  10. data/doc/diagrams/main-classes.dia +0 -0
  11. data/doc/diagrams/page-rendering-classes.dia +0 -0
  12. data/doc/diagrams/ribitservlet-classes.dia +0 -0
  13. data/doc/examples/xhtml-example.html +64 -0
  14. data/doc/notes.txt +7 -0
  15. data/doc/rdoc/classes/ActionAdapter.html +137 -0
  16. data/doc/rdoc/classes/ActionAdapter.src/M000160.html +26 -0
  17. data/doc/rdoc/classes/ActionElement.html +179 -0
  18. data/doc/rdoc/classes/ActionElement.src/M000204.html +19 -0
  19. data/doc/rdoc/classes/ActionElement.src/M000205.html +18 -0
  20. data/doc/rdoc/classes/ActionManager.html +187 -0
  21. data/doc/rdoc/classes/ActionManager.src/M000237.html +19 -0
  22. data/doc/rdoc/classes/ActionManager.src/M000238.html +22 -0
  23. data/doc/rdoc/classes/ActionManager.src/M000239.html +22 -0
  24. data/doc/rdoc/classes/ActionManager.src/M000240.html +23 -0
  25. data/doc/rdoc/classes/Assert.html +229 -0
  26. data/doc/rdoc/classes/Assert.src/M000369.html +20 -0
  27. data/doc/rdoc/classes/Assert.src/M000370.html +18 -0
  28. data/doc/rdoc/classes/Assert.src/M000371.html +20 -0
  29. data/doc/rdoc/classes/Assert.src/M000372.html +18 -0
  30. data/doc/rdoc/classes/Assert.src/M000373.html +20 -0
  31. data/doc/rdoc/classes/Assert.src/M000374.html +18 -0
  32. data/doc/rdoc/classes/Assert.src/M000375.html +22 -0
  33. data/doc/rdoc/classes/Assert/AssertionFailedException.html +117 -0
  34. data/doc/rdoc/classes/BaseTag.html +166 -0
  35. data/doc/rdoc/classes/BaseTag.src/M000049.html +20 -0
  36. data/doc/rdoc/classes/BoldContainer.html +139 -0
  37. data/doc/rdoc/classes/BoldContainer.src/M000164.html +18 -0
  38. data/doc/rdoc/classes/BoldParser.html +156 -0
  39. data/doc/rdoc/classes/BoldParser.src/M000247.html +18 -0
  40. data/doc/rdoc/classes/BoldParser.src/M000248.html +18 -0
  41. data/doc/rdoc/classes/CachedPage.html +187 -0
  42. data/doc/rdoc/classes/CachedPage.src/M000244.html +20 -0
  43. data/doc/rdoc/classes/CachedPage.src/M000245.html +27 -0
  44. data/doc/rdoc/classes/CachedPage.src/M000246.html +18 -0
  45. data/doc/rdoc/classes/CancelAction.html +179 -0
  46. data/doc/rdoc/classes/CancelAction.src/M000165.html +22 -0
  47. data/doc/rdoc/classes/CancelAction.src/M000166.html +20 -0
  48. data/doc/rdoc/classes/CancelAction.src/M000167.html +21 -0
  49. data/doc/rdoc/classes/CancelCategoryAction.html +164 -0
  50. data/doc/rdoc/classes/CancelCategoryAction.src/M000115.html +22 -0
  51. data/doc/rdoc/classes/CancelCategoryAction.src/M000116.html +20 -0
  52. data/doc/rdoc/classes/CategoriesPage.html +212 -0
  53. data/doc/rdoc/classes/CategoriesPage.src/M000232.html +27 -0
  54. data/doc/rdoc/classes/CategoriesPage.src/M000233.html +18 -0
  55. data/doc/rdoc/classes/CategoriesPage.src/M000234.html +73 -0
  56. data/doc/rdoc/classes/CategoriesPage.src/M000235.html +29 -0
  57. data/doc/rdoc/classes/CategoriesPage.src/M000236.html +59 -0
  58. data/doc/rdoc/classes/CategoryBarActionElement.html +139 -0
  59. data/doc/rdoc/classes/CategoryBarActionElement.src/M000069.html +18 -0
  60. data/doc/rdoc/classes/CategoryBarNextLevelActionElement.html +139 -0
  61. data/doc/rdoc/classes/CategoryBarNextLevelActionElement.src/M000026.html +18 -0
  62. data/doc/rdoc/classes/CategoryFormAction.html +169 -0
  63. data/doc/rdoc/classes/CategoryFormAction.src/M000148.html +18 -0
  64. data/doc/rdoc/classes/CategoryFormAction.src/M000149.html +30 -0
  65. data/doc/rdoc/classes/CategoryFormActionAdapter.html +171 -0
  66. data/doc/rdoc/classes/CategoryFormActionAdapter.src/M000112.html +19 -0
  67. data/doc/rdoc/classes/CategoryFormActionAdapter.src/M000113.html +18 -0
  68. data/doc/rdoc/classes/CategoryFormActionAdapter.src/M000114.html +18 -0
  69. data/doc/rdoc/classes/CompositeAction.html +186 -0
  70. data/doc/rdoc/classes/CompositeAction.src/M000119.html +19 -0
  71. data/doc/rdoc/classes/CompositeAction.src/M000120.html +18 -0
  72. data/doc/rdoc/classes/CompositeAction.src/M000121.html +21 -0
  73. data/doc/rdoc/classes/CompositeAction.src/M000122.html +18 -0
  74. data/doc/rdoc/classes/CompositeLinkActionElement.html +156 -0
  75. data/doc/rdoc/classes/CompositeLinkActionElement.src/M000196.html +20 -0
  76. data/doc/rdoc/classes/CompositeLinkActionElement.src/M000197.html +41 -0
  77. data/doc/rdoc/classes/Constants.html +198 -0
  78. data/doc/rdoc/classes/Container.html +281 -0
  79. data/doc/rdoc/classes/Container.src/M000251.html +19 -0
  80. data/doc/rdoc/classes/Container.src/M000252.html +18 -0
  81. data/doc/rdoc/classes/Container.src/M000253.html +18 -0
  82. data/doc/rdoc/classes/Container.src/M000254.html +18 -0
  83. data/doc/rdoc/classes/Container.src/M000255.html +27 -0
  84. data/doc/rdoc/classes/Container.src/M000256.html +18 -0
  85. data/doc/rdoc/classes/Container.src/M000257.html +18 -0
  86. data/doc/rdoc/classes/Container.src/M000258.html +18 -0
  87. data/doc/rdoc/classes/Container.src/M000259.html +18 -0
  88. data/doc/rdoc/classes/Container.src/M000260.html +23 -0
  89. data/doc/rdoc/classes/ContentDoc.html +236 -0
  90. data/doc/rdoc/classes/ContentDoc.src/M000129.html +22 -0
  91. data/doc/rdoc/classes/ContentDoc.src/M000130.html +18 -0
  92. data/doc/rdoc/classes/ContentDoc.src/M000131.html +20 -0
  93. data/doc/rdoc/classes/ContentDoc.src/M000132.html +18 -0
  94. data/doc/rdoc/classes/ContentDoc.src/M000133.html +18 -0
  95. data/doc/rdoc/classes/ContentDoc.src/M000134.html +18 -0
  96. data/doc/rdoc/classes/ContentDoc.src/M000135.html +18 -0
  97. data/doc/rdoc/classes/ContentParser.html +176 -0
  98. data/doc/rdoc/classes/ContentParser.src/M000176.html +30 -0
  99. data/doc/rdoc/classes/ContentParser.src/M000177.html +28 -0
  100. data/doc/rdoc/classes/ContentParser.src/M000178.html +55 -0
  101. data/doc/rdoc/classes/CurrentList.html +209 -0
  102. data/doc/rdoc/classes/CurrentList.src/M000228.html +19 -0
  103. data/doc/rdoc/classes/CurrentList.src/M000229.html +18 -0
  104. data/doc/rdoc/classes/CurrentList.src/M000230.html +18 -0
  105. data/doc/rdoc/classes/CurrentList.src/M000231.html +18 -0
  106. data/doc/rdoc/classes/DataContainer.html +234 -0
  107. data/doc/rdoc/classes/DataContainer.src/M000101.html +26 -0
  108. data/doc/rdoc/classes/DataContainer.src/M000102.html +24 -0
  109. data/doc/rdoc/classes/DataContainer.src/M000103.html +23 -0
  110. data/doc/rdoc/classes/DataContainer.src/M000104.html +26 -0
  111. data/doc/rdoc/classes/DataContainer.src/M000105.html +22 -0
  112. data/doc/rdoc/classes/DataContainer.src/M000106.html +18 -0
  113. data/doc/rdoc/classes/DataStorage.html +199 -0
  114. data/doc/rdoc/classes/DataStorage.src/M000031.html +23 -0
  115. data/doc/rdoc/classes/DataStorage.src/M000032.html +36 -0
  116. data/doc/rdoc/classes/DataStorage.src/M000033.html +25 -0
  117. data/doc/rdoc/classes/DataStorage.src/M000034.html +30 -0
  118. data/doc/rdoc/classes/DataStorage.src/M000035.html +21 -0
  119. data/doc/rdoc/classes/DefaultAction.html +187 -0
  120. data/doc/rdoc/classes/DefaultAction.src/M000014.html +23 -0
  121. data/doc/rdoc/classes/DefaultAction.src/M000015.html +36 -0
  122. data/doc/rdoc/classes/DefaultAction.src/M000016.html +38 -0
  123. data/doc/rdoc/classes/DefaultLoggerFactory.html +140 -0
  124. data/doc/rdoc/classes/DefaultLoggerFactory.src/M000169.html +19 -0
  125. data/doc/rdoc/classes/DirectLinkContainer.html +156 -0
  126. data/doc/rdoc/classes/DirectLinkContainer.src/M000209.html +19 -0
  127. data/doc/rdoc/classes/DirectLinkContainer.src/M000210.html +18 -0
  128. data/doc/rdoc/classes/DirectLinkParser.html +137 -0
  129. data/doc/rdoc/classes/DirectLinkParser.src/M000168.html +39 -0
  130. data/doc/rdoc/classes/DivTag.html +150 -0
  131. data/doc/rdoc/classes/DivTag.src/M000030.html +19 -0
  132. data/doc/rdoc/classes/EditAction.html +177 -0
  133. data/doc/rdoc/classes/EditAction.src/M000056.html +24 -0
  134. data/doc/rdoc/classes/EditAction.src/M000057.html +64 -0
  135. data/doc/rdoc/classes/EditActionAdapter.html +139 -0
  136. data/doc/rdoc/classes/EditActionAdapter.src/M000002.html +20 -0
  137. data/doc/rdoc/classes/EditCategoryAction.html +176 -0
  138. data/doc/rdoc/classes/EditCategoryAction.src/M000126.html +24 -0
  139. data/doc/rdoc/classes/EditCategoryAction.src/M000127.html +39 -0
  140. data/doc/rdoc/classes/EditCategoryActionAdapter.html +139 -0
  141. data/doc/rdoc/classes/EditCategoryActionAdapter.src/M000021.html +20 -0
  142. data/doc/rdoc/classes/EditCategoryPage.html +242 -0
  143. data/doc/rdoc/classes/EditCategoryPage.src/M000036.html +29 -0
  144. data/doc/rdoc/classes/EditCategoryPage.src/M000037.html +18 -0
  145. data/doc/rdoc/classes/EditCategoryPage.src/M000038.html +18 -0
  146. data/doc/rdoc/classes/EditCategoryPage.src/M000039.html +18 -0
  147. data/doc/rdoc/classes/EditCategoryPage.src/M000040.html +109 -0
  148. data/doc/rdoc/classes/EditCategoryPage.src/M000041.html +60 -0
  149. data/doc/rdoc/classes/EditCategoryPage.src/M000042.html +29 -0
  150. data/doc/rdoc/classes/EditNewActionAdapter.html +156 -0
  151. data/doc/rdoc/classes/EditNewActionAdapter.src/M000220.html +20 -0
  152. data/doc/rdoc/classes/EditNewActionAdapter.src/M000221.html +23 -0
  153. data/doc/rdoc/classes/EditPage.html +212 -0
  154. data/doc/rdoc/classes/EditPage.src/M000064.html +33 -0
  155. data/doc/rdoc/classes/EditPage.src/M000065.html +18 -0
  156. data/doc/rdoc/classes/EditPage.src/M000066.html +18 -0
  157. data/doc/rdoc/classes/EditPage.src/M000067.html +18 -0
  158. data/doc/rdoc/classes/EditPage.src/M000068.html +112 -0
  159. data/doc/rdoc/classes/EmphasisContainer.html +156 -0
  160. data/doc/rdoc/classes/EmphasisContainer.src/M000003.html +20 -0
  161. data/doc/rdoc/classes/EmphasisContainer.src/M000004.html +19 -0
  162. data/doc/rdoc/classes/EmphasisParser.html +176 -0
  163. data/doc/rdoc/classes/EmphasisParser.src/M000076.html +19 -0
  164. data/doc/rdoc/classes/EmphasisParser.src/M000077.html +18 -0
  165. data/doc/rdoc/classes/EmphasisParser.src/M000078.html +45 -0
  166. data/doc/rdoc/classes/EscapeParser.html +137 -0
  167. data/doc/rdoc/classes/EscapeParser.src/M000150.html +26 -0
  168. data/doc/rdoc/classes/ExpireMetaTag.html +139 -0
  169. data/doc/rdoc/classes/ExpireMetaTag.src/M000241.html +18 -0
  170. data/doc/rdoc/classes/FilePersistentStorageHandler.html +207 -0
  171. data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000215.html +27 -0
  172. data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000216.html +21 -0
  173. data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000217.html +19 -0
  174. data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000218.html +19 -0
  175. data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000219.html +20 -0
  176. data/doc/rdoc/classes/FormAction.html +169 -0
  177. data/doc/rdoc/classes/FormAction.src/M000081.html +18 -0
  178. data/doc/rdoc/classes/FormAction.src/M000082.html +30 -0
  179. data/doc/rdoc/classes/FormActionAdapter.html +171 -0
  180. data/doc/rdoc/classes/FormActionAdapter.src/M000086.html +19 -0
  181. data/doc/rdoc/classes/FormActionAdapter.src/M000087.html +18 -0
  182. data/doc/rdoc/classes/FormActionAdapter.src/M000088.html +18 -0
  183. data/doc/rdoc/classes/FormActionElement.html +169 -0
  184. data/doc/rdoc/classes/FormActionElement.src/M000044.html +18 -0
  185. data/doc/rdoc/classes/FormActionElement.src/M000045.html +18 -0
  186. data/doc/rdoc/classes/FormActionElement.src/M000046.html +23 -0
  187. data/doc/rdoc/classes/FormInputTag.html +165 -0
  188. data/doc/rdoc/classes/FormInputTag.src/M000161.html +21 -0
  189. data/doc/rdoc/classes/HiddenFormInputTag.html +139 -0
  190. data/doc/rdoc/classes/HiddenFormInputTag.src/M000027.html +18 -0
  191. data/doc/rdoc/classes/IDataStorage.html +170 -0
  192. data/doc/rdoc/classes/IDataStorage.src/M000382.html +18 -0
  193. data/doc/rdoc/classes/IDataStorage.src/M000383.html +18 -0
  194. data/doc/rdoc/classes/IDataStorage.src/M000384.html +18 -0
  195. data/doc/rdoc/classes/ItalicContainer.html +139 -0
  196. data/doc/rdoc/classes/ItalicContainer.src/M000128.html +18 -0
  197. data/doc/rdoc/classes/ItalicParser.html +156 -0
  198. data/doc/rdoc/classes/ItalicParser.src/M000207.html +18 -0
  199. data/doc/rdoc/classes/ItalicParser.src/M000208.html +18 -0
  200. data/doc/rdoc/classes/LinkActionElement.html +184 -0
  201. data/doc/rdoc/classes/LinkActionElement.src/M000005.html +18 -0
  202. data/doc/rdoc/classes/LinkActionElement.src/M000006.html +18 -0
  203. data/doc/rdoc/classes/LinkActionElement.src/M000007.html +18 -0
  204. data/doc/rdoc/classes/LinkActionElement.src/M000008.html +18 -0
  205. data/doc/rdoc/classes/LinkTag.html +187 -0
  206. data/doc/rdoc/classes/LinkTag.src/M000153.html +34 -0
  207. data/doc/rdoc/classes/LinkTag.src/M000154.html +18 -0
  208. data/doc/rdoc/classes/LinkTag.src/M000155.html +20 -0
  209. data/doc/rdoc/classes/ListContainer.html +156 -0
  210. data/doc/rdoc/classes/ListContainer.src/M000174.html +18 -0
  211. data/doc/rdoc/classes/ListContainer.src/M000175.html +19 -0
  212. data/doc/rdoc/classes/ListItemContainer.html +156 -0
  213. data/doc/rdoc/classes/ListItemContainer.src/M000028.html +19 -0
  214. data/doc/rdoc/classes/ListItemContainer.src/M000029.html +19 -0
  215. data/doc/rdoc/classes/ListParser.html +144 -0
  216. data/doc/rdoc/classes/ListParser.src/M000195.html +147 -0
  217. data/doc/rdoc/classes/ListParserUtils.html +141 -0
  218. data/doc/rdoc/classes/ListParserUtils.src/M000385.html +23 -0
  219. data/doc/rdoc/classes/Localization.html +209 -0
  220. data/doc/rdoc/classes/Localization.src/M000311.html +40 -0
  221. data/doc/rdoc/classes/Localization.src/M000312.html +23 -0
  222. data/doc/rdoc/classes/Log4r.html +111 -0
  223. data/doc/rdoc/classes/Log4r/ExtendedRollingFileOutputter.html +178 -0
  224. data/doc/rdoc/classes/Log4r/ExtendedRollingFileOutputter.src/M000380.html +25 -0
  225. data/doc/rdoc/classes/Log4r/ExtendedRollingFileOutputter.src/M000381.html +33 -0
  226. data/doc/rdoc/classes/LoggerFactory.html +152 -0
  227. data/doc/rdoc/classes/LoggerFactory.src/M000062.html +22 -0
  228. data/doc/rdoc/classes/LoggerFactory.src/M000063.html +18 -0
  229. data/doc/rdoc/classes/MetaTag.html +166 -0
  230. data/doc/rdoc/classes/MetaTag.src/M000118.html +20 -0
  231. data/doc/rdoc/classes/NoCacheMetaTag.html +139 -0
  232. data/doc/rdoc/classes/NoCacheMetaTag.src/M000043.html +18 -0
  233. data/doc/rdoc/classes/PageRequest.html +259 -0
  234. data/doc/rdoc/classes/PageRequest.src/M000179.html +20 -0
  235. data/doc/rdoc/classes/PageRequest.src/M000180.html +18 -0
  236. data/doc/rdoc/classes/PageRequest.src/M000181.html +18 -0
  237. data/doc/rdoc/classes/PageRequest.src/M000182.html +18 -0
  238. data/doc/rdoc/classes/PageRequest.src/M000183.html +19 -0
  239. data/doc/rdoc/classes/PageRequest.src/M000184.html +23 -0
  240. data/doc/rdoc/classes/PageRequest.src/M000185.html +23 -0
  241. data/doc/rdoc/classes/PageRequest.src/M000186.html +19 -0
  242. data/doc/rdoc/classes/PageRequest.src/M000187.html +18 -0
  243. data/doc/rdoc/classes/PageResponse.html +250 -0
  244. data/doc/rdoc/classes/PageResponse.src/M000092.html +18 -0
  245. data/doc/rdoc/classes/PageResponse.src/M000093.html +18 -0
  246. data/doc/rdoc/classes/PageResponse.src/M000094.html +18 -0
  247. data/doc/rdoc/classes/PageResponse.src/M000095.html +18 -0
  248. data/doc/rdoc/classes/PageResponse.src/M000096.html +18 -0
  249. data/doc/rdoc/classes/PageResponse.src/M000097.html +18 -0
  250. data/doc/rdoc/classes/PageResponse.src/M000098.html +18 -0
  251. data/doc/rdoc/classes/PageResponse.src/M000099.html +18 -0
  252. data/doc/rdoc/classes/ParagraphContainer.html +156 -0
  253. data/doc/rdoc/classes/ParagraphContainer.src/M000158.html +19 -0
  254. data/doc/rdoc/classes/ParagraphContainer.src/M000159.html +24 -0
  255. data/doc/rdoc/classes/ParagraphParser.html +137 -0
  256. data/doc/rdoc/classes/ParagraphParser.src/M000151.html +42 -0
  257. data/doc/rdoc/classes/PersistentStorageHandler.html +182 -0
  258. data/doc/rdoc/classes/PersistentStorageHandler.src/M000376.html +18 -0
  259. data/doc/rdoc/classes/PersistentStorageHandler.src/M000377.html +18 -0
  260. data/doc/rdoc/classes/PersistentStorageHandler.src/M000378.html +18 -0
  261. data/doc/rdoc/classes/PersistentStorageHandler.src/M000379.html +18 -0
  262. data/doc/rdoc/classes/Pid.html +182 -0
  263. data/doc/rdoc/classes/Pid.src/M000083.html +18 -0
  264. data/doc/rdoc/classes/Pid.src/M000084.html +24 -0
  265. data/doc/rdoc/classes/Pid.src/M000085.html +18 -0
  266. data/doc/rdoc/classes/Properties.html +184 -0
  267. data/doc/rdoc/classes/Properties.src/M000058.html +18 -0
  268. data/doc/rdoc/classes/Properties.src/M000059.html +18 -0
  269. data/doc/rdoc/classes/Properties.src/M000060.html +18 -0
  270. data/doc/rdoc/classes/Properties.src/M000061.html +27 -0
  271. data/doc/rdoc/classes/PropertyList.html +187 -0
  272. data/doc/rdoc/classes/PropertyList.src/M000017.html +19 -0
  273. data/doc/rdoc/classes/PropertyList.src/M000018.html +23 -0
  274. data/doc/rdoc/classes/PropertyList.src/M000019.html +23 -0
  275. data/doc/rdoc/classes/PropertyList.src/M000020.html +18 -0
  276. data/doc/rdoc/classes/RawAttribute.html +154 -0
  277. data/doc/rdoc/classes/RawAttribute.src/M000249.html +20 -0
  278. data/doc/rdoc/classes/RawAttribute.src/M000250.html +21 -0
  279. data/doc/rdoc/classes/RawPage.html +171 -0
  280. data/doc/rdoc/classes/RawPage.src/M000107.html +19 -0
  281. data/doc/rdoc/classes/RawPage.src/M000108.html +18 -0
  282. data/doc/rdoc/classes/RawPage.src/M000109.html +18 -0
  283. data/doc/rdoc/classes/ReferenceLinkContainer.html +156 -0
  284. data/doc/rdoc/classes/ReferenceLinkContainer.src/M000213.html +20 -0
  285. data/doc/rdoc/classes/ReferenceLinkContainer.src/M000214.html +19 -0
  286. data/doc/rdoc/classes/Ribit.html +124 -0
  287. data/doc/rdoc/classes/Ribit/ContentStore.html +236 -0
  288. data/doc/rdoc/classes/Ribit/ContentStore.src/M000304.html +23 -0
  289. data/doc/rdoc/classes/Ribit/ContentStore.src/M000305.html +29 -0
  290. data/doc/rdoc/classes/Ribit/ContentStore.src/M000306.html +25 -0
  291. data/doc/rdoc/classes/Ribit/ContentStore.src/M000307.html +49 -0
  292. data/doc/rdoc/classes/Ribit/ContentStore.src/M000308.html +18 -0
  293. data/doc/rdoc/classes/Ribit/ContentStore.src/M000309.html +73 -0
  294. data/doc/rdoc/classes/Ribit/ContentStore.src/M000310.html +51 -0
  295. data/doc/rdoc/classes/Ribit/FileWriter.html +162 -0
  296. data/doc/rdoc/classes/Ribit/FileWriter.src/M000289.html +19 -0
  297. data/doc/rdoc/classes/Ribit/FileWriter.src/M000290.html +32 -0
  298. data/doc/rdoc/classes/Ribit/Repository.html +174 -0
  299. data/doc/rdoc/classes/Ribit/Repository.src/M000276.html +18 -0
  300. data/doc/rdoc/classes/Ribit/Repository.src/M000277.html +18 -0
  301. data/doc/rdoc/classes/Ribit/Repository.src/M000278.html +18 -0
  302. data/doc/rdoc/classes/Ribit/RibitLogger.html +137 -0
  303. data/doc/rdoc/classes/Ribit/RibitLogger.src/M000301.html +18 -0
  304. data/doc/rdoc/classes/Ribit/RibitLoggerConfig.html +182 -0
  305. data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000279.html +18 -0
  306. data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000280.html +23 -0
  307. data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000281.html +21 -0
  308. data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000282.html +18 -0
  309. data/doc/rdoc/classes/Ribit/RibitLoggerFactory.html +154 -0
  310. data/doc/rdoc/classes/Ribit/RibitLoggerFactory.src/M000287.html +18 -0
  311. data/doc/rdoc/classes/Ribit/RibitLoggerFactory.src/M000288.html +25 -0
  312. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.html +229 -0
  313. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000294.html +26 -0
  314. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000295.html +18 -0
  315. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000296.html +18 -0
  316. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000297.html +18 -0
  317. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000298.html +18 -0
  318. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000299.html +18 -0
  319. data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000300.html +18 -0
  320. data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.html +210 -0
  321. data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.src/M000291.html +20 -0
  322. data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.src/M000292.html +32 -0
  323. data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.src/M000293.html +18 -0
  324. data/doc/rdoc/classes/Ribit/Writer.html +163 -0
  325. data/doc/rdoc/classes/Ribit/Writer.src/M000302.html +18 -0
  326. data/doc/rdoc/classes/Ribit/Writer.src/M000303.html +21 -0
  327. data/doc/rdoc/classes/RibitConfig.html +247 -0
  328. data/doc/rdoc/classes/RibitConfig.src/M000072.html +32 -0
  329. data/doc/rdoc/classes/RibitConfig.src/M000073.html +18 -0
  330. data/doc/rdoc/classes/RibitConfig.src/M000074.html +18 -0
  331. data/doc/rdoc/classes/RibitConfig.src/M000075.html +18 -0
  332. data/doc/rdoc/classes/RibitConfigParser.html +140 -0
  333. data/doc/rdoc/classes/RibitConfigParser.src/M000117.html +45 -0
  334. data/doc/rdoc/classes/RibitData.html +128 -0
  335. data/doc/rdoc/classes/RibitData/CategoriesWriter.html +169 -0
  336. data/doc/rdoc/classes/RibitData/CategoriesWriter.src/M000338.html +18 -0
  337. data/doc/rdoc/classes/RibitData/CategoriesWriter.src/M000339.html +27 -0
  338. data/doc/rdoc/classes/RibitData/CategoriesWriter.src/M000340.html +24 -0
  339. data/doc/rdoc/classes/RibitData/Category.html +485 -0
  340. data/doc/rdoc/classes/RibitData/Category.src/M000313.html +27 -0
  341. data/doc/rdoc/classes/RibitData/Category.src/M000314.html +36 -0
  342. data/doc/rdoc/classes/RibitData/Category.src/M000315.html +22 -0
  343. data/doc/rdoc/classes/RibitData/Category.src/M000316.html +18 -0
  344. data/doc/rdoc/classes/RibitData/Category.src/M000317.html +18 -0
  345. data/doc/rdoc/classes/RibitData/Category.src/M000318.html +18 -0
  346. data/doc/rdoc/classes/RibitData/Category.src/M000319.html +18 -0
  347. data/doc/rdoc/classes/RibitData/Category.src/M000320.html +18 -0
  348. data/doc/rdoc/classes/RibitData/Category.src/M000321.html +18 -0
  349. data/doc/rdoc/classes/RibitData/Category.src/M000322.html +18 -0
  350. data/doc/rdoc/classes/RibitData/Category.src/M000323.html +18 -0
  351. data/doc/rdoc/classes/RibitData/Category.src/M000324.html +18 -0
  352. data/doc/rdoc/classes/RibitData/Category.src/M000325.html +18 -0
  353. data/doc/rdoc/classes/RibitData/Category.src/M000326.html +18 -0
  354. data/doc/rdoc/classes/RibitData/Category.src/M000327.html +36 -0
  355. data/doc/rdoc/classes/RibitData/Category.src/M000328.html +18 -0
  356. data/doc/rdoc/classes/RibitData/Category.src/M000329.html +48 -0
  357. data/doc/rdoc/classes/RibitData/Category.src/M000330.html +45 -0
  358. data/doc/rdoc/classes/RibitData/Category.src/M000331.html +30 -0
  359. data/doc/rdoc/classes/RibitData/Category.src/M000332.html +25 -0
  360. data/doc/rdoc/classes/RibitData/Category.src/M000333.html +18 -0
  361. data/doc/rdoc/classes/RibitData/CategoryParser.html +217 -0
  362. data/doc/rdoc/classes/RibitData/CategoryParser.src/M000357.html +18 -0
  363. data/doc/rdoc/classes/RibitData/CategoryParser.src/M000358.html +29 -0
  364. data/doc/rdoc/classes/RibitData/CategoryParser.src/M000359.html +31 -0
  365. data/doc/rdoc/classes/RibitData/CategoryParser.src/M000360.html +27 -0
  366. data/doc/rdoc/classes/RibitData/CategoryParser.src/M000361.html +45 -0
  367. data/doc/rdoc/classes/RibitData/Page.html +313 -0
  368. data/doc/rdoc/classes/RibitData/Page.src/M000362.html +33 -0
  369. data/doc/rdoc/classes/RibitData/Page.src/M000363.html +22 -0
  370. data/doc/rdoc/classes/RibitData/Page.src/M000364.html +18 -0
  371. data/doc/rdoc/classes/RibitData/Page.src/M000365.html +18 -0
  372. data/doc/rdoc/classes/RibitData/Page.src/M000366.html +18 -0
  373. data/doc/rdoc/classes/RibitData/Page.src/M000367.html +46 -0
  374. data/doc/rdoc/classes/RibitData/Page.src/M000368.html +26 -0
  375. data/doc/rdoc/classes/RibitData/PageParser.html +190 -0
  376. data/doc/rdoc/classes/RibitData/PageParser.src/M000334.html +19 -0
  377. data/doc/rdoc/classes/RibitData/PageParser.src/M000335.html +32 -0
  378. data/doc/rdoc/classes/RibitData/PageParser.src/M000336.html +42 -0
  379. data/doc/rdoc/classes/RibitData/PageParser.src/M000337.html +21 -0
  380. data/doc/rdoc/classes/RibitData/RibitData.html +389 -0
  381. data/doc/rdoc/classes/RibitData/RibitData.src/M000341.html +26 -0
  382. data/doc/rdoc/classes/RibitData/RibitData.src/M000342.html +22 -0
  383. data/doc/rdoc/classes/RibitData/RibitData.src/M000343.html +18 -0
  384. data/doc/rdoc/classes/RibitData/RibitData.src/M000344.html +36 -0
  385. data/doc/rdoc/classes/RibitData/RibitData.src/M000345.html +18 -0
  386. data/doc/rdoc/classes/RibitData/RibitData.src/M000346.html +25 -0
  387. data/doc/rdoc/classes/RibitData/RibitData.src/M000347.html +18 -0
  388. data/doc/rdoc/classes/RibitData/RibitData.src/M000348.html +22 -0
  389. data/doc/rdoc/classes/RibitData/RibitData.src/M000349.html +18 -0
  390. data/doc/rdoc/classes/RibitData/RibitData.src/M000350.html +30 -0
  391. data/doc/rdoc/classes/RibitData/RibitData.src/M000351.html +18 -0
  392. data/doc/rdoc/classes/RibitData/RibitData.src/M000352.html +48 -0
  393. data/doc/rdoc/classes/RibitData/RibitData.src/M000353.html +30 -0
  394. data/doc/rdoc/classes/RibitData/RibitData.src/M000354.html +22 -0
  395. data/doc/rdoc/classes/RibitData/RibitData.src/M000355.html +22 -0
  396. data/doc/rdoc/classes/RibitData/RibitData.src/M000356.html +22 -0
  397. data/doc/rdoc/classes/RibitData/RibitDataException.html +113 -0
  398. data/doc/rdoc/classes/RibitException.html +117 -0
  399. data/doc/rdoc/classes/RibitLinkContainer.html +156 -0
  400. data/doc/rdoc/classes/RibitLinkContainer.src/M000211.html +85 -0
  401. data/doc/rdoc/classes/RibitLinkContainer.src/M000212.html +18 -0
  402. data/doc/rdoc/classes/RibitLinkParser.html +137 -0
  403. data/doc/rdoc/classes/RibitLinkParser.src/M000100.html +50 -0
  404. data/doc/rdoc/classes/RibitServlet.html +196 -0
  405. data/doc/rdoc/classes/RibitServlet.src/M000222.html +37 -0
  406. data/doc/rdoc/classes/RibitServlet.src/M000223.html +53 -0
  407. data/doc/rdoc/classes/RibitServlet.src/M000224.html +39 -0
  408. data/doc/rdoc/classes/RibitServlet.src/M000225.html +19 -0
  409. data/doc/rdoc/classes/RootContainer.html +139 -0
  410. data/doc/rdoc/classes/RootContainer.src/M000206.html +19 -0
  411. data/doc/rdoc/classes/SaveAction.html +164 -0
  412. data/doc/rdoc/classes/SaveAction.src/M000162.html +24 -0
  413. data/doc/rdoc/classes/SaveAction.src/M000163.html +116 -0
  414. data/doc/rdoc/classes/SaveCategoryAction.html +164 -0
  415. data/doc/rdoc/classes/SaveCategoryAction.src/M000047.html +24 -0
  416. data/doc/rdoc/classes/SaveCategoryAction.src/M000048.html +97 -0
  417. data/doc/rdoc/classes/SectionContainer.html +156 -0
  418. data/doc/rdoc/classes/SectionContainer.src/M000070.html +19 -0
  419. data/doc/rdoc/classes/SectionContainer.src/M000071.html +20 -0
  420. data/doc/rdoc/classes/SectionParser.html +137 -0
  421. data/doc/rdoc/classes/SectionParser.src/M000152.html +41 -0
  422. data/doc/rdoc/classes/SelectOptionTag.html +177 -0
  423. data/doc/rdoc/classes/SelectOptionTag.src/M000156.html +22 -0
  424. data/doc/rdoc/classes/SelectOptionTag.src/M000157.html +18 -0
  425. data/doc/rdoc/classes/StyleSheetAction.html +182 -0
  426. data/doc/rdoc/classes/StyleSheetAction.src/M000226.html +31 -0
  427. data/doc/rdoc/classes/StyleSheetAction.src/M000227.html +36 -0
  428. data/doc/rdoc/classes/TextContainer.html +214 -0
  429. data/doc/rdoc/classes/TextContainer.src/M000050.html +19 -0
  430. data/doc/rdoc/classes/TextContainer.src/M000051.html +18 -0
  431. data/doc/rdoc/classes/TextContainer.src/M000052.html +18 -0
  432. data/doc/rdoc/classes/TextContainer.src/M000053.html +18 -0
  433. data/doc/rdoc/classes/TextContainer.src/M000054.html +18 -0
  434. data/doc/rdoc/classes/TextContainer.src/M000055.html +18 -0
  435. data/doc/rdoc/classes/TextPage.html +226 -0
  436. data/doc/rdoc/classes/TextPage.src/M000198.html +29 -0
  437. data/doc/rdoc/classes/TextPage.src/M000199.html +18 -0
  438. data/doc/rdoc/classes/TextPage.src/M000200.html +54 -0
  439. data/doc/rdoc/classes/TextPage.src/M000201.html +36 -0
  440. data/doc/rdoc/classes/TextPage.src/M000202.html +46 -0
  441. data/doc/rdoc/classes/TextPage.src/M000203.html +25 -0
  442. data/doc/rdoc/classes/URL.html +182 -0
  443. data/doc/rdoc/classes/URL.src/M000123.html +24 -0
  444. data/doc/rdoc/classes/URL.src/M000124.html +19 -0
  445. data/doc/rdoc/classes/URL.src/M000125.html +35 -0
  446. data/doc/rdoc/classes/UnformattedContentContainer.html +156 -0
  447. data/doc/rdoc/classes/UnformattedContentContainer.src/M000079.html +20 -0
  448. data/doc/rdoc/classes/UnformattedContentContainer.src/M000080.html +20 -0
  449. data/doc/rdoc/classes/UnformattedContentParser.html +137 -0
  450. data/doc/rdoc/classes/UnformattedContentParser.src/M000194.html +49 -0
  451. data/doc/rdoc/classes/ViewAction.html +221 -0
  452. data/doc/rdoc/classes/ViewAction.src/M000009.html +25 -0
  453. data/doc/rdoc/classes/ViewAction.src/M000010.html +20 -0
  454. data/doc/rdoc/classes/ViewAction.src/M000011.html +77 -0
  455. data/doc/rdoc/classes/ViewAction.src/M000012.html +18 -0
  456. data/doc/rdoc/classes/ViewAction.src/M000013.html +22 -0
  457. data/doc/rdoc/classes/ViewActionAdapter.html +186 -0
  458. data/doc/rdoc/classes/ViewActionAdapter.src/M000022.html +20 -0
  459. data/doc/rdoc/classes/ViewActionAdapter.src/M000023.html +24 -0
  460. data/doc/rdoc/classes/ViewActionAdapter.src/M000024.html +20 -0
  461. data/doc/rdoc/classes/ViewActionAdapter.src/M000025.html +21 -0
  462. data/doc/rdoc/classes/ViewCategoriesAction.html +211 -0
  463. data/doc/rdoc/classes/ViewCategoriesAction.src/M000261.html +25 -0
  464. data/doc/rdoc/classes/ViewCategoriesAction.src/M000262.html +20 -0
  465. data/doc/rdoc/classes/ViewCategoriesAction.src/M000263.html +61 -0
  466. data/doc/rdoc/classes/ViewCategoriesAction.src/M000264.html +22 -0
  467. data/doc/rdoc/classes/ViewCategoriesActionAdapter.html +171 -0
  468. data/doc/rdoc/classes/ViewCategoriesActionAdapter.src/M000089.html +18 -0
  469. data/doc/rdoc/classes/ViewCategoriesActionAdapter.src/M000090.html +24 -0
  470. data/doc/rdoc/classes/ViewCategoriesActionAdapter.src/M000091.html +18 -0
  471. data/doc/rdoc/classes/W3CValidatorLinkActionAdapter.html +156 -0
  472. data/doc/rdoc/classes/W3CValidatorLinkActionAdapter.src/M000110.html +26 -0
  473. data/doc/rdoc/classes/W3CValidatorLinkActionAdapter.src/M000111.html +18 -0
  474. data/doc/rdoc/classes/WebAction.html +165 -0
  475. data/doc/rdoc/classes/WebAction.src/M000242.html +18 -0
  476. data/doc/rdoc/classes/WebAction.src/M000243.html +19 -0
  477. data/doc/rdoc/classes/WebPage.html +184 -0
  478. data/doc/rdoc/classes/WebPage.src/M000170.html +17 -0
  479. data/doc/rdoc/classes/WebPage.src/M000171.html +19 -0
  480. data/doc/rdoc/classes/WebPage.src/M000172.html +18 -0
  481. data/doc/rdoc/classes/WebPage.src/M000173.html +18 -0
  482. data/doc/rdoc/classes/XHTMLDocument.html +377 -0
  483. data/doc/rdoc/classes/XHTMLDocument.src/M000136.html +26 -0
  484. data/doc/rdoc/classes/XHTMLDocument.src/M000137.html +40 -0
  485. data/doc/rdoc/classes/XHTMLDocument.src/M000138.html +20 -0
  486. data/doc/rdoc/classes/XHTMLDocument.src/M000139.html +18 -0
  487. data/doc/rdoc/classes/XHTMLDocument.src/M000140.html +18 -0
  488. data/doc/rdoc/classes/XHTMLDocument.src/M000141.html +19 -0
  489. data/doc/rdoc/classes/XHTMLDocument.src/M000142.html +21 -0
  490. data/doc/rdoc/classes/XHTMLDocument.src/M000143.html +30 -0
  491. data/doc/rdoc/classes/XHTMLDocument.src/M000144.html +18 -0
  492. data/doc/rdoc/classes/XHTMLDocument.src/M000145.html +18 -0
  493. data/doc/rdoc/classes/XHTMLDocument.src/M000146.html +23 -0
  494. data/doc/rdoc/classes/XHTMLDocument.src/M000147.html +18 -0
  495. data/doc/rdoc/classes/XHTMLException.html +117 -0
  496. data/doc/rdoc/classes/XHTMLPage.html +225 -0
  497. data/doc/rdoc/classes/XHTMLPage.src/M000188.html +20 -0
  498. data/doc/rdoc/classes/XHTMLPage.src/M000189.html +18 -0
  499. data/doc/rdoc/classes/XHTMLPage.src/M000190.html +44 -0
  500. data/doc/rdoc/classes/XHTMLPage.src/M000191.html +18 -0
  501. data/doc/rdoc/classes/XHTMLPage.src/M000192.html +54 -0
  502. data/doc/rdoc/classes/XHTMLPage.src/M000193.html +22 -0
  503. data/doc/rdoc/created.rid +1 -0
  504. data/doc/rdoc/files/CHANGES.html +150 -0
  505. data/doc/rdoc/files/INSTALL.html +169 -0
  506. data/doc/rdoc/files/LICENSE.html +449 -0
  507. data/doc/rdoc/files/README.html +176 -0
  508. data/doc/rdoc/files/lib/common/assert_rb.html +101 -0
  509. data/doc/rdoc/files/lib/common/cvs_rb.html +116 -0
  510. data/doc/rdoc/files/lib/common/datastorage_rb.html +108 -0
  511. data/doc/rdoc/files/lib/common/loggerfactory_rb.html +108 -0
  512. data/doc/rdoc/files/lib/common/pid_rb.html +101 -0
  513. data/doc/rdoc/files/lib/common/properties_rb.html +101 -0
  514. data/doc/rdoc/files/lib/common/url_rb.html +108 -0
  515. data/doc/rdoc/files/lib/log4r/outputter/extendedrollingfileoutputter_rb.html +111 -0
  516. data/doc/rdoc/files/lib/ribit/action_rb.html +116 -0
  517. data/doc/rdoc/files/lib/ribit/actionelement_rb.html +108 -0
  518. data/doc/rdoc/files/lib/ribit/common_rb.html +130 -0
  519. data/doc/rdoc/files/lib/ribit/common_rb.src/M000001.html +25 -0
  520. data/doc/rdoc/files/lib/ribit/config_rb.html +116 -0
  521. data/doc/rdoc/files/lib/ribit/constants_rb.html +101 -0
  522. data/doc/rdoc/files/lib/ribit/contentparser_rb.html +112 -0
  523. data/doc/rdoc/files/lib/ribit/contentstore_rb.html +112 -0
  524. data/doc/rdoc/files/lib/ribit/localization_rb.html +108 -0
  525. data/doc/rdoc/files/lib/ribit/main_rb.html +120 -0
  526. data/doc/rdoc/files/lib/ribit/ribit_rb.html +123 -0
  527. data/doc/rdoc/files/lib/ribit/ribitdata_rb.html +112 -0
  528. data/doc/rdoc/files/lib/ribit/ribitlogger_rb.html +111 -0
  529. data/doc/rdoc/files/lib/ribit/webpage_rb.html +118 -0
  530. data/doc/rdoc/files/lib/ribit/xhtmldocument_rb.html +109 -0
  531. data/doc/rdoc/files/lib/ribit/xhtmltag_rb.html +109 -0
  532. data/doc/rdoc/fr_class_index.html +150 -0
  533. data/doc/rdoc/fr_file_index.html +53 -0
  534. data/doc/rdoc/fr_method_index.html +411 -0
  535. data/doc/rdoc/index.html +24 -0
  536. data/doc/rdoc/rdoc-style.css +208 -0
  537. data/doc/spec.txt +42 -0
  538. data/doc/test_run_25052005.txt +108 -0
  539. data/doc/testplan.txt +87 -0
  540. data/doc/www/index.html +5 -0
  541. data/lib/common/assert.rb +72 -0
  542. data/lib/common/cvs.rb +201 -0
  543. data/lib/common/datastorage.rb +265 -0
  544. data/lib/common/loggerfactory.rb +56 -0
  545. data/lib/common/pid.rb +44 -0
  546. data/lib/common/properties.rb +89 -0
  547. data/lib/common/url.rb +64 -0
  548. data/lib/log4r/outputter/extendedrollingfileoutputter.rb +73 -0
  549. data/lib/ribit/action.rb +1106 -0
  550. data/lib/ribit/actionelement.rb +152 -0
  551. data/lib/ribit/common.rb +34 -0
  552. data/lib/ribit/config.rb +123 -0
  553. data/lib/ribit/constants.rb +50 -0
  554. data/lib/ribit/contentparser.rb +1111 -0
  555. data/lib/ribit/contentstore.rb +406 -0
  556. data/lib/ribit/localization.rb +76 -0
  557. data/lib/ribit/main.rb +114 -0
  558. data/lib/ribit/ribit.rb +319 -0
  559. data/lib/ribit/ribitdata.rb +909 -0
  560. data/lib/ribit/ribitlogger.rb +192 -0
  561. data/lib/ribit/webpage.rb +802 -0
  562. data/lib/ribit/xhtmldocument.rb +148 -0
  563. data/lib/ribit/xhtmltag.rb +189 -0
  564. data/share/config/content/1/1.xml +6 -0
  565. data/share/config/content/1/2.xml +6 -0
  566. data/share/config/content/1/3.xml +6 -0
  567. data/share/config/content/1/4.xml +6 -0
  568. data/share/config/content/1/5.xml +6 -0
  569. data/share/config/content/1/category.xml +7 -0
  570. data/share/config/content/1/files/edit-category-template.html +59 -0
  571. data/share/config/content/1/files/edit-template.html +88 -0
  572. data/share/config/content/1/files/localization_en.properties +11 -0
  573. data/share/config/content/1/files/ribit.css +215 -0
  574. data/share/config/content/1/files/view-template.html +50 -0
  575. data/share/config/content/2/1.xml +19 -0
  576. data/share/config/content/2/2.xml +54 -0
  577. data/share/config/content/2/category.xml +5 -0
  578. data/share/config/content/3/1.xml +11 -0
  579. data/share/config/content/3/3.xml +17 -0
  580. data/share/config/content/3/4.xml +28 -0
  581. data/share/config/content/3/category.xml +5 -0
  582. data/share/config/content/categories.xml +12 -0
  583. data/share/config/ribitconfig.xml +48 -0
  584. data/share/config/ribitconfig_dev.xml +41 -0
  585. data/share/config/ribitconfig_local.xml +39 -0
  586. data/share/test/config/content/1/1.xml +6 -0
  587. data/share/test/config/content/1/2.xml +6 -0
  588. data/share/test/config/content/1/3.xml +6 -0
  589. data/share/test/config/content/1/4.xml +6 -0
  590. data/share/test/config/content/1/category.xml +4 -0
  591. data/share/test/config/content/1/files/edit-template.html +50 -0
  592. data/share/test/config/content/1/files/localization_en.properties +4 -0
  593. data/share/test/config/content/1/files/ribit.css +139 -0
  594. data/share/test/config/content/1/files/view-template.html +36 -0
  595. data/share/test/config/content/2/1.xml +16 -0
  596. data/share/test/config/content/2/2.xml +25 -0
  597. data/share/test/config/content/2/category.xml +4 -0
  598. data/share/test/config/content/categories.xml +11 -0
  599. data/share/test/config/content/ribitdata.xml +348 -0
  600. data/share/test/config/ribitconfig.xml +36 -0
  601. data/share/test/test1.xml +13 -0
  602. data/share/test/test2.xml +17 -0
  603. data/share/test/test3.xml +5 -0
  604. data/test/alltests.rb +35 -0
  605. data/test/common/allcommontests.rb +40 -0
  606. data/test/common/asserttest.rb +71 -0
  607. data/test/common/cvstest.rb +117 -0
  608. data/test/common/datastoragetest.rb +151 -0
  609. data/test/common/filepersistentstoragehandlertest.rb +105 -0
  610. data/test/common/propertiestest.rb +77 -0
  611. data/test/common/urltest.rb +70 -0
  612. data/test/log4r/outputter/alllog4routputtertests.rb +28 -0
  613. data/test/log4r/outputter/extendedrollingfileoutputtertest.rb +77 -0
  614. data/test/mock/mock.rb +147 -0
  615. data/test/ribit/actionadaptertest.rb +58 -0
  616. data/test/ribit/actionelementtest.rb +147 -0
  617. data/test/ribit/actionmanagertest.rb +55 -0
  618. data/test/ribit/allribittests.rb +62 -0
  619. data/test/ribit/categoryformactiontest.rb +153 -0
  620. data/test/ribit/configtest.rb +43 -0
  621. data/test/ribit/contentparsertest.rb +404 -0
  622. data/test/ribit/contentstorestub.rb +64 -0
  623. data/test/ribit/contentstoretest.rb +222 -0
  624. data/test/ribit/editcategorypagetest.rb +121 -0
  625. data/test/ribit/formactiontest.rb +367 -0
  626. data/test/ribit/localizationtest.rb +65 -0
  627. data/test/ribit/loggertest.rb +44 -0
  628. data/test/ribit/misc/allmisctests.rb +32 -0
  629. data/test/ribit/misc/amritatest.rb +24 -0
  630. data/test/ribit/misc/debugservlet.rb +63 -0
  631. data/test/ribit/misc/postsevlet.rb +36 -0
  632. data/test/ribit/misc/rexmlcdatatest.rb +17 -0
  633. data/test/ribit/misc/rexmldoctypetest.rb +20 -0
  634. data/test/ribit/misc/rexmlreadtest.rb +13 -0
  635. data/test/ribit/misc/rexmlwritetest.rb +28 -0
  636. data/test/ribit/misc/rubytest.rb +184 -0
  637. data/test/ribit/misc/suidtest.rb +21 -0
  638. data/test/ribit/misc/suite.rb +12 -0
  639. data/test/ribit/misc/wwwtest.rb +68 -0
  640. data/test/ribit/pagerequesttest.rb +74 -0
  641. data/test/ribit/ribitdatatest.rb +404 -0
  642. data/test/ribit/ribitservlettest.rb +94 -0
  643. data/test/ribit/testdata/ribittestdata.rb +49 -0
  644. data/test/ribit/testutil/ribitstub.rb +83 -0
  645. data/test/ribit/testutil/ribittestcase.rb +66 -0
  646. data/test/ribit/viewactiontest.rb +332 -0
  647. data/test/ribit/webpagetest.rb +531 -0
  648. data/test/ribit/xhtmldocumenttest.rb +263 -0
  649. data/test/ribit/xhtmltagtest.rb +84 -0
  650. metadata +837 -0
@@ -0,0 +1,56 @@
1
+ #--
2
+ # Copyright (C) 2004-2005 Tero Vuorela
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU General Public License as published by the Free
6
+ # Software Foundation; either version 2 of the License, or (at your option)
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ # more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along with
15
+ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
+ # Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #++
18
+
19
+ require 'logger'
20
+
21
+ ##
22
+ #
23
+ class LoggerFactory
24
+ # singleton
25
+ @@instance = nil
26
+
27
+ #
28
+ def LoggerFactory.get_logger( loggerName )
29
+ if ( @@instance == nil )
30
+ create_default_instance
31
+ end
32
+
33
+ return @@instance.get_logger( loggerName )
34
+ end
35
+
36
+ #
37
+ def LoggerFactory.set_instance( newLogFactory )
38
+ @@instance = newLogFactory
39
+ end
40
+
41
+ private
42
+ #
43
+ def LoggerFactory.create_default_instance
44
+ @@instance = DefaultLoggerFactory.new
45
+ end
46
+ end
47
+
48
+ ##
49
+ #
50
+ class DefaultLoggerFactory
51
+ # Returns a new logger named 'loggerName'
52
+ def get_logger( loggerName )
53
+ # by default return
54
+ return Logger.new( STDOUT )
55
+ end
56
+ end
@@ -0,0 +1,44 @@
1
+ #--
2
+ # Copyright (C) 2004-2005 Tero Vuorela
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU General Public License as published by the Free
6
+ # Software Foundation; either version 2 of the License, or (at your option)
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ # more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along with
15
+ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
+ # Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #++
18
+
19
+ ##
20
+ #
21
+ class Pid
22
+ attr_reader :pid
23
+
24
+ #
25
+ def initialize
26
+ @pid = Process.pid
27
+ end
28
+
29
+ #
30
+ def write_to_file( fileName )
31
+ if ( fileName == nil )
32
+ raise IOException( 'File name is nil' )
33
+ end
34
+
35
+ pidHandle = File.new( fileName, 'w' )
36
+ pidHandle.print( pid )
37
+ pidHandle.close
38
+ end
39
+
40
+ #
41
+ def to_s
42
+ @pid.to_s
43
+ end
44
+ end
@@ -0,0 +1,89 @@
1
+ #--
2
+ # Copyright (C) 2004-2005 Tero Vuorela
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU General Public License as published by the Free
6
+ # Software Foundation; either version 2 of the License, or (at your option)
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ # more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along with
15
+ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
+ # Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #++
18
+
19
+ ##
20
+ #
21
+ class Properties
22
+
23
+ #
24
+ def initialize
25
+ @props = Hash.new
26
+ end
27
+
28
+ #
29
+ def get( key )
30
+ return @props[key]
31
+ end
32
+
33
+ #
34
+ def put( key, value )
35
+ @props[key] = value
36
+ end
37
+
38
+ #
39
+ def load( inputStream )
40
+ inputStream.each_line do |line|
41
+ if ( /^[ \t]*#/.match( line ) != nil or /^[ \t]*$/.match( line ) != nil )
42
+ # it is a comment line or empty line => skip it
43
+ else
44
+ match = /([^=]+)=(.*)/.match( line )
45
+ key = match[1].strip
46
+ value = match[2].strip
47
+ @props[key] = value
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ ##
55
+ #
56
+ class PropertyList
57
+
58
+ #
59
+ def initialize
60
+ @keys = Array.new
61
+ @values = Array.new
62
+ end
63
+
64
+ #
65
+ def put( key, value )
66
+ if ( get( key ) != nil )
67
+ raise 'Key is already used'
68
+ end
69
+
70
+ @keys.push( key )
71
+ @values.push( value )
72
+ end
73
+
74
+ #
75
+ def get( key )
76
+ i = @keys.index( key )
77
+ if ( i == nil )
78
+ return nil
79
+ end
80
+
81
+ return @values[i]
82
+ end
83
+
84
+ # Keeps the order where key-value pairs were inserted
85
+ def keys
86
+ return @keys
87
+ end
88
+
89
+ end
@@ -0,0 +1,64 @@
1
+ #--
2
+ # Copyright (C) 2004-2005 Tero Vuorela
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU General Public License as published by the Free
6
+ # Software Foundation; either version 2 of the License, or (at your option)
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ # more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along with
15
+ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
+ # Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #++
18
+
19
+ require 'uri'
20
+
21
+ ##
22
+ #
23
+ class URL
24
+ attr_reader :pid
25
+
26
+ #
27
+ def initialize( protocol, address, path )
28
+ @protocol = protocol
29
+ @address = address
30
+ @path = path
31
+
32
+ # params are stored to list so that we can keep order they have been added
33
+ @paramNames = []
34
+ @paramValuesByName = {}
35
+ end
36
+
37
+ #
38
+ def add_param( name, value )
39
+ @paramNames.push( name )
40
+ @paramValuesByName[name] = value
41
+ end
42
+
43
+ #
44
+ def to_s
45
+ url = ''
46
+ url << @protocol + '://' if @protocol != nil
47
+ url << @address if @address != nil
48
+ url << '/' if not url.empty?
49
+
50
+ # path always exists
51
+ url << @path
52
+ url << '?'
53
+
54
+ @paramNames.each do |name|
55
+ value = @paramValuesByName[name]
56
+ value = URI.escape( value )
57
+ url << "#{name}=#{value}"
58
+ url << '&'
59
+ end
60
+
61
+ # last char away (? or & character)
62
+ url.chop
63
+ end
64
+ end
@@ -0,0 +1,73 @@
1
+ #--
2
+ # Copyright (C) 2004-2005 Tero Vuorela
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU General Public License as published by the Free
6
+ # Software Foundation; either version 2 of the License, or (at your option)
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ # more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along with
15
+ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
+ # Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #++
18
+
19
+ require 'rubygems'
20
+ require_gem 'log4r'
21
+ require 'log4r/logger'
22
+ require 'log4r/outputter/rollingfileoutputter'
23
+ require 'date'
24
+
25
+ module Log4r
26
+ ##
27
+ # ExtendedRollingFileOutputter - subclass of RollingFileOutputter that takes
28
+ # date pattern what is used to build the log file name.
29
+ #
30
+ # Example: Default pattern '-%d%m%Y-%H%H%S' creates log files like
31
+ # myapp-01082004-123150.log.
32
+ #
33
+ # Additional hash arguments are:
34
+ #
35
+ # [<tt>:datepattern</tt>] Pattern used in build log file name
36
+ #
37
+ class ExtendedRollingFileOutputter < Log4r::RollingFileOutputter
38
+
39
+ #
40
+ def initialize( _name, hash={} )
41
+
42
+ if ( hash['datepattern'] != nil )
43
+ @datePattern = hash['datepattern']
44
+ else
45
+ @datePattern = '-%d%m%Y-%H%H%S'
46
+ end
47
+
48
+ super( _name, hash )
49
+ end
50
+
51
+ # construct a new filename from the count and baseFileName
52
+ def makeNewFilename( counter=nil )
53
+ pad = Time.now.strftime( @datePattern )
54
+ pad << '-' + counter.to_s if counter != nil
55
+ newbase = @baseFilename.sub(/(\.\w*)$/, pad + '\1')
56
+ @filename = File.join(File.dirname(@filename), newbase)
57
+
58
+ if ( File.exist?( @filename ) )
59
+ puts "exists " + @filename
60
+ counter = 0 unless counter != nil
61
+ counter = counter + 1
62
+
63
+ return makeNewFilename( counter )
64
+ end
65
+
66
+ Logger.log_internal {"File #{@filename} created"}
67
+
68
+ return @filename
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,1106 @@
1
+ #--
2
+ # Copyright (C) 2004-2005 Tero Vuorela
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU General Public License as published by the Free
6
+ # Software Foundation; either version 2 of the License, or (at your option)
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ # more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along with
15
+ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
+ # Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #++
18
+
19
+ require 'ribit/common'
20
+ require 'ribit/localization'
21
+ require 'ribit/webpage'
22
+ require 'ribit/xhtmltag'
23
+ require 'ribit/ribitdata'
24
+ require 'ribit/constants'
25
+ require 'common/assert'
26
+ require 'common/url'
27
+ require 'rexml/document'
28
+
29
+ #
30
+ class WebAction
31
+ attr_reader :id
32
+
33
+ #
34
+ def run( pageRequest, pageResponse )
35
+ @pageRequest = pageRequest
36
+ end
37
+
38
+ #
39
+ def add_headers( page )
40
+ baseUrlTag = BaseTag.new( @pageRequest.get_base_url )
41
+ page.add_head_element( baseUrlTag )
42
+ end
43
+
44
+ end
45
+
46
+ #
47
+ class ActionManager
48
+
49
+ #
50
+ def initialize()
51
+ @actions = Hash.new
52
+ @defaultAction = nil
53
+ end
54
+
55
+ #
56
+ def register_action( webAction )
57
+ if ( @actions[webAction.id] != nil )
58
+ raise "ID #{webAction.id} already registered"
59
+ end
60
+
61
+ @actions[webAction.id] = webAction
62
+ end
63
+
64
+ #
65
+ def set_default_action( id )
66
+ if ( @actions[id] == nil )
67
+ raise "No action registered for ID=#{id}"
68
+ end
69
+
70
+ @defaultAction = @actions[id]
71
+ end
72
+
73
+ # Returns default action if action not found
74
+ def get_action( id )
75
+ if ( id == nil )
76
+ # return default action
77
+ return @defaultAction
78
+ end
79
+
80
+ return @actions[id]
81
+ end
82
+
83
+ end
84
+
85
+ ##
86
+ #
87
+ class CompositeAction < WebAction
88
+
89
+ #
90
+ def initialize( id )
91
+ @id = id
92
+ @actions = Hash.new
93
+ end
94
+
95
+ #
96
+ def add_action( webAction )
97
+ @actions[webAction.id] = webAction
98
+ end
99
+
100
+ #
101
+ def run( pageRequest, pageResponse )
102
+ super( pageRequest, pageResponse )
103
+
104
+ actionID = get_child_action_id( pageRequest )
105
+ @actions[actionID].run( pageRequest, pageResponse )
106
+ end
107
+
108
+ #
109
+ def get_child_action_id( pageRequest )
110
+ raise 'should be implemented in child classes'
111
+ end
112
+ end
113
+
114
+ ##
115
+ #
116
+ class FormAction < CompositeAction
117
+ ID = 'form'
118
+ #
119
+ def initialize( ribitData )
120
+ super( ID )
121
+ end
122
+
123
+ #
124
+ def get_child_action_id( pageRequest )
125
+ query = pageRequest.get_query_data
126
+
127
+ # Only that name has a value that is attached
128
+ # to pressed button
129
+
130
+ @actions.each_key do |key|
131
+ if ( query[key] != nil )
132
+ return key
133
+ end
134
+ end
135
+
136
+ # no action found
137
+ return nil
138
+ end
139
+
140
+ end
141
+
142
+ ##
143
+ #
144
+ class CategoryFormAction < CompositeAction
145
+ ID = 'category-form'
146
+ #
147
+ def initialize( ribitData )
148
+ super( ID )
149
+ end
150
+
151
+ #
152
+ def get_child_action_id( pageRequest )
153
+ query = pageRequest.get_query_data
154
+
155
+ # Only that name has a value that is attached
156
+ # to pressed button
157
+
158
+ @actions.each_key do |key|
159
+ if ( query[key] != nil )
160
+ return key
161
+ end
162
+ end
163
+
164
+ # no action found
165
+ return nil
166
+ end
167
+
168
+ end
169
+
170
+ ##
171
+ #
172
+ class SaveAction < WebAction
173
+ include Assert
174
+ include Localization
175
+
176
+ #
177
+ def initialize( ribitData, ribitConfig, pageCache )
178
+ assert_not_nil( ribitData, 'RibitData is nil' )
179
+
180
+ @id = 'form:save'
181
+ @ribitData = ribitData
182
+ @ribitConfig = ribitConfig
183
+ @pageCache = pageCache
184
+ @logger = RibitLogger.new( SaveAction )
185
+ end
186
+
187
+ #
188
+ def run( pageRequest, pageResponse )
189
+ super( pageRequest, pageResponse )
190
+
191
+ pageID = pageRequest.get_requested_page_id
192
+ message = ''
193
+
194
+ if ( pageID == nil )
195
+ raise RibitException, 'No page ID defined for save action', caller
196
+ end
197
+
198
+ query = pageRequest.get_query_data
199
+ data = query[Constants::PAGE_DATA_FORM_PARAM_NAME]
200
+ name = query[Constants::PAGE_NAME_FORM_PARAM_NAME]
201
+
202
+ if ( pageID == Constants::NEW_PAGE_ID )
203
+ categoryName = pageRequest.get_request_param( Constants::CATEGORY_FORM_PARAM_NAME )
204
+ category = @ribitData.get_category_by_full_name( categoryName )
205
+
206
+ if ( category == nil )
207
+ @logger.debug( "Category #{categoryName} doesn't exists => will be created" )
208
+ # might be short reference or totally new (several levels too)
209
+ # no easy way to make difference => assuming always full ref
210
+ # => use of :: at the beginning for toplevel
211
+
212
+ categoryParts = categoryName.split( '::' )
213
+ if ( categoryParts[0] == '' )
214
+ categoryParts.delete_at( 0 )
215
+ end
216
+ cat = ''
217
+ parentCategory = nil
218
+ categoryParts.each do |part|
219
+ cat << part
220
+ @logger.debug( "Checking category #{cat} existance" )
221
+ tmpCategory = @ribitData.get_category_by_full_name( cat )
222
+ if ( tmpCategory == nil )
223
+ @logger.debug( "Creating category #{cat}" )
224
+ tmpCategory = @ribitData.create_category( part, '', parentCategory )
225
+ end
226
+ cat << '::'
227
+ parentCategory = tmpCategory
228
+ end
229
+
230
+ # now every category should have been created and
231
+ # parentCategory contains the last one = the current category
232
+ category = parentCategory
233
+ end
234
+
235
+ # create a new page
236
+ newPageID = category.get_next_free_page_id
237
+ @logger.debug( "creating a new page for ID=#{newPageID}" )
238
+
239
+ # category should already exists in RibitData => page gets recorded
240
+ page = RibitData::Page.new( newPageID, name, category )
241
+ page.data = data
242
+
243
+ message = get_localized( ACTION_NEW_PAGE_OK )
244
+ pageID = page.full_id
245
+
246
+ # NOTE: this is a new page
247
+ # => categories and all pages linking to this have changed
248
+ # => delete all pages
249
+
250
+ # TODO: later we could know where pages are referenced
251
+
252
+ if ( @pageCache != nil )
253
+ @pageCache.delete_all
254
+ end
255
+
256
+ # check that there exists a page
257
+ elsif ( @ribitData.get_page_by_id( pageID ) == nil )
258
+ raise RibitException, "No page for ID=#{pageID}", caller
259
+ else
260
+ @logger.debug( "saving page for ID=#{pageID}" )
261
+
262
+ page = @ribitData.get_page_by_id( pageID )
263
+ page.data = data
264
+
265
+ # if name has changed then contents of categories page will change
266
+ if ( page.name != name and @pageCache != nil )
267
+ @pageCache.delete( ViewCategoriesAction::PAGE_CACHE_ID )
268
+ end
269
+
270
+ page.name = name
271
+
272
+ message = get_localized( ACTION_SAVE_OK )
273
+ @pageCache.delete( page.full_id ) unless @pageCache == nil
274
+ end
275
+
276
+ @ribitData.save_page( page )
277
+
278
+ # show the saved page
279
+ page = TextPage.new( @ribitData, page, @ribitConfig )
280
+ page.set_message( message )
281
+
282
+ # set the base url for whole page (all links are relative to this)
283
+ add_headers( page )
284
+
285
+ # finally build the page
286
+ page.output_page( pageResponse )
287
+
288
+ end
289
+
290
+ end
291
+
292
+ ##
293
+ #
294
+ class SaveCategoryAction < WebAction
295
+ include Assert
296
+ include Localization
297
+
298
+ #
299
+ def initialize( ribitData, ribitConfig, pageCache )
300
+ assert_not_nil( ribitData, 'RibitData is nil' )
301
+
302
+ @id = 'form:save'
303
+ @ribitData = ribitData
304
+ @ribitConfig = ribitConfig
305
+ @logger = RibitLogger.new( SaveAction )
306
+ @pageCache = pageCache
307
+ end
308
+
309
+ #
310
+ def run( pageRequest, pageResponse )
311
+ super( pageRequest, pageResponse )
312
+
313
+ catID = pageRequest.get_request_param( Constants::CATEGORY_ID_REQUEST_PARAM_NAME )
314
+
315
+ if ( catID == nil )
316
+ raise RibitException, 'No category ID defined for EditCategoryAction', caller
317
+ end
318
+
319
+ category = @ribitData.get_category_by_id( catID )
320
+ if ( category == nil )
321
+ raise RibitException, "No category for ID=#{catID}", caller
322
+ end
323
+ message = ''
324
+
325
+ query = pageRequest.get_query_data
326
+ categoryName = query[Constants::CATEGORY_NAME_FORM_PARAM_NAME]
327
+ mainPageID = query[Constants::CATEGORY_MAIN_PAGE_ID_FORM_PARAM_NAME]
328
+ parentCategoryID = query[Constants::CATEGORY_PARENT_ID_FORM_PARAM_NAME]
329
+ @logger.debug( "New properties for category #{category.id}: name=#{categoryName}, mainPageID=#{mainPageID}, parentCategoryID=#{parentCategoryID}" )
330
+
331
+ categoryDataChanged = false
332
+
333
+ if ( categoryName != category.name )
334
+ @logger.debug( "Changing category name from #{category.name} to #{categoryName}" )
335
+ category.name = categoryName
336
+ categoryDataChanged = true
337
+ end
338
+ @logger.debug( "Current mainPageID=#{category.get_main_page_id}" )
339
+ if ( mainPageID != category.get_main_page_id )
340
+ @logger.debug( "Changing main page id from #{category.get_main_page_id} to #{mainPageID}" )
341
+ category.set_main_page_id( mainPageID )
342
+ categoryDataChanged = true
343
+ end
344
+
345
+ # in form special string marked nil ie. no parent
346
+ parentCategoryID = nil if parentCategoryID == Constants::CATEGORY_NO_PARENT_FORM_VALUE
347
+ currentParentCategoryID = nil
348
+ currentParentCategoryID = category.get_parent_category.id unless category.toplevel_category?
349
+
350
+ categoriesHierarchyChanged = false
351
+ if ( parentCategoryID != currentParentCategoryID )
352
+ @logger.debug( "Changing parent category id to #{parentCategoryID}" )
353
+ category.set_parent_category( @ribitData.get_category_by_id( parentCategoryID ) )
354
+ categoriesHierarchyChanged = true
355
+ end
356
+
357
+ # TODO: new category feature is not yet implemented
358
+
359
+ @logger.debug( "saving category for ID=#{catID}" )
360
+
361
+ message = get_localized( ACTION_SAVE_CATEGORY_OK )
362
+
363
+ # saving data depending on what changed
364
+ if ( categoryDataChanged )
365
+ @ribitData.save_category( category )
366
+
367
+ # delete all child pages from cache, their content might have been changed
368
+ if ( @pageCache != nil )
369
+ category.get_pages.each do |childPage|
370
+ @pageCache.delete( childPage.full_id )
371
+ end
372
+
373
+ @pageCache.delete( ViewCategoriesAction::PAGE_CACHE_ID )
374
+ end
375
+ end
376
+
377
+ if ( categoriesHierarchyChanged )
378
+ @ribitData.save_categories_hierarchy
379
+ @pageCache.delete_all unless @pageCache == nil
380
+ end
381
+
382
+ # show the categories page
383
+ page = CategoriesPage.new( @ribitData, @ribitConfig )
384
+ page.set_message( message )
385
+
386
+ # set the base url for whole page (all links are relative to this)
387
+ add_headers( page )
388
+
389
+ page.output_page( pageResponse )
390
+
391
+ end
392
+
393
+ end
394
+
395
+ ##
396
+ #
397
+ class ViewAction < WebAction
398
+ include Assert
399
+
400
+ ID = 'view'
401
+
402
+ def initialize( ribitData, ribitConfig, pageCache )
403
+ assert_not_nil( ribitData, 'RibitData is nil' )
404
+ assert_not_nil( ribitConfig )
405
+
406
+ @id = ID
407
+ @ribitData = ribitData
408
+ @ribitConfig = ribitConfig
409
+ @pageCache = pageCache
410
+ @logger = RibitLogger.new( ViewAction )
411
+ end
412
+
413
+ #
414
+ def decorate_page( page )
415
+ # set the base url for whole page (all links are relative to this)
416
+ add_headers( page )
417
+ return false
418
+ end
419
+
420
+ #
421
+ def run( pageRequest, pageResponse )
422
+ super( pageRequest, pageResponse )
423
+
424
+ # get page id and show the page
425
+ pageID = get_page_id( pageRequest )
426
+
427
+ if ( pageID == nil )
428
+ raise "No page ID defined"
429
+ end
430
+
431
+ page = @ribitData.get_page_by_id( pageID )
432
+ # check that there exists a page
433
+ if ( page == nil )
434
+ raise "No page for ID=#{pageID}"
435
+ end
436
+
437
+ # check first from cache
438
+ cachedPage = get_cached_page( page.full_id )
439
+
440
+ if ( cachedPage != nil )
441
+ @logger.debug( 'Found page from cache for pageId=' + page.full_id )
442
+
443
+ lastModified = pageRequest.get_header_field( 'If-Modified-Since' )
444
+ if ( lastModified != nil )
445
+ @logger.debug( "Found If-Modified-Since field from HTTP headers" )
446
+ time = Time.httpdate( lastModified )
447
+
448
+ # NOTE: MODIFIED time contains also fraction of seconds but httpdate
449
+ # doesn't have them => we have to compare full seconds
450
+ if ( cachedPage.is_time_same_or_after( lastModified ) )
451
+ @logger.debug( "Cached page is up to date" )
452
+ pageResponse.status = 304
453
+ return
454
+ end
455
+ end
456
+
457
+ pageResponse.set_body( cachedPage.data )
458
+ pageResponse.set_content_type( cachedPage.contentType )
459
+
460
+ pageResponse.set_header_field( 'Cache-Control', 'public, must-revalidate, proxy-revalidate' )
461
+ pageResponse.set_header_field( 'Last-Modified', cachedPage.lastModfiedHttpdate )
462
+
463
+ else
464
+ @logger.debug( "Building page for ID=#{page.full_id}" )
465
+ textPage = TextPage.new( @ribitData, page, @ribitConfig )
466
+ messagesInserted = decorate_page( textPage )
467
+
468
+ textPage.output_page( pageResponse )
469
+
470
+ # store page to cache if there wasn't any messages
471
+ if ( @pageCache != nil and not messagesInserted )
472
+ # we can safely insert data to cache
473
+ @logger.debug( "Inserting page #{page.full_id} data to cache" )
474
+
475
+ cachedPage = CachedPage.new( pageResponse.get_body, pageResponse.get_content_type )
476
+ @pageCache.add( page.full_id, cachedPage )
477
+
478
+ pageResponse.set_header_field( 'Cache-Control', 'public, must-revalidate, proxy-revalidate' )
479
+ pageResponse.set_header_field( 'Last-Modified', cachedPage.lastModfiedHttpdate )
480
+ end
481
+ end
482
+ end
483
+
484
+ #
485
+ def get_page_id( pageRequest )
486
+ return pageRequest.get_requested_page_id
487
+ end
488
+
489
+ #
490
+ def get_cached_page( pageFullId )
491
+ if ( @pageCache == nil )
492
+ return nil
493
+ end
494
+
495
+ return @pageCache.get( pageFullId )
496
+ end
497
+
498
+
499
+ end
500
+
501
+ ##
502
+ #
503
+ class CachedPage
504
+ attr_reader :data, :contentType
505
+
506
+ #
507
+ def initialize( data, contentType )
508
+ @data = data
509
+ @contentType = contentType
510
+ @lastModified = Time.now
511
+ end
512
+
513
+ #
514
+ def is_time_same_or_after( lastModifiedHttpDate )
515
+
516
+ time = Time.httpdate( lastModifiedHttpDate )
517
+
518
+ # NOTE: @lastModified time contains also fraction of seconds but httpdate
519
+ # doesn't have them => we have to compare full seconds
520
+ if ( ( time.to_i <=> @lastModified.to_i ) >= 0 )
521
+ return true
522
+ end
523
+
524
+ return false
525
+ end
526
+
527
+ #
528
+ def lastModfiedHttpdate
529
+ @lastModified.httpdate
530
+ end
531
+ end
532
+
533
+
534
+ ##
535
+ # This action is the default action that is responsible for creating
536
+ # a page when no specific action is defined by request URL. The action
537
+ # views the main page defined in Ribit configuration file.
538
+ class DefaultAction < ViewAction
539
+ include Localization
540
+
541
+ #
542
+ def initialize( ribitData, ribitConfig, pageCache )
543
+ super( ribitData, ribitConfig, pageCache )
544
+ @id = 'default'
545
+ @logger = RibitLogger.new( DefaultAction )
546
+ @ribitData = ribitData
547
+ @defaultPageID = nil
548
+
549
+ end
550
+
551
+ #
552
+ def run( pageRequest, pageResponse )
553
+ begin
554
+ super( pageRequest, pageResponse )
555
+ rescue RibitException => exception
556
+ @logger.error( 'Showing default page failed' )
557
+ @logger.error( format_exception( exception ) )
558
+
559
+ # probable reason was that default page was not found
560
+ # => show categories page
561
+ # => if that throws error too then upper level takes care of it
562
+
563
+ # TODO: caching of this page ?? should reuse view categories action ??
564
+ @logger.info( 'Because default page failed showing Categories page' );
565
+
566
+ page = CategoriesPage.new( @ribitData, @ribitConfig )
567
+ page.set_message( get_localized( ACTION_DEFAULT_PAGE_FAILED, { 'message' => exception.message } ) )
568
+ decorate_page( page )
569
+
570
+ page.output_page( pageResponse )
571
+ end
572
+ end
573
+
574
+ #
575
+ def get_page_id( pageRequest )
576
+ if ( @defaultPageID == nil )
577
+ mainPageRef = @ribitConfig[RibitConfig::MAIN_PAGE]
578
+
579
+ # first we try by name
580
+ page = @ribitData.get_page_by_full_name( mainPageRef )
581
+
582
+ if ( page == nil )
583
+ page = @ribitData.get_page_by_id( mainPageRef )
584
+ end
585
+
586
+ if ( page == nil )
587
+ raise RibitException, "No default page found: #{mainPageRef}", caller
588
+ end
589
+
590
+ @defaultPageID = page.full_id
591
+
592
+ @logger.debug(
593
+ "The default page is: name=#{page.full_name}, pageID=#{@defaultPageID}" )
594
+ end
595
+
596
+ return @defaultPageID
597
+ end
598
+
599
+ end
600
+
601
+
602
+ #
603
+ class EditAction < WebAction
604
+ include Assert
605
+ include Localization
606
+
607
+ ID = 'edit'
608
+
609
+ def initialize( ribitData, ribitConfig )
610
+ assert_not_nil( ribitData, 'RibitData is nil' )
611
+ assert_not_nil( ribitConfig, 'RibitConfig' )
612
+
613
+ @id = ID
614
+ @ribitData = ribitData
615
+ @ribitConfig = ribitConfig
616
+ @logger = RibitLogger.new( EditAction )
617
+ end
618
+
619
+ #
620
+ def run( pageRequest, pageResponse )
621
+ super( pageRequest, pageResponse )
622
+
623
+ # get page id and show the edit page
624
+ pageID = pageRequest.get_requested_page_id
625
+
626
+ if ( pageID == nil )
627
+ raise RibitException, 'No page ID defined for EditAction', caller
628
+ end
629
+
630
+ if ( pageID == Constants::NEW_PAGE_ID )
631
+ # we don't have data in ribitData, so we need add necessary stuff form
632
+ # - name
633
+ # - category
634
+ @logger.debug( 'building edit page for non-existent page' )
635
+
636
+ # build empty page
637
+ previousPageID = pageRequest.get_request_param( Constants::PREV_REQUEST_PARAM_NAME )
638
+ page = EditPage.new( @ribitData, pageID, previousPageID, @ribitConfig )
639
+
640
+ # add name + category info
641
+ name = pageRequest.get_request_param( Constants::PAGE_NAME_REQUEST_PARAM_NAME )
642
+ if ( name == nil )
643
+ raise RibitException, 'No \'name\' defined in request', caller
644
+ end
645
+
646
+ category = pageRequest.get_request_param( Constants::CATEGORY_REQUEST_PARAM_NAME )
647
+ if ( category == nil )
648
+ raise RibitException, 'No \'category\' defined in request', caller
649
+ end
650
+
651
+ page.add_form_action_params( Constants::PAGE_NAME_REQUEST_PARAM_NAME, name );
652
+ page.add_form_action_params( Constants::CATEGORY_REQUEST_PARAM_NAME, category );
653
+
654
+ if ( @ribitData.get_category_by_full_name( category ) == nil )
655
+ page.set_message( get_localized( ACTION_CATEGORY_CREATION_NOTICE, {'category' => category } ) )
656
+ end
657
+
658
+ elsif ( @ribitData.get_page_by_id( pageID ) == nil )
659
+ raise RibitException, "No page for ID=#{pageID}", caller
660
+ else
661
+ @logger.debug( "building edit page for ID=#{pageID}" )
662
+ page = EditPage.new( @ribitData, pageID, pageID, @ribitConfig )
663
+ end
664
+
665
+ add_headers( page )
666
+ page.output_page( pageResponse )
667
+
668
+ end
669
+
670
+ end
671
+
672
+ ##
673
+ #
674
+ class CancelAction < ViewAction
675
+ include Assert
676
+ include Localization
677
+
678
+ def initialize( ribitData, ribitConfig )
679
+ # cancel contains message => can't cache the page
680
+ super( ribitData, ribitConfig, nil )
681
+
682
+ @id = 'form:cancel'
683
+ @logger = RibitLogger.new( CancelAction )
684
+ end
685
+
686
+ #
687
+ def decorate_page( page )
688
+ super( page )
689
+ page.set_message( get_localized( ACTION_EDIT_CANCELED ) )
690
+ return true
691
+ end
692
+
693
+ #
694
+ def get_page_id( pageRequest )
695
+ query = pageRequest.get_query_data
696
+ prevPageID = query[Constants::PREV_FORM_PARAM_NAME]
697
+ assert_not_nil( prevPageID, "No #{Constants::PREV_FORM_PARAM_NAME} found from form data" )
698
+ return prevPageID
699
+ end
700
+
701
+ end
702
+
703
+
704
+ ##
705
+ #
706
+ class StyleSheetAction < ViewAction
707
+ include Assert
708
+ # CSS is not modified (not possible currently, so last modified time is time of start up
709
+ MODIFIED = Time.new
710
+
711
+ def initialize( ribitData )
712
+ assert_not_nil( ribitData, 'RibitData is nil' )
713
+
714
+ @id = 'stylesheet'
715
+ @ribitData = ribitData
716
+ @logger = RibitLogger.new( StyleSheetAction )
717
+ cssPage = ribitData.get_page_by_full_name( "core::css" )
718
+
719
+ if ( cssPage != nil )
720
+ @cssPageData = cssPage.data
721
+ else
722
+ # page not found, it is not mandatory
723
+ @logger.warn( 'No CSS page found by name core::css' )
724
+ @cssPageData = '# No CSS page found by name core::css'
725
+ end
726
+ end
727
+
728
+ #
729
+ def run( pageRequest, pageResponse )
730
+ lastModified = pageRequest.get_header_field( 'If-Modified-Since' )
731
+ if ( lastModified != nil )
732
+ @logger.debug( "Found If-Modified-Since field from HTTP headers" )
733
+ time = Time.httpdate( lastModified )
734
+
735
+ # NOTE: MODIFIED time contains also fraction of seconds but httpdate
736
+ # doesn't have them => we have to compare full seconds
737
+ if ( ( time.to_i <=> MODIFIED.to_i ) >= 0 )
738
+ @logger.debug( "Cached copy is up to date" )
739
+ pageResponse.status = 304
740
+ return
741
+ end
742
+ end
743
+
744
+ page = RawPage.new( @cssPageData, 'text/css' )
745
+ page.output_page( pageResponse )
746
+
747
+ pageResponse.set_header_field( 'Cache-Control', 'public, must-revalidate, proxy-revalidate' )
748
+ pageResponse.set_header_field( 'Last-Modified', MODIFIED.httpdate )
749
+ end
750
+
751
+ end
752
+
753
+ ##
754
+ #
755
+ class ViewCategoriesAction < WebAction
756
+ include Assert
757
+
758
+ ID = 'categories'
759
+ PAGE_CACHE_ID = 'categories'
760
+
761
+ def initialize( ribitData, ribitConfig, pageCache )
762
+ assert_not_nil( ribitData, 'RibitData is nil' )
763
+ assert_not_nil( ribitConfig )
764
+
765
+ @id = ID
766
+ @ribitData = ribitData
767
+ @ribitConfig = ribitConfig
768
+ @pageCache = pageCache
769
+ @logger = RibitLogger.new( ViewCategoriesAction )
770
+ end
771
+
772
+ #
773
+ def decorate_page( page )
774
+ # set baseUrl etc.
775
+ add_headers( page )
776
+ return false
777
+ end
778
+
779
+ #
780
+ def run( pageRequest, pageResponse )
781
+ super( pageRequest, pageResponse )
782
+
783
+ cachedPage = get_cached_page
784
+ if ( cachedPage != nil )
785
+ @logger.debug( 'Found categories page from cache' )
786
+
787
+ lastModified = pageRequest.get_header_field( 'If-Modified-Since' )
788
+ if ( lastModified != nil )
789
+ @logger.debug( "Found If-Modified-Since field from HTTP headers" )
790
+ time = Time.httpdate( lastModified )
791
+
792
+ # NOTE: MODIFIED time contains also fraction of seconds but httpdate
793
+ # doesn't have them => we have to compare full seconds
794
+ if ( cachedPage.is_time_same_or_after( lastModified ) )
795
+ @logger.debug( "Cached page is up to date" )
796
+ pageResponse.status = 304
797
+ return
798
+ end
799
+ end
800
+
801
+ pageResponse.set_body( cachedPage.data )
802
+ pageResponse.set_content_type( cachedPage.contentType )
803
+
804
+ pageResponse.set_header_field( 'Cache-Control', 'public, must-revalidate, proxy-revalidate' )
805
+ pageResponse.set_header_field( 'Last-Modified', cachedPage.lastModfiedHttpdate )
806
+
807
+ else
808
+ page = CategoriesPage.new( @ribitData, @ribitConfig )
809
+ decorate_page( page )
810
+
811
+ page.output_page( pageResponse )
812
+
813
+ if ( @pageCache != nil )
814
+ # we can safely insert data to cache
815
+ @logger.debug( "Inserting categories page data to cache" )
816
+
817
+ cachedPage = CachedPage.new( pageResponse.get_body, pageResponse.get_content_type )
818
+ @pageCache.add( PAGE_CACHE_ID, cachedPage )
819
+
820
+ pageResponse.set_header_field( 'Cache-Control', 'public, must-revalidate, proxy-revalidate' )
821
+ pageResponse.set_header_field( 'Last-Modified', cachedPage.lastModfiedHttpdate )
822
+ end
823
+ end
824
+
825
+ end
826
+
827
+ #
828
+ def get_cached_page
829
+ if ( @pageCache == nil )
830
+ return nil
831
+ end
832
+
833
+ return @pageCache.get( PAGE_CACHE_ID )
834
+ end
835
+
836
+ end
837
+
838
+ ##
839
+ #
840
+ class CancelCategoryAction < ViewCategoriesAction
841
+ include Assert
842
+ include Localization
843
+
844
+ def initialize( ribitData, ribitConfig )
845
+ # never use page cache because there will be a message
846
+ super( ribitData, ribitConfig, nil )
847
+
848
+ @id = 'form:cancel'
849
+ @logger = RibitLogger.new( CancelAction )
850
+ end
851
+
852
+ #
853
+ def decorate_page( page )
854
+ super( page )
855
+ page.set_message( get_localized( ACTION_EDIT_CANCELED ) )
856
+ return true
857
+ end
858
+
859
+ end
860
+
861
+ #
862
+ class EditCategoryAction < WebAction
863
+ include Assert
864
+
865
+ ID = 'edit-category'
866
+
867
+ def initialize( ribitData, ribitConfig )
868
+ assert_not_nil( ribitData, 'RibitData is nil' )
869
+ assert_not_nil( ribitConfig, 'RibitConfig' )
870
+
871
+ @id = ID
872
+ @ribitData = ribitData
873
+ @ribitConfig = ribitConfig
874
+ @logger = RibitLogger.new( EditAction )
875
+ end
876
+
877
+ #
878
+ def run( pageRequest, pageResponse )
879
+ super( pageRequest, pageResponse )
880
+
881
+ catID = pageRequest.get_request_param( Constants::CATEGORY_ID_REQUEST_PARAM_NAME )
882
+
883
+ if ( catID == nil )
884
+ raise RibitException, 'No category ID defined for EditCategoryAction', caller
885
+ end
886
+
887
+ if ( catID == Constants::NEW_CATEGORY_ID )
888
+ # TODO: new category functionality is not yet supported
889
+ elsif ( @ribitData.get_category_by_id( catID ) == nil )
890
+ raise RibitException, "No category for ID=#{catID}", caller
891
+ else
892
+ @logger.debug( "building edit category page for ID=#{catID}" )
893
+ page = EditCategoryPage.new( @ribitData, catID, @ribitConfig )
894
+ end
895
+
896
+ # set the base url for whole page (all links are relative to this)
897
+ add_headers( page )
898
+
899
+ page.output_page( pageResponse )
900
+
901
+ end
902
+
903
+ end
904
+
905
+
906
+ ###########################################################################
907
+
908
+ ##
909
+ #
910
+ class ActionAdapter
911
+
912
+ #
913
+ def build_url( actionID, propertyList=nil, encode=true )
914
+ url = URL.new( nil, nil, "#{actionID}" )
915
+
916
+ if ( propertyList != nil )
917
+ propertyList.keys.each do |key|
918
+ url.add_param( key, propertyList.get( key ) )
919
+ end
920
+ end
921
+
922
+ return url
923
+ end
924
+
925
+ end
926
+
927
+
928
+ ##
929
+ #
930
+ class ViewActionAdapter < ActionAdapter
931
+
932
+ #
933
+ def initialize( targetID, text=nil )
934
+ # id might be number
935
+ @targetID = targetID.to_s
936
+ @linkText = text
937
+ end
938
+
939
+ #
940
+ def process( element )
941
+ # build url
942
+ element.attributes['href'] = get_url()
943
+
944
+ # change link text only if specified so
945
+ if ( @linkText != nil )
946
+ element.text = @linkText
947
+ end
948
+ end
949
+
950
+ #
951
+ def get_url
952
+ propertyList = PropertyList.new
953
+ propertyList.put( Constants::PAGE_ID_REQUEST_PARAM_NAME, @targetID )
954
+ return build_url( ViewAction::ID, propertyList )
955
+ end
956
+
957
+ #
958
+ def to_ele
959
+ element = REXML::Element.new( 'a' )
960
+ element.attributes['href'] = get_url()
961
+ element.text = @linkText
962
+ return element
963
+ end
964
+ end
965
+
966
+ ##
967
+ #
968
+ class ViewCategoriesActionAdapter < ActionAdapter
969
+
970
+ #
971
+ def initialize( text=nil )
972
+ @linkText = text
973
+ end
974
+
975
+ #
976
+ def process( element )
977
+ # build url
978
+ element.attributes['href'] = get_url()
979
+
980
+ # change link text only if specified so
981
+ if ( @linkText != nil )
982
+ element.text = @linkText
983
+ end
984
+ end
985
+
986
+ #
987
+ def get_url
988
+ return build_url( ViewCategoriesAction::ID )
989
+ end
990
+
991
+ end
992
+
993
+ ##
994
+ #
995
+ class EditActionAdapter < ViewActionAdapter
996
+
997
+ #
998
+ def get_url
999
+ propertyList = PropertyList.new
1000
+ propertyList.put( Constants::PAGE_ID_REQUEST_PARAM_NAME, @targetID )
1001
+ return build_url( EditAction::ID, propertyList )
1002
+ end
1003
+
1004
+ end
1005
+
1006
+ ##
1007
+ #
1008
+ class EditNewActionAdapter < ActionAdapter
1009
+
1010
+ #
1011
+ def initialize( category, name, prevPageID )
1012
+ @category = category
1013
+ @name = name
1014
+ @prevPageID = prevPageID
1015
+ end
1016
+
1017
+ #
1018
+ def get_url
1019
+ propertyList = PropertyList.new
1020
+ propertyList.put( Constants::PAGE_ID_REQUEST_PARAM_NAME, Constants::NEW_PAGE_ID )
1021
+ propertyList.put( Constants::CATEGORY_REQUEST_PARAM_NAME, @category )
1022
+ propertyList.put( Constants::PAGE_NAME_REQUEST_PARAM_NAME, @name )
1023
+ propertyList.put( Constants::PREV_REQUEST_PARAM_NAME, @prevPageID )
1024
+ return build_url( EditAction::ID, propertyList )
1025
+ end
1026
+
1027
+ end
1028
+
1029
+ ##
1030
+ #
1031
+ class EditCategoryActionAdapter < ViewActionAdapter
1032
+
1033
+ #
1034
+ def get_url
1035
+ propertyList = PropertyList.new
1036
+ propertyList.put( Constants::CATEGORY_ID_REQUEST_PARAM_NAME, @targetID )
1037
+ return build_url( EditCategoryAction::ID, propertyList )
1038
+ end
1039
+
1040
+ end
1041
+
1042
+ ##
1043
+ #
1044
+ class FormActionAdapter < ActionAdapter
1045
+
1046
+ #
1047
+ def initialize( pageID )
1048
+ @propertyList = PropertyList.new
1049
+ @propertyList.put( Constants::PAGE_ID_REQUEST_PARAM_NAME, pageID )
1050
+ end
1051
+
1052
+ #
1053
+ def add_param( key, value )
1054
+ @propertyList.put( key, value )
1055
+ end
1056
+
1057
+ #
1058
+ def get_url( encode=true )
1059
+ return build_url( FormAction::ID, @propertyList, encode )
1060
+ end
1061
+
1062
+ end
1063
+
1064
+ ##
1065
+ #
1066
+ class CategoryFormActionAdapter < ActionAdapter
1067
+
1068
+ #
1069
+ def initialize( pageID )
1070
+ @propertyList = PropertyList.new
1071
+ @propertyList.put( Constants::CATEGORY_ID_REQUEST_PARAM_NAME, pageID )
1072
+ end
1073
+
1074
+ #
1075
+ def add_param( key, value )
1076
+ @propertyList.put( key, value )
1077
+ end
1078
+
1079
+ #
1080
+ def get_url( encode=true )
1081
+ return build_url( CategoryFormAction::ID, @propertyList, encode )
1082
+ end
1083
+
1084
+ end
1085
+
1086
+ ##
1087
+ #
1088
+ class W3CValidatorLinkActionAdapter < ActionAdapter
1089
+ #
1090
+ def initialize( url )
1091
+ @url = url
1092
+
1093
+ @url = URI.escape( @url )
1094
+
1095
+ # replace some char that may confuse (url is value of one parameter, not many parameters)
1096
+ @url.gsub!( /&/, '%26' )
1097
+ @url.gsub!( /:/, '%3A' )
1098
+ @url.gsub!( /\//, '%2F' )
1099
+ @url.gsub!( /=/, '%3D' )
1100
+ end
1101
+
1102
+ #
1103
+ def get_url
1104
+ return "http://validator.w3.org/check?uri=#{@url}"
1105
+ end
1106
+ end