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.
- data/INSTALL +52 -0
- data/LICENSE +343 -0
- data/README +42 -0
- data/bin/ribit +26 -0
- data/bin/ribit-setup +153 -0
- data/bin/ribitd +18 -0
- data/doc/TODO.txt +207 -0
- data/doc/devdiary.txt +258 -0
- data/doc/diagrams/content-classes.dia +0 -0
- data/doc/diagrams/main-classes.dia +0 -0
- data/doc/diagrams/page-rendering-classes.dia +0 -0
- data/doc/diagrams/ribitservlet-classes.dia +0 -0
- data/doc/examples/xhtml-example.html +64 -0
- data/doc/notes.txt +7 -0
- data/doc/rdoc/classes/ActionAdapter.html +137 -0
- data/doc/rdoc/classes/ActionAdapter.src/M000160.html +26 -0
- data/doc/rdoc/classes/ActionElement.html +179 -0
- data/doc/rdoc/classes/ActionElement.src/M000204.html +19 -0
- data/doc/rdoc/classes/ActionElement.src/M000205.html +18 -0
- data/doc/rdoc/classes/ActionManager.html +187 -0
- data/doc/rdoc/classes/ActionManager.src/M000237.html +19 -0
- data/doc/rdoc/classes/ActionManager.src/M000238.html +22 -0
- data/doc/rdoc/classes/ActionManager.src/M000239.html +22 -0
- data/doc/rdoc/classes/ActionManager.src/M000240.html +23 -0
- data/doc/rdoc/classes/Assert.html +229 -0
- data/doc/rdoc/classes/Assert.src/M000369.html +20 -0
- data/doc/rdoc/classes/Assert.src/M000370.html +18 -0
- data/doc/rdoc/classes/Assert.src/M000371.html +20 -0
- data/doc/rdoc/classes/Assert.src/M000372.html +18 -0
- data/doc/rdoc/classes/Assert.src/M000373.html +20 -0
- data/doc/rdoc/classes/Assert.src/M000374.html +18 -0
- data/doc/rdoc/classes/Assert.src/M000375.html +22 -0
- data/doc/rdoc/classes/Assert/AssertionFailedException.html +117 -0
- data/doc/rdoc/classes/BaseTag.html +166 -0
- data/doc/rdoc/classes/BaseTag.src/M000049.html +20 -0
- data/doc/rdoc/classes/BoldContainer.html +139 -0
- data/doc/rdoc/classes/BoldContainer.src/M000164.html +18 -0
- data/doc/rdoc/classes/BoldParser.html +156 -0
- data/doc/rdoc/classes/BoldParser.src/M000247.html +18 -0
- data/doc/rdoc/classes/BoldParser.src/M000248.html +18 -0
- data/doc/rdoc/classes/CachedPage.html +187 -0
- data/doc/rdoc/classes/CachedPage.src/M000244.html +20 -0
- data/doc/rdoc/classes/CachedPage.src/M000245.html +27 -0
- data/doc/rdoc/classes/CachedPage.src/M000246.html +18 -0
- data/doc/rdoc/classes/CancelAction.html +179 -0
- data/doc/rdoc/classes/CancelAction.src/M000165.html +22 -0
- data/doc/rdoc/classes/CancelAction.src/M000166.html +20 -0
- data/doc/rdoc/classes/CancelAction.src/M000167.html +21 -0
- data/doc/rdoc/classes/CancelCategoryAction.html +164 -0
- data/doc/rdoc/classes/CancelCategoryAction.src/M000115.html +22 -0
- data/doc/rdoc/classes/CancelCategoryAction.src/M000116.html +20 -0
- data/doc/rdoc/classes/CategoriesPage.html +212 -0
- data/doc/rdoc/classes/CategoriesPage.src/M000232.html +27 -0
- data/doc/rdoc/classes/CategoriesPage.src/M000233.html +18 -0
- data/doc/rdoc/classes/CategoriesPage.src/M000234.html +73 -0
- data/doc/rdoc/classes/CategoriesPage.src/M000235.html +29 -0
- data/doc/rdoc/classes/CategoriesPage.src/M000236.html +59 -0
- data/doc/rdoc/classes/CategoryBarActionElement.html +139 -0
- data/doc/rdoc/classes/CategoryBarActionElement.src/M000069.html +18 -0
- data/doc/rdoc/classes/CategoryBarNextLevelActionElement.html +139 -0
- data/doc/rdoc/classes/CategoryBarNextLevelActionElement.src/M000026.html +18 -0
- data/doc/rdoc/classes/CategoryFormAction.html +169 -0
- data/doc/rdoc/classes/CategoryFormAction.src/M000148.html +18 -0
- data/doc/rdoc/classes/CategoryFormAction.src/M000149.html +30 -0
- data/doc/rdoc/classes/CategoryFormActionAdapter.html +171 -0
- data/doc/rdoc/classes/CategoryFormActionAdapter.src/M000112.html +19 -0
- data/doc/rdoc/classes/CategoryFormActionAdapter.src/M000113.html +18 -0
- data/doc/rdoc/classes/CategoryFormActionAdapter.src/M000114.html +18 -0
- data/doc/rdoc/classes/CompositeAction.html +186 -0
- data/doc/rdoc/classes/CompositeAction.src/M000119.html +19 -0
- data/doc/rdoc/classes/CompositeAction.src/M000120.html +18 -0
- data/doc/rdoc/classes/CompositeAction.src/M000121.html +21 -0
- data/doc/rdoc/classes/CompositeAction.src/M000122.html +18 -0
- data/doc/rdoc/classes/CompositeLinkActionElement.html +156 -0
- data/doc/rdoc/classes/CompositeLinkActionElement.src/M000196.html +20 -0
- data/doc/rdoc/classes/CompositeLinkActionElement.src/M000197.html +41 -0
- data/doc/rdoc/classes/Constants.html +198 -0
- data/doc/rdoc/classes/Container.html +281 -0
- data/doc/rdoc/classes/Container.src/M000251.html +19 -0
- data/doc/rdoc/classes/Container.src/M000252.html +18 -0
- data/doc/rdoc/classes/Container.src/M000253.html +18 -0
- data/doc/rdoc/classes/Container.src/M000254.html +18 -0
- data/doc/rdoc/classes/Container.src/M000255.html +27 -0
- data/doc/rdoc/classes/Container.src/M000256.html +18 -0
- data/doc/rdoc/classes/Container.src/M000257.html +18 -0
- data/doc/rdoc/classes/Container.src/M000258.html +18 -0
- data/doc/rdoc/classes/Container.src/M000259.html +18 -0
- data/doc/rdoc/classes/Container.src/M000260.html +23 -0
- data/doc/rdoc/classes/ContentDoc.html +236 -0
- data/doc/rdoc/classes/ContentDoc.src/M000129.html +22 -0
- data/doc/rdoc/classes/ContentDoc.src/M000130.html +18 -0
- data/doc/rdoc/classes/ContentDoc.src/M000131.html +20 -0
- data/doc/rdoc/classes/ContentDoc.src/M000132.html +18 -0
- data/doc/rdoc/classes/ContentDoc.src/M000133.html +18 -0
- data/doc/rdoc/classes/ContentDoc.src/M000134.html +18 -0
- data/doc/rdoc/classes/ContentDoc.src/M000135.html +18 -0
- data/doc/rdoc/classes/ContentParser.html +176 -0
- data/doc/rdoc/classes/ContentParser.src/M000176.html +30 -0
- data/doc/rdoc/classes/ContentParser.src/M000177.html +28 -0
- data/doc/rdoc/classes/ContentParser.src/M000178.html +55 -0
- data/doc/rdoc/classes/CurrentList.html +209 -0
- data/doc/rdoc/classes/CurrentList.src/M000228.html +19 -0
- data/doc/rdoc/classes/CurrentList.src/M000229.html +18 -0
- data/doc/rdoc/classes/CurrentList.src/M000230.html +18 -0
- data/doc/rdoc/classes/CurrentList.src/M000231.html +18 -0
- data/doc/rdoc/classes/DataContainer.html +234 -0
- data/doc/rdoc/classes/DataContainer.src/M000101.html +26 -0
- data/doc/rdoc/classes/DataContainer.src/M000102.html +24 -0
- data/doc/rdoc/classes/DataContainer.src/M000103.html +23 -0
- data/doc/rdoc/classes/DataContainer.src/M000104.html +26 -0
- data/doc/rdoc/classes/DataContainer.src/M000105.html +22 -0
- data/doc/rdoc/classes/DataContainer.src/M000106.html +18 -0
- data/doc/rdoc/classes/DataStorage.html +199 -0
- data/doc/rdoc/classes/DataStorage.src/M000031.html +23 -0
- data/doc/rdoc/classes/DataStorage.src/M000032.html +36 -0
- data/doc/rdoc/classes/DataStorage.src/M000033.html +25 -0
- data/doc/rdoc/classes/DataStorage.src/M000034.html +30 -0
- data/doc/rdoc/classes/DataStorage.src/M000035.html +21 -0
- data/doc/rdoc/classes/DefaultAction.html +187 -0
- data/doc/rdoc/classes/DefaultAction.src/M000014.html +23 -0
- data/doc/rdoc/classes/DefaultAction.src/M000015.html +36 -0
- data/doc/rdoc/classes/DefaultAction.src/M000016.html +38 -0
- data/doc/rdoc/classes/DefaultLoggerFactory.html +140 -0
- data/doc/rdoc/classes/DefaultLoggerFactory.src/M000169.html +19 -0
- data/doc/rdoc/classes/DirectLinkContainer.html +156 -0
- data/doc/rdoc/classes/DirectLinkContainer.src/M000209.html +19 -0
- data/doc/rdoc/classes/DirectLinkContainer.src/M000210.html +18 -0
- data/doc/rdoc/classes/DirectLinkParser.html +137 -0
- data/doc/rdoc/classes/DirectLinkParser.src/M000168.html +39 -0
- data/doc/rdoc/classes/DivTag.html +150 -0
- data/doc/rdoc/classes/DivTag.src/M000030.html +19 -0
- data/doc/rdoc/classes/EditAction.html +177 -0
- data/doc/rdoc/classes/EditAction.src/M000056.html +24 -0
- data/doc/rdoc/classes/EditAction.src/M000057.html +64 -0
- data/doc/rdoc/classes/EditActionAdapter.html +139 -0
- data/doc/rdoc/classes/EditActionAdapter.src/M000002.html +20 -0
- data/doc/rdoc/classes/EditCategoryAction.html +176 -0
- data/doc/rdoc/classes/EditCategoryAction.src/M000126.html +24 -0
- data/doc/rdoc/classes/EditCategoryAction.src/M000127.html +39 -0
- data/doc/rdoc/classes/EditCategoryActionAdapter.html +139 -0
- data/doc/rdoc/classes/EditCategoryActionAdapter.src/M000021.html +20 -0
- data/doc/rdoc/classes/EditCategoryPage.html +242 -0
- data/doc/rdoc/classes/EditCategoryPage.src/M000036.html +29 -0
- data/doc/rdoc/classes/EditCategoryPage.src/M000037.html +18 -0
- data/doc/rdoc/classes/EditCategoryPage.src/M000038.html +18 -0
- data/doc/rdoc/classes/EditCategoryPage.src/M000039.html +18 -0
- data/doc/rdoc/classes/EditCategoryPage.src/M000040.html +109 -0
- data/doc/rdoc/classes/EditCategoryPage.src/M000041.html +60 -0
- data/doc/rdoc/classes/EditCategoryPage.src/M000042.html +29 -0
- data/doc/rdoc/classes/EditNewActionAdapter.html +156 -0
- data/doc/rdoc/classes/EditNewActionAdapter.src/M000220.html +20 -0
- data/doc/rdoc/classes/EditNewActionAdapter.src/M000221.html +23 -0
- data/doc/rdoc/classes/EditPage.html +212 -0
- data/doc/rdoc/classes/EditPage.src/M000064.html +33 -0
- data/doc/rdoc/classes/EditPage.src/M000065.html +18 -0
- data/doc/rdoc/classes/EditPage.src/M000066.html +18 -0
- data/doc/rdoc/classes/EditPage.src/M000067.html +18 -0
- data/doc/rdoc/classes/EditPage.src/M000068.html +112 -0
- data/doc/rdoc/classes/EmphasisContainer.html +156 -0
- data/doc/rdoc/classes/EmphasisContainer.src/M000003.html +20 -0
- data/doc/rdoc/classes/EmphasisContainer.src/M000004.html +19 -0
- data/doc/rdoc/classes/EmphasisParser.html +176 -0
- data/doc/rdoc/classes/EmphasisParser.src/M000076.html +19 -0
- data/doc/rdoc/classes/EmphasisParser.src/M000077.html +18 -0
- data/doc/rdoc/classes/EmphasisParser.src/M000078.html +45 -0
- data/doc/rdoc/classes/EscapeParser.html +137 -0
- data/doc/rdoc/classes/EscapeParser.src/M000150.html +26 -0
- data/doc/rdoc/classes/ExpireMetaTag.html +139 -0
- data/doc/rdoc/classes/ExpireMetaTag.src/M000241.html +18 -0
- data/doc/rdoc/classes/FilePersistentStorageHandler.html +207 -0
- data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000215.html +27 -0
- data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000216.html +21 -0
- data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000217.html +19 -0
- data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000218.html +19 -0
- data/doc/rdoc/classes/FilePersistentStorageHandler.src/M000219.html +20 -0
- data/doc/rdoc/classes/FormAction.html +169 -0
- data/doc/rdoc/classes/FormAction.src/M000081.html +18 -0
- data/doc/rdoc/classes/FormAction.src/M000082.html +30 -0
- data/doc/rdoc/classes/FormActionAdapter.html +171 -0
- data/doc/rdoc/classes/FormActionAdapter.src/M000086.html +19 -0
- data/doc/rdoc/classes/FormActionAdapter.src/M000087.html +18 -0
- data/doc/rdoc/classes/FormActionAdapter.src/M000088.html +18 -0
- data/doc/rdoc/classes/FormActionElement.html +169 -0
- data/doc/rdoc/classes/FormActionElement.src/M000044.html +18 -0
- data/doc/rdoc/classes/FormActionElement.src/M000045.html +18 -0
- data/doc/rdoc/classes/FormActionElement.src/M000046.html +23 -0
- data/doc/rdoc/classes/FormInputTag.html +165 -0
- data/doc/rdoc/classes/FormInputTag.src/M000161.html +21 -0
- data/doc/rdoc/classes/HiddenFormInputTag.html +139 -0
- data/doc/rdoc/classes/HiddenFormInputTag.src/M000027.html +18 -0
- data/doc/rdoc/classes/IDataStorage.html +170 -0
- data/doc/rdoc/classes/IDataStorage.src/M000382.html +18 -0
- data/doc/rdoc/classes/IDataStorage.src/M000383.html +18 -0
- data/doc/rdoc/classes/IDataStorage.src/M000384.html +18 -0
- data/doc/rdoc/classes/ItalicContainer.html +139 -0
- data/doc/rdoc/classes/ItalicContainer.src/M000128.html +18 -0
- data/doc/rdoc/classes/ItalicParser.html +156 -0
- data/doc/rdoc/classes/ItalicParser.src/M000207.html +18 -0
- data/doc/rdoc/classes/ItalicParser.src/M000208.html +18 -0
- data/doc/rdoc/classes/LinkActionElement.html +184 -0
- data/doc/rdoc/classes/LinkActionElement.src/M000005.html +18 -0
- data/doc/rdoc/classes/LinkActionElement.src/M000006.html +18 -0
- data/doc/rdoc/classes/LinkActionElement.src/M000007.html +18 -0
- data/doc/rdoc/classes/LinkActionElement.src/M000008.html +18 -0
- data/doc/rdoc/classes/LinkTag.html +187 -0
- data/doc/rdoc/classes/LinkTag.src/M000153.html +34 -0
- data/doc/rdoc/classes/LinkTag.src/M000154.html +18 -0
- data/doc/rdoc/classes/LinkTag.src/M000155.html +20 -0
- data/doc/rdoc/classes/ListContainer.html +156 -0
- data/doc/rdoc/classes/ListContainer.src/M000174.html +18 -0
- data/doc/rdoc/classes/ListContainer.src/M000175.html +19 -0
- data/doc/rdoc/classes/ListItemContainer.html +156 -0
- data/doc/rdoc/classes/ListItemContainer.src/M000028.html +19 -0
- data/doc/rdoc/classes/ListItemContainer.src/M000029.html +19 -0
- data/doc/rdoc/classes/ListParser.html +144 -0
- data/doc/rdoc/classes/ListParser.src/M000195.html +147 -0
- data/doc/rdoc/classes/ListParserUtils.html +141 -0
- data/doc/rdoc/classes/ListParserUtils.src/M000385.html +23 -0
- data/doc/rdoc/classes/Localization.html +209 -0
- data/doc/rdoc/classes/Localization.src/M000311.html +40 -0
- data/doc/rdoc/classes/Localization.src/M000312.html +23 -0
- data/doc/rdoc/classes/Log4r.html +111 -0
- data/doc/rdoc/classes/Log4r/ExtendedRollingFileOutputter.html +178 -0
- data/doc/rdoc/classes/Log4r/ExtendedRollingFileOutputter.src/M000380.html +25 -0
- data/doc/rdoc/classes/Log4r/ExtendedRollingFileOutputter.src/M000381.html +33 -0
- data/doc/rdoc/classes/LoggerFactory.html +152 -0
- data/doc/rdoc/classes/LoggerFactory.src/M000062.html +22 -0
- data/doc/rdoc/classes/LoggerFactory.src/M000063.html +18 -0
- data/doc/rdoc/classes/MetaTag.html +166 -0
- data/doc/rdoc/classes/MetaTag.src/M000118.html +20 -0
- data/doc/rdoc/classes/NoCacheMetaTag.html +139 -0
- data/doc/rdoc/classes/NoCacheMetaTag.src/M000043.html +18 -0
- data/doc/rdoc/classes/PageRequest.html +259 -0
- data/doc/rdoc/classes/PageRequest.src/M000179.html +20 -0
- data/doc/rdoc/classes/PageRequest.src/M000180.html +18 -0
- data/doc/rdoc/classes/PageRequest.src/M000181.html +18 -0
- data/doc/rdoc/classes/PageRequest.src/M000182.html +18 -0
- data/doc/rdoc/classes/PageRequest.src/M000183.html +19 -0
- data/doc/rdoc/classes/PageRequest.src/M000184.html +23 -0
- data/doc/rdoc/classes/PageRequest.src/M000185.html +23 -0
- data/doc/rdoc/classes/PageRequest.src/M000186.html +19 -0
- data/doc/rdoc/classes/PageRequest.src/M000187.html +18 -0
- data/doc/rdoc/classes/PageResponse.html +250 -0
- data/doc/rdoc/classes/PageResponse.src/M000092.html +18 -0
- data/doc/rdoc/classes/PageResponse.src/M000093.html +18 -0
- data/doc/rdoc/classes/PageResponse.src/M000094.html +18 -0
- data/doc/rdoc/classes/PageResponse.src/M000095.html +18 -0
- data/doc/rdoc/classes/PageResponse.src/M000096.html +18 -0
- data/doc/rdoc/classes/PageResponse.src/M000097.html +18 -0
- data/doc/rdoc/classes/PageResponse.src/M000098.html +18 -0
- data/doc/rdoc/classes/PageResponse.src/M000099.html +18 -0
- data/doc/rdoc/classes/ParagraphContainer.html +156 -0
- data/doc/rdoc/classes/ParagraphContainer.src/M000158.html +19 -0
- data/doc/rdoc/classes/ParagraphContainer.src/M000159.html +24 -0
- data/doc/rdoc/classes/ParagraphParser.html +137 -0
- data/doc/rdoc/classes/ParagraphParser.src/M000151.html +42 -0
- data/doc/rdoc/classes/PersistentStorageHandler.html +182 -0
- data/doc/rdoc/classes/PersistentStorageHandler.src/M000376.html +18 -0
- data/doc/rdoc/classes/PersistentStorageHandler.src/M000377.html +18 -0
- data/doc/rdoc/classes/PersistentStorageHandler.src/M000378.html +18 -0
- data/doc/rdoc/classes/PersistentStorageHandler.src/M000379.html +18 -0
- data/doc/rdoc/classes/Pid.html +182 -0
- data/doc/rdoc/classes/Pid.src/M000083.html +18 -0
- data/doc/rdoc/classes/Pid.src/M000084.html +24 -0
- data/doc/rdoc/classes/Pid.src/M000085.html +18 -0
- data/doc/rdoc/classes/Properties.html +184 -0
- data/doc/rdoc/classes/Properties.src/M000058.html +18 -0
- data/doc/rdoc/classes/Properties.src/M000059.html +18 -0
- data/doc/rdoc/classes/Properties.src/M000060.html +18 -0
- data/doc/rdoc/classes/Properties.src/M000061.html +27 -0
- data/doc/rdoc/classes/PropertyList.html +187 -0
- data/doc/rdoc/classes/PropertyList.src/M000017.html +19 -0
- data/doc/rdoc/classes/PropertyList.src/M000018.html +23 -0
- data/doc/rdoc/classes/PropertyList.src/M000019.html +23 -0
- data/doc/rdoc/classes/PropertyList.src/M000020.html +18 -0
- data/doc/rdoc/classes/RawAttribute.html +154 -0
- data/doc/rdoc/classes/RawAttribute.src/M000249.html +20 -0
- data/doc/rdoc/classes/RawAttribute.src/M000250.html +21 -0
- data/doc/rdoc/classes/RawPage.html +171 -0
- data/doc/rdoc/classes/RawPage.src/M000107.html +19 -0
- data/doc/rdoc/classes/RawPage.src/M000108.html +18 -0
- data/doc/rdoc/classes/RawPage.src/M000109.html +18 -0
- data/doc/rdoc/classes/ReferenceLinkContainer.html +156 -0
- data/doc/rdoc/classes/ReferenceLinkContainer.src/M000213.html +20 -0
- data/doc/rdoc/classes/ReferenceLinkContainer.src/M000214.html +19 -0
- data/doc/rdoc/classes/Ribit.html +124 -0
- data/doc/rdoc/classes/Ribit/ContentStore.html +236 -0
- data/doc/rdoc/classes/Ribit/ContentStore.src/M000304.html +23 -0
- data/doc/rdoc/classes/Ribit/ContentStore.src/M000305.html +29 -0
- data/doc/rdoc/classes/Ribit/ContentStore.src/M000306.html +25 -0
- data/doc/rdoc/classes/Ribit/ContentStore.src/M000307.html +49 -0
- data/doc/rdoc/classes/Ribit/ContentStore.src/M000308.html +18 -0
- data/doc/rdoc/classes/Ribit/ContentStore.src/M000309.html +73 -0
- data/doc/rdoc/classes/Ribit/ContentStore.src/M000310.html +51 -0
- data/doc/rdoc/classes/Ribit/FileWriter.html +162 -0
- data/doc/rdoc/classes/Ribit/FileWriter.src/M000289.html +19 -0
- data/doc/rdoc/classes/Ribit/FileWriter.src/M000290.html +32 -0
- data/doc/rdoc/classes/Ribit/Repository.html +174 -0
- data/doc/rdoc/classes/Ribit/Repository.src/M000276.html +18 -0
- data/doc/rdoc/classes/Ribit/Repository.src/M000277.html +18 -0
- data/doc/rdoc/classes/Ribit/Repository.src/M000278.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLogger.html +137 -0
- data/doc/rdoc/classes/Ribit/RibitLogger.src/M000301.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerConfig.html +182 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000279.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000280.html +23 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000281.html +21 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerConfig.src/M000282.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerFactory.html +154 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerFactory.src/M000287.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerFactory.src/M000288.html +25 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.html +229 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000294.html +26 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000295.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000296.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000297.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000298.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000299.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerImpl.src/M000300.html +18 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.html +210 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.src/M000291.html +20 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.src/M000292.html +32 -0
- data/doc/rdoc/classes/Ribit/RibitLoggerWrapper.src/M000293.html +18 -0
- data/doc/rdoc/classes/Ribit/Writer.html +163 -0
- data/doc/rdoc/classes/Ribit/Writer.src/M000302.html +18 -0
- data/doc/rdoc/classes/Ribit/Writer.src/M000303.html +21 -0
- data/doc/rdoc/classes/RibitConfig.html +247 -0
- data/doc/rdoc/classes/RibitConfig.src/M000072.html +32 -0
- data/doc/rdoc/classes/RibitConfig.src/M000073.html +18 -0
- data/doc/rdoc/classes/RibitConfig.src/M000074.html +18 -0
- data/doc/rdoc/classes/RibitConfig.src/M000075.html +18 -0
- data/doc/rdoc/classes/RibitConfigParser.html +140 -0
- data/doc/rdoc/classes/RibitConfigParser.src/M000117.html +45 -0
- data/doc/rdoc/classes/RibitData.html +128 -0
- data/doc/rdoc/classes/RibitData/CategoriesWriter.html +169 -0
- data/doc/rdoc/classes/RibitData/CategoriesWriter.src/M000338.html +18 -0
- data/doc/rdoc/classes/RibitData/CategoriesWriter.src/M000339.html +27 -0
- data/doc/rdoc/classes/RibitData/CategoriesWriter.src/M000340.html +24 -0
- data/doc/rdoc/classes/RibitData/Category.html +485 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000313.html +27 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000314.html +36 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000315.html +22 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000316.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000317.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000318.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000319.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000320.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000321.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000322.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000323.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000324.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000325.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000326.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000327.html +36 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000328.html +18 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000329.html +48 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000330.html +45 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000331.html +30 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000332.html +25 -0
- data/doc/rdoc/classes/RibitData/Category.src/M000333.html +18 -0
- data/doc/rdoc/classes/RibitData/CategoryParser.html +217 -0
- data/doc/rdoc/classes/RibitData/CategoryParser.src/M000357.html +18 -0
- data/doc/rdoc/classes/RibitData/CategoryParser.src/M000358.html +29 -0
- data/doc/rdoc/classes/RibitData/CategoryParser.src/M000359.html +31 -0
- data/doc/rdoc/classes/RibitData/CategoryParser.src/M000360.html +27 -0
- data/doc/rdoc/classes/RibitData/CategoryParser.src/M000361.html +45 -0
- data/doc/rdoc/classes/RibitData/Page.html +313 -0
- data/doc/rdoc/classes/RibitData/Page.src/M000362.html +33 -0
- data/doc/rdoc/classes/RibitData/Page.src/M000363.html +22 -0
- data/doc/rdoc/classes/RibitData/Page.src/M000364.html +18 -0
- data/doc/rdoc/classes/RibitData/Page.src/M000365.html +18 -0
- data/doc/rdoc/classes/RibitData/Page.src/M000366.html +18 -0
- data/doc/rdoc/classes/RibitData/Page.src/M000367.html +46 -0
- data/doc/rdoc/classes/RibitData/Page.src/M000368.html +26 -0
- data/doc/rdoc/classes/RibitData/PageParser.html +190 -0
- data/doc/rdoc/classes/RibitData/PageParser.src/M000334.html +19 -0
- data/doc/rdoc/classes/RibitData/PageParser.src/M000335.html +32 -0
- data/doc/rdoc/classes/RibitData/PageParser.src/M000336.html +42 -0
- data/doc/rdoc/classes/RibitData/PageParser.src/M000337.html +21 -0
- data/doc/rdoc/classes/RibitData/RibitData.html +389 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000341.html +26 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000342.html +22 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000343.html +18 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000344.html +36 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000345.html +18 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000346.html +25 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000347.html +18 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000348.html +22 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000349.html +18 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000350.html +30 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000351.html +18 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000352.html +48 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000353.html +30 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000354.html +22 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000355.html +22 -0
- data/doc/rdoc/classes/RibitData/RibitData.src/M000356.html +22 -0
- data/doc/rdoc/classes/RibitData/RibitDataException.html +113 -0
- data/doc/rdoc/classes/RibitException.html +117 -0
- data/doc/rdoc/classes/RibitLinkContainer.html +156 -0
- data/doc/rdoc/classes/RibitLinkContainer.src/M000211.html +85 -0
- data/doc/rdoc/classes/RibitLinkContainer.src/M000212.html +18 -0
- data/doc/rdoc/classes/RibitLinkParser.html +137 -0
- data/doc/rdoc/classes/RibitLinkParser.src/M000100.html +50 -0
- data/doc/rdoc/classes/RibitServlet.html +196 -0
- data/doc/rdoc/classes/RibitServlet.src/M000222.html +37 -0
- data/doc/rdoc/classes/RibitServlet.src/M000223.html +53 -0
- data/doc/rdoc/classes/RibitServlet.src/M000224.html +39 -0
- data/doc/rdoc/classes/RibitServlet.src/M000225.html +19 -0
- data/doc/rdoc/classes/RootContainer.html +139 -0
- data/doc/rdoc/classes/RootContainer.src/M000206.html +19 -0
- data/doc/rdoc/classes/SaveAction.html +164 -0
- data/doc/rdoc/classes/SaveAction.src/M000162.html +24 -0
- data/doc/rdoc/classes/SaveAction.src/M000163.html +116 -0
- data/doc/rdoc/classes/SaveCategoryAction.html +164 -0
- data/doc/rdoc/classes/SaveCategoryAction.src/M000047.html +24 -0
- data/doc/rdoc/classes/SaveCategoryAction.src/M000048.html +97 -0
- data/doc/rdoc/classes/SectionContainer.html +156 -0
- data/doc/rdoc/classes/SectionContainer.src/M000070.html +19 -0
- data/doc/rdoc/classes/SectionContainer.src/M000071.html +20 -0
- data/doc/rdoc/classes/SectionParser.html +137 -0
- data/doc/rdoc/classes/SectionParser.src/M000152.html +41 -0
- data/doc/rdoc/classes/SelectOptionTag.html +177 -0
- data/doc/rdoc/classes/SelectOptionTag.src/M000156.html +22 -0
- data/doc/rdoc/classes/SelectOptionTag.src/M000157.html +18 -0
- data/doc/rdoc/classes/StyleSheetAction.html +182 -0
- data/doc/rdoc/classes/StyleSheetAction.src/M000226.html +31 -0
- data/doc/rdoc/classes/StyleSheetAction.src/M000227.html +36 -0
- data/doc/rdoc/classes/TextContainer.html +214 -0
- data/doc/rdoc/classes/TextContainer.src/M000050.html +19 -0
- data/doc/rdoc/classes/TextContainer.src/M000051.html +18 -0
- data/doc/rdoc/classes/TextContainer.src/M000052.html +18 -0
- data/doc/rdoc/classes/TextContainer.src/M000053.html +18 -0
- data/doc/rdoc/classes/TextContainer.src/M000054.html +18 -0
- data/doc/rdoc/classes/TextContainer.src/M000055.html +18 -0
- data/doc/rdoc/classes/TextPage.html +226 -0
- data/doc/rdoc/classes/TextPage.src/M000198.html +29 -0
- data/doc/rdoc/classes/TextPage.src/M000199.html +18 -0
- data/doc/rdoc/classes/TextPage.src/M000200.html +54 -0
- data/doc/rdoc/classes/TextPage.src/M000201.html +36 -0
- data/doc/rdoc/classes/TextPage.src/M000202.html +46 -0
- data/doc/rdoc/classes/TextPage.src/M000203.html +25 -0
- data/doc/rdoc/classes/URL.html +182 -0
- data/doc/rdoc/classes/URL.src/M000123.html +24 -0
- data/doc/rdoc/classes/URL.src/M000124.html +19 -0
- data/doc/rdoc/classes/URL.src/M000125.html +35 -0
- data/doc/rdoc/classes/UnformattedContentContainer.html +156 -0
- data/doc/rdoc/classes/UnformattedContentContainer.src/M000079.html +20 -0
- data/doc/rdoc/classes/UnformattedContentContainer.src/M000080.html +20 -0
- data/doc/rdoc/classes/UnformattedContentParser.html +137 -0
- data/doc/rdoc/classes/UnformattedContentParser.src/M000194.html +49 -0
- data/doc/rdoc/classes/ViewAction.html +221 -0
- data/doc/rdoc/classes/ViewAction.src/M000009.html +25 -0
- data/doc/rdoc/classes/ViewAction.src/M000010.html +20 -0
- data/doc/rdoc/classes/ViewAction.src/M000011.html +77 -0
- data/doc/rdoc/classes/ViewAction.src/M000012.html +18 -0
- data/doc/rdoc/classes/ViewAction.src/M000013.html +22 -0
- data/doc/rdoc/classes/ViewActionAdapter.html +186 -0
- data/doc/rdoc/classes/ViewActionAdapter.src/M000022.html +20 -0
- data/doc/rdoc/classes/ViewActionAdapter.src/M000023.html +24 -0
- data/doc/rdoc/classes/ViewActionAdapter.src/M000024.html +20 -0
- data/doc/rdoc/classes/ViewActionAdapter.src/M000025.html +21 -0
- data/doc/rdoc/classes/ViewCategoriesAction.html +211 -0
- data/doc/rdoc/classes/ViewCategoriesAction.src/M000261.html +25 -0
- data/doc/rdoc/classes/ViewCategoriesAction.src/M000262.html +20 -0
- data/doc/rdoc/classes/ViewCategoriesAction.src/M000263.html +61 -0
- data/doc/rdoc/classes/ViewCategoriesAction.src/M000264.html +22 -0
- data/doc/rdoc/classes/ViewCategoriesActionAdapter.html +171 -0
- data/doc/rdoc/classes/ViewCategoriesActionAdapter.src/M000089.html +18 -0
- data/doc/rdoc/classes/ViewCategoriesActionAdapter.src/M000090.html +24 -0
- data/doc/rdoc/classes/ViewCategoriesActionAdapter.src/M000091.html +18 -0
- data/doc/rdoc/classes/W3CValidatorLinkActionAdapter.html +156 -0
- data/doc/rdoc/classes/W3CValidatorLinkActionAdapter.src/M000110.html +26 -0
- data/doc/rdoc/classes/W3CValidatorLinkActionAdapter.src/M000111.html +18 -0
- data/doc/rdoc/classes/WebAction.html +165 -0
- data/doc/rdoc/classes/WebAction.src/M000242.html +18 -0
- data/doc/rdoc/classes/WebAction.src/M000243.html +19 -0
- data/doc/rdoc/classes/WebPage.html +184 -0
- data/doc/rdoc/classes/WebPage.src/M000170.html +17 -0
- data/doc/rdoc/classes/WebPage.src/M000171.html +19 -0
- data/doc/rdoc/classes/WebPage.src/M000172.html +18 -0
- data/doc/rdoc/classes/WebPage.src/M000173.html +18 -0
- data/doc/rdoc/classes/XHTMLDocument.html +377 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000136.html +26 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000137.html +40 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000138.html +20 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000139.html +18 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000140.html +18 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000141.html +19 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000142.html +21 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000143.html +30 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000144.html +18 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000145.html +18 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000146.html +23 -0
- data/doc/rdoc/classes/XHTMLDocument.src/M000147.html +18 -0
- data/doc/rdoc/classes/XHTMLException.html +117 -0
- data/doc/rdoc/classes/XHTMLPage.html +225 -0
- data/doc/rdoc/classes/XHTMLPage.src/M000188.html +20 -0
- data/doc/rdoc/classes/XHTMLPage.src/M000189.html +18 -0
- data/doc/rdoc/classes/XHTMLPage.src/M000190.html +44 -0
- data/doc/rdoc/classes/XHTMLPage.src/M000191.html +18 -0
- data/doc/rdoc/classes/XHTMLPage.src/M000192.html +54 -0
- data/doc/rdoc/classes/XHTMLPage.src/M000193.html +22 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/CHANGES.html +150 -0
- data/doc/rdoc/files/INSTALL.html +169 -0
- data/doc/rdoc/files/LICENSE.html +449 -0
- data/doc/rdoc/files/README.html +176 -0
- data/doc/rdoc/files/lib/common/assert_rb.html +101 -0
- data/doc/rdoc/files/lib/common/cvs_rb.html +116 -0
- data/doc/rdoc/files/lib/common/datastorage_rb.html +108 -0
- data/doc/rdoc/files/lib/common/loggerfactory_rb.html +108 -0
- data/doc/rdoc/files/lib/common/pid_rb.html +101 -0
- data/doc/rdoc/files/lib/common/properties_rb.html +101 -0
- data/doc/rdoc/files/lib/common/url_rb.html +108 -0
- data/doc/rdoc/files/lib/log4r/outputter/extendedrollingfileoutputter_rb.html +111 -0
- data/doc/rdoc/files/lib/ribit/action_rb.html +116 -0
- data/doc/rdoc/files/lib/ribit/actionelement_rb.html +108 -0
- data/doc/rdoc/files/lib/ribit/common_rb.html +130 -0
- data/doc/rdoc/files/lib/ribit/common_rb.src/M000001.html +25 -0
- data/doc/rdoc/files/lib/ribit/config_rb.html +116 -0
- data/doc/rdoc/files/lib/ribit/constants_rb.html +101 -0
- data/doc/rdoc/files/lib/ribit/contentparser_rb.html +112 -0
- data/doc/rdoc/files/lib/ribit/contentstore_rb.html +112 -0
- data/doc/rdoc/files/lib/ribit/localization_rb.html +108 -0
- data/doc/rdoc/files/lib/ribit/main_rb.html +120 -0
- data/doc/rdoc/files/lib/ribit/ribit_rb.html +123 -0
- data/doc/rdoc/files/lib/ribit/ribitdata_rb.html +112 -0
- data/doc/rdoc/files/lib/ribit/ribitlogger_rb.html +111 -0
- data/doc/rdoc/files/lib/ribit/webpage_rb.html +118 -0
- data/doc/rdoc/files/lib/ribit/xhtmldocument_rb.html +109 -0
- data/doc/rdoc/files/lib/ribit/xhtmltag_rb.html +109 -0
- data/doc/rdoc/fr_class_index.html +150 -0
- data/doc/rdoc/fr_file_index.html +53 -0
- data/doc/rdoc/fr_method_index.html +411 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/doc/spec.txt +42 -0
- data/doc/test_run_25052005.txt +108 -0
- data/doc/testplan.txt +87 -0
- data/doc/www/index.html +5 -0
- data/lib/common/assert.rb +72 -0
- data/lib/common/cvs.rb +201 -0
- data/lib/common/datastorage.rb +265 -0
- data/lib/common/loggerfactory.rb +56 -0
- data/lib/common/pid.rb +44 -0
- data/lib/common/properties.rb +89 -0
- data/lib/common/url.rb +64 -0
- data/lib/log4r/outputter/extendedrollingfileoutputter.rb +73 -0
- data/lib/ribit/action.rb +1106 -0
- data/lib/ribit/actionelement.rb +152 -0
- data/lib/ribit/common.rb +34 -0
- data/lib/ribit/config.rb +123 -0
- data/lib/ribit/constants.rb +50 -0
- data/lib/ribit/contentparser.rb +1111 -0
- data/lib/ribit/contentstore.rb +406 -0
- data/lib/ribit/localization.rb +76 -0
- data/lib/ribit/main.rb +114 -0
- data/lib/ribit/ribit.rb +319 -0
- data/lib/ribit/ribitdata.rb +909 -0
- data/lib/ribit/ribitlogger.rb +192 -0
- data/lib/ribit/webpage.rb +802 -0
- data/lib/ribit/xhtmldocument.rb +148 -0
- data/lib/ribit/xhtmltag.rb +189 -0
- data/share/config/content/1/1.xml +6 -0
- data/share/config/content/1/2.xml +6 -0
- data/share/config/content/1/3.xml +6 -0
- data/share/config/content/1/4.xml +6 -0
- data/share/config/content/1/5.xml +6 -0
- data/share/config/content/1/category.xml +7 -0
- data/share/config/content/1/files/edit-category-template.html +59 -0
- data/share/config/content/1/files/edit-template.html +88 -0
- data/share/config/content/1/files/localization_en.properties +11 -0
- data/share/config/content/1/files/ribit.css +215 -0
- data/share/config/content/1/files/view-template.html +50 -0
- data/share/config/content/2/1.xml +19 -0
- data/share/config/content/2/2.xml +54 -0
- data/share/config/content/2/category.xml +5 -0
- data/share/config/content/3/1.xml +11 -0
- data/share/config/content/3/3.xml +17 -0
- data/share/config/content/3/4.xml +28 -0
- data/share/config/content/3/category.xml +5 -0
- data/share/config/content/categories.xml +12 -0
- data/share/config/ribitconfig.xml +48 -0
- data/share/config/ribitconfig_dev.xml +41 -0
- data/share/config/ribitconfig_local.xml +39 -0
- data/share/test/config/content/1/1.xml +6 -0
- data/share/test/config/content/1/2.xml +6 -0
- data/share/test/config/content/1/3.xml +6 -0
- data/share/test/config/content/1/4.xml +6 -0
- data/share/test/config/content/1/category.xml +4 -0
- data/share/test/config/content/1/files/edit-template.html +50 -0
- data/share/test/config/content/1/files/localization_en.properties +4 -0
- data/share/test/config/content/1/files/ribit.css +139 -0
- data/share/test/config/content/1/files/view-template.html +36 -0
- data/share/test/config/content/2/1.xml +16 -0
- data/share/test/config/content/2/2.xml +25 -0
- data/share/test/config/content/2/category.xml +4 -0
- data/share/test/config/content/categories.xml +11 -0
- data/share/test/config/content/ribitdata.xml +348 -0
- data/share/test/config/ribitconfig.xml +36 -0
- data/share/test/test1.xml +13 -0
- data/share/test/test2.xml +17 -0
- data/share/test/test3.xml +5 -0
- data/test/alltests.rb +35 -0
- data/test/common/allcommontests.rb +40 -0
- data/test/common/asserttest.rb +71 -0
- data/test/common/cvstest.rb +117 -0
- data/test/common/datastoragetest.rb +151 -0
- data/test/common/filepersistentstoragehandlertest.rb +105 -0
- data/test/common/propertiestest.rb +77 -0
- data/test/common/urltest.rb +70 -0
- data/test/log4r/outputter/alllog4routputtertests.rb +28 -0
- data/test/log4r/outputter/extendedrollingfileoutputtertest.rb +77 -0
- data/test/mock/mock.rb +147 -0
- data/test/ribit/actionadaptertest.rb +58 -0
- data/test/ribit/actionelementtest.rb +147 -0
- data/test/ribit/actionmanagertest.rb +55 -0
- data/test/ribit/allribittests.rb +62 -0
- data/test/ribit/categoryformactiontest.rb +153 -0
- data/test/ribit/configtest.rb +43 -0
- data/test/ribit/contentparsertest.rb +404 -0
- data/test/ribit/contentstorestub.rb +64 -0
- data/test/ribit/contentstoretest.rb +222 -0
- data/test/ribit/editcategorypagetest.rb +121 -0
- data/test/ribit/formactiontest.rb +367 -0
- data/test/ribit/localizationtest.rb +65 -0
- data/test/ribit/loggertest.rb +44 -0
- data/test/ribit/misc/allmisctests.rb +32 -0
- data/test/ribit/misc/amritatest.rb +24 -0
- data/test/ribit/misc/debugservlet.rb +63 -0
- data/test/ribit/misc/postsevlet.rb +36 -0
- data/test/ribit/misc/rexmlcdatatest.rb +17 -0
- data/test/ribit/misc/rexmldoctypetest.rb +20 -0
- data/test/ribit/misc/rexmlreadtest.rb +13 -0
- data/test/ribit/misc/rexmlwritetest.rb +28 -0
- data/test/ribit/misc/rubytest.rb +184 -0
- data/test/ribit/misc/suidtest.rb +21 -0
- data/test/ribit/misc/suite.rb +12 -0
- data/test/ribit/misc/wwwtest.rb +68 -0
- data/test/ribit/pagerequesttest.rb +74 -0
- data/test/ribit/ribitdatatest.rb +404 -0
- data/test/ribit/ribitservlettest.rb +94 -0
- data/test/ribit/testdata/ribittestdata.rb +49 -0
- data/test/ribit/testutil/ribitstub.rb +83 -0
- data/test/ribit/testutil/ribittestcase.rb +66 -0
- data/test/ribit/viewactiontest.rb +332 -0
- data/test/ribit/webpagetest.rb +531 -0
- data/test/ribit/xhtmldocumenttest.rb +263 -0
- data/test/ribit/xhtmltagtest.rb +84 -0
- 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
|
data/lib/common/pid.rb
ADDED
|
@@ -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
|
data/lib/common/url.rb
ADDED
|
@@ -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
|
data/lib/ribit/action.rb
ADDED
|
@@ -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
|