IOWA 1.0.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.
- checksums.yaml +7 -0
- data/CONTRIBUTORS +14 -0
- data/README.md +23 -0
- data/RELEASE_NOTES +77 -0
- data/ToDo +21 -0
- data/components/CRUDList/CRUDList.html +13 -0
- data/components/CRUDList/CRUDList.iwa +136 -0
- data/components/Content/Content.html +0 -0
- data/components/Content/Content.iwa +143 -0
- data/components/Content/example/README +9 -0
- data/components/Content/example/cgi/iowa.cgi +10 -0
- data/components/Content/example/demo.rb +30 -0
- data/components/Content/example/doc/index.html +7 -0
- data/components/Content/example/iowa/Content.html +1 -0
- data/components/Content/example/iowa/Content.iwa +1 -0
- data/components/Content/example/iowa/Main.html +6 -0
- data/components/Content/example/iowa/Main.iwa +3 -0
- data/components/Content/example/iowa/_content/body +7 -0
- data/components/Content/example/iowa/_content/body2 +3 -0
- data/components/Content/example/iowa/_content/title +2 -0
- data/components/Content/example/iowa/app.cnf +8 -0
- data/components/Content/example/iowa/app.rb +8 -0
- data/components/Content/example/webrick.rb +38 -0
- data/components/Include/Include.html +1 -0
- data/components/Include/Include.iwa +30 -0
- data/components/Include/readme +5 -0
- data/components/JumpTo/JumpTo.html +8 -0
- data/components/JumpTo/JumpTo.iwa +8 -0
- data/components/JumpTo/readme +6 -0
- data/doc/Architecture.txt +6 -0
- data/doc/History.txt +33 -0
- data/doc/StandardDispatcher.txt +19 -0
- data/examples/blog/README +1 -0
- data/examples/hello_world/README +17 -0
- data/examples/hello_world/htdocs/hello_world_html.html +24 -0
- data/examples/hello_world/htdocs/hello_world_ruby.html +41 -0
- data/examples/hello_world/iowa/HelloWorld.html +14 -0
- data/examples/hello_world/iowa/HelloWorld.iwa +31 -0
- data/examples/hello_world/iowa/Index.html +16 -0
- data/examples/hello_world/iowa/Index.iwa +5 -0
- data/examples/hello_world/iowa/iowa_hello_world.cnf +19 -0
- data/examples/hello_world/iowa/iowa_hello_world.rb +5 -0
- data/examples/hello_world/iowa/mapfile.cnf +6 -0
- data/examples/hw1/iowa/Main.html +1 -0
- data/examples/hw1/iowa/README +9 -0
- data/examples/hw1/iowa/hw.rb +4 -0
- data/examples/hw2/iowa/Main.html +10 -0
- data/examples/hw2/iowa/Main.iwa +7 -0
- data/examples/hw2/iowa/README +16 -0
- data/examples/hw2/iowa/hw.rb +4 -0
- data/examples/hw3/iowa/Main.html +11 -0
- data/examples/hw3/iowa/Main.iwa +7 -0
- data/examples/hw3/iowa/README +22 -0
- data/examples/hw3/iowa/hw.rb +4 -0
- data/examples/hw4/iowa/Greetings.html +10 -0
- data/examples/hw4/iowa/Greetings.iwa +9 -0
- data/examples/hw4/iowa/Main.html +12 -0
- data/examples/hw4/iowa/Main.iwa +10 -0
- data/examples/hw4/iowa/README +28 -0
- data/examples/hw4/iowa/hw.rb +4 -0
- data/examples/hw5/iowa/Footer.html +2 -0
- data/examples/hw5/iowa/Greetings.html +4 -0
- data/examples/hw5/iowa/Greetings.iwa +12 -0
- data/examples/hw5/iowa/Header.html +6 -0
- data/examples/hw5/iowa/Main.html +12 -0
- data/examples/hw5/iowa/Main.iwa +13 -0
- data/examples/hw5/iowa/README +16 -0
- data/examples/hw5/iowa/hw.rb +4 -0
- data/examples/template_server/iowa/Content.iwa +121 -0
- data/examples/template_server/iowa/Content.view +0 -0
- data/examples/template_server/iowa/DBContentDispatcher.rb +112 -0
- data/examples/template_server/iowa/DBContentPage.html +3 -0
- data/examples/template_server/iowa/DBContentPage.iwa +85 -0
- data/examples/template_server/iowa/app.cnf +13 -0
- data/examples/template_server/iowa/app.rb +5 -0
- data/ext/Classifier/classifier.c +256 -0
- data/ext/Classifier/ext_help.h +14 -0
- data/ext/Classifier/extconf.rb +5 -0
- data/ext/Classifier/tst.h +40 -0
- data/ext/Classifier/tst_cleanup.c +24 -0
- data/ext/Classifier/tst_delete.c +146 -0
- data/ext/Classifier/tst_grow_node_free_list.c +38 -0
- data/ext/Classifier/tst_init.c +41 -0
- data/ext/Classifier/tst_insert.c +192 -0
- data/ext/Classifier/tst_search.c +68 -0
- data/ext/http11/README +11 -0
- data/ext/http11/ext_help.h +15 -0
- data/ext/http11/extconf.rb +5 -0
- data/ext/http11/http11.c +534 -0
- data/ext/http11/http11.c.dif +422 -0
- data/ext/http11/http11_parser.c +1243 -0
- data/ext/http11/http11_parser.c.dif +193 -0
- data/ext/http11/http11_parser.h +49 -0
- data/ext/http11/http11_parser.h.dif +20 -0
- data/ext/http11/http11_parser.rl +192 -0
- data/ext/httpmachine/Makefile +149 -0
- data/ext/httpmachine/extconf.rb +33 -0
- data/ext/httpmachine/http.cpp +430 -0
- data/ext/httpmachine/http.h +156 -0
- data/ext/httpmachine/rubyhttp.cpp +165 -0
- data/external/mime-types/LICENCE +18 -0
- data/external/mime-types/README +46 -0
- data/external/mime-types/doc/classes/MIME.html +120 -0
- data/external/mime-types/doc/classes/MIME/InvalidContentType.html +119 -0
- data/external/mime-types/doc/classes/MIME/Type.html +866 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000010.html +22 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000011.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000012.html +19 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000013.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000014.html +26 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000015.html +33 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000016.html +27 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000017.html +35 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000018.html +34 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000019.html +24 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000020.html +38 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000021.html +22 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000022.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000023.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000024.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000025.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000026.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000027.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000028.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000029.html +18 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000030.html +19 -0
- data/external/mime-types/doc/classes/MIME/Type.src/M000031.html +26 -0
- data/external/mime-types/doc/classes/MIME/Types.html +459 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000001.html +19 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000002.html +32 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000003.html +21 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000004.html +18 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000005.html +26 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000006.html +18 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000007.html +18 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000008.html +18 -0
- data/external/mime-types/doc/classes/MIME/Types.src/M000009.html +18 -0
- data/external/mime-types/doc/created.rid +1 -0
- data/external/mime-types/doc/files/ChangeLog.html +320 -0
- data/external/mime-types/doc/files/README.html +145 -0
- data/external/mime-types/doc/files/lib/mime/types_rb.html +101 -0
- data/external/mime-types/doc/fr_class_index.html +30 -0
- data/external/mime-types/doc/fr_file_index.html +29 -0
- data/external/mime-types/doc/fr_method_index.html +57 -0
- data/external/mime-types/doc/index.html +24 -0
- data/external/mime-types/doc/rdoc-style.css +208 -0
- data/external/mime-types/lib/mime/types.rb +1558 -0
- data/external/package.rb +672 -0
- data/external/test_support.rb +95 -0
- data/external/tmail/README +7 -0
- data/external/tmail/tmail.rb +4 -0
- data/external/tmail/tmail/address.rb +222 -0
- data/external/tmail/tmail/base64.rb +52 -0
- data/external/tmail/tmail/compat.rb +39 -0
- data/external/tmail/tmail/config.rb +50 -0
- data/external/tmail/tmail/encode.rb +447 -0
- data/external/tmail/tmail/header.rb +895 -0
- data/external/tmail/tmail/info.rb +14 -0
- data/external/tmail/tmail/loader.rb +1 -0
- data/external/tmail/tmail/mail.rb +869 -0
- data/external/tmail/tmail/mailbox.rb +386 -0
- data/external/tmail/tmail/mbox.rb +1 -0
- data/external/tmail/tmail/net.rb +260 -0
- data/external/tmail/tmail/obsolete.rb +123 -0
- data/external/tmail/tmail/parser.rb +1475 -0
- data/external/tmail/tmail/parser.y +372 -0
- data/external/tmail/tmail/port.rb +356 -0
- data/external/tmail/tmail/scanner.rb +17 -0
- data/external/tmail/tmail/scanner_r.rb +243 -0
- data/external/tmail/tmail/stringio.rb +256 -0
- data/external/tmail/tmail/textutils.rb +197 -0
- data/external/tmail/tmail/tmail.rb +1 -0
- data/external/tmail/tmail/utils.rb +23 -0
- data/external/win32-process/README +133 -0
- data/external/win32-process/lib/win32/process.rb +561 -0
- data/external/windows-pr/README +145 -0
- data/external/windows-pr/doc/conversion_guide.txt +25 -0
- data/external/windows-pr/lib/windows/clipboard.rb +72 -0
- data/external/windows-pr/lib/windows/console.rb +323 -0
- data/external/windows-pr/lib/windows/device_io.rb +88 -0
- data/external/windows-pr/lib/windows/directory.rb +80 -0
- data/external/windows-pr/lib/windows/error.rb +313 -0
- data/external/windows-pr/lib/windows/eventlog.rb +120 -0
- data/external/windows-pr/lib/windows/file.rb +349 -0
- data/external/windows-pr/lib/windows/filesystem.rb +16 -0
- data/external/windows-pr/lib/windows/handle.rb +31 -0
- data/external/windows-pr/lib/windows/library.rb +76 -0
- data/external/windows-pr/lib/windows/limits.rb +13 -0
- data/external/windows-pr/lib/windows/memory.rb +117 -0
- data/external/windows-pr/lib/windows/msvcrt/buffer.rb +48 -0
- data/external/windows-pr/lib/windows/msvcrt/file.rb +18 -0
- data/external/windows-pr/lib/windows/msvcrt/string.rb +46 -0
- data/external/windows-pr/lib/windows/national.rb +557 -0
- data/external/windows-pr/lib/windows/path.rb +296 -0
- data/external/windows-pr/lib/windows/pipe.rb +77 -0
- data/external/windows-pr/lib/windows/process.rb +171 -0
- data/external/windows-pr/lib/windows/registry.rb +238 -0
- data/external/windows-pr/lib/windows/security.rb +89 -0
- data/external/windows-pr/lib/windows/service.rb +183 -0
- data/external/windows-pr/lib/windows/shell.rb +88 -0
- data/external/windows-pr/lib/windows/sound.rb +52 -0
- data/external/windows-pr/lib/windows/synchronize.rb +161 -0
- data/external/windows-pr/lib/windows/system_info.rb +70 -0
- data/external/windows-pr/lib/windows/unicode.rb +138 -0
- data/external/windows-pr/lib/windows/window.rb +22 -0
- data/iowa.gemspec +45 -0
- data/microprojects/DiskCache/LICENSE +28 -0
- data/microprojects/DiskCache/README +17 -0
- data/microprojects/DiskCache/external/package.rb +608 -0
- data/microprojects/DiskCache/external/test_support.rb +8 -0
- data/microprojects/DiskCache/setup.rb +22 -0
- data/microprojects/DiskCache/src/iowa/Association.rb +67 -0
- data/microprojects/DiskCache/src/iowa/Constants.rb +159 -0
- data/microprojects/DiskCache/src/iowa/DiskStore.rb +377 -0
- data/microprojects/DiskCache/src/iowa/Hash.rb +63 -0
- data/microprojects/DiskCache/src/iowa/Lockfile.rb +575 -0
- data/microprojects/DiskCache/src/iowa/Mutex.rb +142 -0
- data/microprojects/DiskCache/src/iowa/caches/DiskCache.rb +605 -0
- data/microprojects/DiskCache/src/iowa/caches/LRUCache.rb +287 -0
- data/microprojects/DiskCache/test/TC_DiskCache.rb +218 -0
- data/microprojects/LRUCache/LICENSE +28 -0
- data/microprojects/LRUCache/README +13 -0
- data/microprojects/LRUCache/external/package.rb +608 -0
- data/microprojects/LRUCache/external/test_support.rb +8 -0
- data/microprojects/LRUCache/setup.rb +22 -0
- data/microprojects/LRUCache/src/iowa/Association.rb +57 -0
- data/microprojects/LRUCache/src/iowa/Constants.rb +159 -0
- data/microprojects/LRUCache/src/iowa/Hash.rb +63 -0
- data/microprojects/LRUCache/src/iowa/Mutex.rb +129 -0
- data/microprojects/LRUCache/src/iowa/caches/LRUCache.rb +287 -0
- data/microprojects/LRUCache/test/TC_LRUCache.rb +65 -0
- data/microprojects/LinkedList/LICENSE +28 -0
- data/microprojects/LinkedList/README +13 -0
- data/microprojects/LinkedList/external/package.rb +608 -0
- data/microprojects/LinkedList/external/test_support.rb +8 -0
- data/microprojects/LinkedList/setup.rb +22 -0
- data/microprojects/LinkedList/src/iowa/LinkedList.rb +165 -0
- data/microprojects/LinkedList/test/TC_LinkedList.rb +42 -0
- data/microprojects/README +8 -0
- data/setup.rb +116 -0
- data/share/iowa/app_skeleton/Main.html +8 -0
- data/share/iowa/app_skeleton/Main.iwa +15 -0
- data/share/iowa/app_skeleton/app.cnf +48 -0
- data/share/iowa/app_skeleton/app.rb +58 -0
- data/share/iowa/app_skeleton/models/model.rb +49 -0
- data/src/ihc.rb +223 -0
- data/src/iowa.cgi +29 -0
- data/src/iowa.rb +637 -0
- data/src/iowa/AbstractCache.rb +96 -0
- data/src/iowa/AcceptLanguage.rb +76 -0
- data/src/iowa/Application.rb +928 -0
- data/src/iowa/ApplicationStats.rb +72 -0
- data/src/iowa/Association.rb +67 -0
- data/src/iowa/BindingsParser.rb +62 -0
- data/src/iowa/Breakpoint.rb +273 -0
- data/src/iowa/CSS.rb +564 -0
- data/src/iowa/Client.rb +192 -0
- data/src/iowa/Component.rb +405 -0
- data/src/iowa/ComponentProxy.rb +26 -0
- data/src/iowa/Config.rb +21 -0
- data/src/iowa/Constants.rb +226 -0
- data/src/iowa/Context.rb +218 -0
- data/src/iowa/ContextLogger.rb +16 -0
- data/src/iowa/DbPool.rb +222 -0
- data/src/iowa/DetachedComponent.rb +18 -0
- data/src/iowa/Dispatcher.rb +27 -0
- data/src/iowa/DynamicElements.rb +471 -0
- data/src/iowa/Element.rb +100 -0
- data/src/iowa/Email.rb +287 -0
- data/src/iowa/Extensions/AllExtensions.rb +4 -0
- data/src/iowa/Extensions/Class.rb +94 -0
- data/src/iowa/Extensions/Date.rb +88 -0
- data/src/iowa/Extensions/DateTime.rb +88 -0
- data/src/iowa/Extensions/Hash.rb +22 -0
- data/src/iowa/Extensions/Kernel.rb +6 -0
- data/src/iowa/Extensions/Numeric.rb +47 -0
- data/src/iowa/Extensions/Object.rb +11 -0
- data/src/iowa/Extensions/String.rb +60 -0
- data/src/iowa/Extensions/Time.rb +89 -0
- data/src/iowa/Extensions/TimeExtensions.rb +6 -0
- data/src/iowa/Form.rb +368 -0
- data/src/iowa/Hash.rb +85 -0
- data/src/iowa/ISAAC.rb +175 -0
- data/src/iowa/ImageSize.rb +279 -0
- data/src/iowa/IowaComponentMixins.rb +7 -0
- data/src/iowa/JSON-lexer.rb +296 -0
- data/src/iowa/JSON-objects.rb +201 -0
- data/src/iowa/KeyValueCoding.rb +91 -0
- data/src/iowa/LinkedList.rb +175 -0
- data/src/iowa/Loader.rb +22 -0
- data/src/iowa/Lockfile.rb +575 -0
- data/src/iowa/Logger.rb +74 -0
- data/src/iowa/Monkey.rb +20 -0
- data/src/iowa/Mutex.rb +142 -0
- data/src/iowa/Policy.rb +70 -0
- data/src/iowa/Pool.rb +243 -0
- data/src/iowa/PrettyException.rb +1091 -0
- data/src/iowa/Request.rb +244 -0
- data/src/iowa/Response.rb +133 -0
- data/src/iowa/Session.rb +354 -0
- data/src/iowa/SessionStats.rb +78 -0
- data/src/iowa/String.rb +65 -0
- data/src/iowa/Tag.rb +101 -0
- data/src/iowa/TemplateParser.rb +236 -0
- data/src/iowa/Util.rb +314 -0
- data/src/iowa/Webcache.rb +122 -0
- data/src/iowa/caches/BiLevelCache.rb +65 -0
- data/src/iowa/caches/ClassLimitedCache.rb +67 -0
- data/src/iowa/caches/DiskCache.rb +609 -0
- data/src/iowa/caches/DiskStore.rb +380 -0
- data/src/iowa/caches/LRUCache-alternative.rb +155 -0
- data/src/iowa/caches/LRUCache.rb +290 -0
- data/src/iowa/caches/SimpleLRUCache.rb +112 -0
- data/src/iowa/dispatchers/StandardDispatcher.rb +396 -0
- data/src/iowa/dispatchers/StandardDispatcherWithClassifier.rb +93 -0
- data/src/iowa/js/iowa_jsonrpc.js +381 -0
- data/src/iowa/js/jsonrpc.js +187 -0
- data/src/iowa/js/jsonrpc_async.js +261 -0
- data/src/iowa/loaders/DiskLoader.rb +50 -0
- data/src/iowa/loggers/Analogger.rb +54 -0
- data/src/iowa/loggers/AsyncLogger.rb +54 -0
- data/src/iowa/loggers/BitBucket.rb +38 -0
- data/src/iowa/loggers/Log4R.rb +13 -0
- data/src/iowa/loggers/Log4rLogger.rb +48 -0
- data/src/iowa/loggers/Logger.rb +29 -0
- data/src/iowa/loggers/RubyLogger.rb +9 -0
- data/src/iowa/pools/DBConnectionPool.rb +53 -0
- data/src/iowa/request/Apache.rb +90 -0
- data/src/iowa/request/EMHybrid.rb +59 -0
- data/src/iowa/request/ENV.rb +80 -0
- data/src/iowa/request/FCGI.rb +68 -0
- data/src/iowa/request/HTTPMachine.rb +75 -0
- data/src/iowa/request/Mongrel.rb +68 -0
- data/src/iowa/request/WEBrick.rb +48 -0
- data/src/iowa/version.rb +3 -0
- data/src/iowa/webrick/HTTPServer.rb +43 -0
- data/src/iowa/webrick/WEBrickServlet.rb +28 -0
- data/src/iowa_fcgi_handler.rb +101 -0
- data/src/iowa_httpmachine.rb +141 -0
- data/src/iowa_hybrid.rb +193 -0
- data/src/iowa_hybrid_cluster.rb +231 -0
- data/src/iowa_mongrel.rb +136 -0
- data/src/iowa_webrick.rb +194 -0
- data/src/iowa_webrick_legacy.rb +104 -0
- data/src/mod_iowa.rb +104 -0
- data/tcss.rb +61 -0
- data/test/README.windows +12 -0
- data/test/TC_AcceptLanguage.rb +61 -0
- data/test/TC_AppConfig.rb +43 -0
- data/test/TC_AppConfig/cgi/iowa.cgi +7 -0
- data/test/TC_AppConfig/doc/index.html +1 -0
- data/test/TC_AppConfig/iowa/Main.html +4 -0
- data/test/TC_AppConfig/iowa/Main.iwa +17 -0
- data/test/TC_AppConfig/iowa/README +1 -0
- data/test/TC_AppConfig/iowa/app.cnf +19 -0
- data/test/TC_AppConfig/iowa/app.rb +8 -0
- data/test/TC_AppConfig/webrick.rb +38 -0
- data/test/TC_Association.rb +29 -0
- data/test/TC_BiLevelCache.rb +71 -0
- data/test/TC_CGI_Adaptor.rb +55 -0
- data/test/TC_CGI_Adaptor/cgi/iowa.cgi +7 -0
- data/test/TC_CGI_Adaptor/doc/index.html +1 -0
- data/test/TC_CGI_Adaptor/iowa/Main.html +8 -0
- data/test/TC_CGI_Adaptor/iowa/Main.iwa +14 -0
- data/test/TC_CGI_Adaptor/iowa/README +1 -0
- data/test/TC_CGI_Adaptor/iowa/app.cnf +8 -0
- data/test/TC_CGI_Adaptor/iowa/app.rb +8 -0
- data/test/TC_CGI_Adaptor/webrick.rb +38 -0
- data/test/TC_CSS.rb +660 -0
- data/test/TC_ClassLimitedCache.rb +89 -0
- data/test/TC_Classifier.rb +80 -0
- data/test/TC_DbPool.rb +127 -0
- data/test/TC_DiskCache.rb +218 -0
- data/test/TC_Hybrid.rb +58 -0
- data/test/TC_Hybrid/doc/thing.txt +1 -0
- data/test/TC_Hybrid/iowa/Main.html +3 -0
- data/test/TC_Hybrid/iowa/Main.iwa +7 -0
- data/test/TC_Hybrid/iowa/NewPage.html +1 -0
- data/test/TC_Hybrid/iowa/NewPage.iwa +5 -0
- data/test/TC_Hybrid/iowa/app.cnf +10 -0
- data/test/TC_Hybrid/iowa/app.rb +5 -0
- data/test/TC_IOWAFunctions/doc/Ajax1.html +1 -0
- data/test/TC_IOWAFunctions/doc/Ajax1.iwa +1 -0
- data/test/TC_IOWAFunctions/doc/index.html +1 -0
- data/test/TC_IOWAFunctions/doc/js/dojo.js +9686 -0
- data/test/TC_IOWAFunctions/iowa/Ajax1.html +40 -0
- data/test/TC_IOWAFunctions/iowa/Ajax1.iwa +23 -0
- data/test/TC_IOWAFunctions/iowa/AjaxWidget.iwa +19 -0
- data/test/TC_IOWAFunctions/iowa/AjaxWidget.view +22 -0
- data/test/TC_IOWAFunctions/iowa/DanielTest.html +9 -0
- data/test/TC_IOWAFunctions/iowa/DanielTest.iwa +10 -0
- data/test/TC_IOWAFunctions/iowa/IntervalWidget.html +1 -0
- data/test/TC_IOWAFunctions/iowa/IntervalWidget.iwa +14 -0
- data/test/TC_IOWAFunctions/iowa/Main.html +1 -0
- data/test/TC_IOWAFunctions/iowa/NestedRepeat1.html +12 -0
- data/test/TC_IOWAFunctions/iowa/NestedRepeat1.iwa +24 -0
- data/test/TC_IOWAFunctions/iowa/RPCResponse.iwa +7 -0
- data/test/TC_IOWAFunctions/iowa/RPCResponse.view +1 -0
- data/test/TC_IOWAFunctions/iowa/Repeat1.iwa +31 -0
- data/test/TC_IOWAFunctions/iowa/Repeat1.view +9 -0
- data/test/TC_IOWAFunctions/iowa/Repeat2.iwa +32 -0
- data/test/TC_IOWAFunctions/iowa/Repeat2.view +11 -0
- data/test/TC_IOWAFunctions/iowa/Repeat3.iwa +44 -0
- data/test/TC_IOWAFunctions/iowa/Repeat3.view +18 -0
- data/test/TC_IOWAFunctions/iowa/TesCon.html +1 -0
- data/test/TC_IOWAFunctions/iowa/TesCon.iwa +5 -0
- data/test/TC_IOWAFunctions/iowa/app.cnf +19 -0
- data/test/TC_IOWAFunctions/iowa/app.rb +9 -0
- data/test/TC_IOWAFunctions/iowa/mapfile.cnf +8 -0
- data/test/TC_ISAAC.rb +52 -0
- data/test/TC_ImageSize.rb +84 -0
- data/test/TC_ImageSize/img.bmp +0 -0
- data/test/TC_ImageSize/img.gif +0 -0
- data/test/TC_ImageSize/img.jpg +0 -0
- data/test/TC_ImageSize/img.pcx +0 -0
- data/test/TC_ImageSize/img.pgm +7144 -0
- data/test/TC_ImageSize/img.png +0 -0
- data/test/TC_ImageSize/img.ppm +0 -0
- data/test/TC_ImageSize/img.psd +0 -0
- data/test/TC_ImageSize/img.tiff +0 -0
- data/test/TC_ImageSize/img.xbm +22 -0
- data/test/TC_KeyValueCoding.rb +35 -0
- data/test/TC_LRUCache.rb +296 -0
- data/test/TC_LinkedList.rb +46 -0
- data/test/TC_Lockfile.rb +106 -0
- data/test/TC_Minimal.rb +45 -0
- data/test/TC_Minimal/app.cnf +8 -0
- data/test/TC_Minimal/cgi-bin/iowa.cgi +11 -0
- data/test/TC_Minimal/doc/index.html +1 -0
- data/test/TC_Minimal/iowa/Main.html +1 -0
- data/test/TC_Minimal/iowa/README +1 -0
- data/test/TC_Minimal/iowa/app.rb +3 -0
- data/test/TC_Minimal/webrick.rb +38 -0
- data/test/TC_Mongrel.rb +58 -0
- data/test/TC_Mongrel/doc/thing.txt +1 -0
- data/test/TC_Mongrel/iowa/Main.html +3 -0
- data/test/TC_Mongrel/iowa/Main.iwa +7 -0
- data/test/TC_Mongrel/iowa/NewPage.html +1 -0
- data/test/TC_Mongrel/iowa/NewPage.iwa +5 -0
- data/test/TC_Mongrel/iowa/app.cnf +10 -0
- data/test/TC_Mongrel/iowa/app.rb +5 -0
- data/test/TC_NoSubclass.rb +56 -0
- data/test/TC_NoSubclass/cgi/iowa.cgi +7 -0
- data/test/TC_NoSubclass/doc/index.html +1 -0
- data/test/TC_NoSubclass/iowa/Main.html +8 -0
- data/test/TC_NoSubclass/iowa/Main.iwa +14 -0
- data/test/TC_NoSubclass/iowa/README +1 -0
- data/test/TC_NoSubclass/iowa/app.cnf +8 -0
- data/test/TC_NoSubclass/iowa/app.rb +5 -0
- data/test/TC_NoSubclass/webrick.rb +38 -0
- data/test/TC_Pool.rb +139 -0
- data/test/TC_RenderedCache/doc/thing.txt +1 -0
- data/test/TC_RenderedCache/iowa/BigPage.html +1 -0
- data/test/TC_RenderedCache/iowa/BigPage.iwa +12 -0
- data/test/TC_RenderedCache/iowa/Main.html +3 -0
- data/test/TC_RenderedCache/iowa/Main.iwa +7 -0
- data/test/TC_RenderedCache/iowa/NewPage.html +1 -0
- data/test/TC_RenderedCache/iowa/NewPage.iwa +11 -0
- data/test/TC_RenderedCache/iowa/app.cnf +13 -0
- data/test/TC_RenderedCache/iowa/app.rb +5 -0
- data/test/TC_RenderedCache/iowa/mapfile.map +4 -0
- data/test/TC_ResourceURL.rb +73 -0
- data/test/TC_ResourceURL/iowa/Main.html +2 -0
- data/test/TC_ResourceURL/iowa/Main.iwa +10 -0
- data/test/TC_ResourceURL/iowa/app.cnf +10 -0
- data/test/TC_ResourceURL/iowa/app.rb +5 -0
- data/test/TC_SimpleDetached.rb +41 -0
- data/test/TC_StandardDispatcher.rb +362 -0
- data/test/TC_StandardDispatcherWithClassifier.rb +358 -0
- data/test/TC_String.rb +24 -0
- data/test/TC_Tag.rb +41 -0
- data/test/TC_Webrick.rb +56 -0
- data/test/TC_Webrick/doc/thing.txt +1 -0
- data/test/TC_Webrick/iowa/Main.html +3 -0
- data/test/TC_Webrick/iowa/Main.iwa +7 -0
- data/test/TC_Webrick/iowa/NewPage.html +1 -0
- data/test/TC_Webrick/iowa/NewPage.iwa +5 -0
- data/test/TC_Webrick/iowa/app.cnf +10 -0
- data/test/TC_Webrick/iowa/app.rb +5 -0
- data/test/tc_template.rb +15 -0
- data/test/tests.conf +19 -0
- data/utils/CVS/Entries +3 -0
- data/utils/CVS/Repository +1 -0
- data/utils/CVS/Root +1 -0
- data/utils/QuickCert-1.0.2.tar.gz +0 -0
- data/utils/QuickCert-1.0.2/InstalledFiles +7 -0
- data/utils/QuickCert-1.0.2/MANIFEST +10 -0
- data/utils/QuickCert-1.0.2/Makefile +15 -0
- data/utils/QuickCert-1.0.2/README +56 -0
- data/utils/QuickCert-1.0.2/bin/QuickCert +355 -0
- data/utils/QuickCert-1.0.2/config.save +12 -0
- data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/README +60 -0
- data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_c.rb +26 -0
- data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_s.rb +35 -0
- data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/qc_config +21 -0
- data/utils/QuickCert-1.0.2/lib/QuickCert/defaults.rb +28 -0
- data/utils/QuickCert-1.0.2/setup.rb +1312 -0
- data/utils/iowa_apps +422 -0
- data/utils/smtp_sink.rb +9 -0
- data/utils/startup_template.cnf +27 -0
- data/utils/startup_template.rb +73 -0
- metadata +551 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# This file illustrates the methods that any cache implementation
|
|
2
|
+
# must expose in order for IOWA to use it. An application will
|
|
3
|
+
# default to using the LRUCache unless told otherwise.
|
|
4
|
+
|
|
5
|
+
require 'thread'
|
|
6
|
+
require 'iowa/Constants'
|
|
7
|
+
require 'iowa/Hash'
|
|
8
|
+
|
|
9
|
+
module Iowa
|
|
10
|
+
|
|
11
|
+
# Caches must be thread safe.
|
|
12
|
+
|
|
13
|
+
class AbstractCache
|
|
14
|
+
|
|
15
|
+
# Initialize the empty cache. The initialization must accept a hash as
|
|
16
|
+
# an argument, and must accept, at a minimum, the following key/value
|
|
17
|
+
# pairs in the hash as arguments:
|
|
18
|
+
# :maxsize -- the maximum number of elements to cache.
|
|
19
|
+
# :maxttl -- the maximum age, in seconds, of an element in the cache.
|
|
20
|
+
#
|
|
21
|
+
# Every argument to the cache must have an acceptable default value.
|
|
22
|
+
|
|
23
|
+
def initialize(args = {Cmaxsize => 20, Cttl => nil})
|
|
24
|
+
if args.kind_of? ::Hash
|
|
25
|
+
oargs = args
|
|
26
|
+
args = Iowa::Hash.new
|
|
27
|
+
args.step_merge!(oargs)
|
|
28
|
+
end
|
|
29
|
+
args.stringify_keys! if args.respond_to? :stringify_keys!
|
|
30
|
+
begin
|
|
31
|
+
@max = args[Cmaxsize] || 20
|
|
32
|
+
@maxttl = args[Cttl]
|
|
33
|
+
@mutex = Mutex.new
|
|
34
|
+
rescue Exception
|
|
35
|
+
args = {Cmaxsize => 20, Cttl => nil}
|
|
36
|
+
retry
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Check to see if the cache contains the given key.
|
|
41
|
+
|
|
42
|
+
def include?(key)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Remove a key/value pair from the cache, by key.
|
|
46
|
+
|
|
47
|
+
def delete(key)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Return the element identified by the given key.
|
|
51
|
+
|
|
52
|
+
def [](key)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Set the element of the cache identified by the given key.
|
|
56
|
+
|
|
57
|
+
def []=(key, val)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Allows one to set the maximum size of the cache queue. If the queue
|
|
61
|
+
# is currently larger than the size that it is being set to, elements
|
|
62
|
+
# will be expired until the queue is at the maximum size.
|
|
63
|
+
|
|
64
|
+
def size=(max)
|
|
65
|
+
end
|
|
66
|
+
alias maxsize= size=
|
|
67
|
+
|
|
68
|
+
# Return the maximum size of the cache.
|
|
69
|
+
|
|
70
|
+
def maxsize
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Return the current size of the cache.
|
|
74
|
+
|
|
75
|
+
def size
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Return a copy of current set of keys to cache elements.
|
|
79
|
+
|
|
80
|
+
def queue
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Adds a finalization method to the cache that will be called before
|
|
84
|
+
# the object in the cache is expired.
|
|
85
|
+
|
|
86
|
+
def add_finalizer(*args,&block)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Is called when an object in the cache is expired. Iterates through
|
|
90
|
+
# the defined finalization methods, if any.
|
|
91
|
+
|
|
92
|
+
def do_finalization(key,obj)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'iowa/caches/LRUCache'
|
|
2
|
+
require 'iowa/Constants'
|
|
3
|
+
|
|
4
|
+
module Iowa
|
|
5
|
+
class AcceptLanguage
|
|
6
|
+
|
|
7
|
+
attr_accessor :default
|
|
8
|
+
|
|
9
|
+
QFRXP = /\s*;\s*/
|
|
10
|
+
|
|
11
|
+
def initialize(default = Cen)
|
|
12
|
+
@slf = {default => {}}
|
|
13
|
+
@default = default
|
|
14
|
+
@al_cache = Iowa::Caches::LRUCache.new({:maxsize => 100})
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def []=(k,v)
|
|
18
|
+
language,dialect = k.split(C_dash,2)
|
|
19
|
+
if @slf.has_key?(language)
|
|
20
|
+
@slf[language][dialect] = v
|
|
21
|
+
else
|
|
22
|
+
@slf[language] = {dialect => v}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def [](v)
|
|
27
|
+
language,dialect = v.split(C_dash,2)
|
|
28
|
+
@slf.has_key?(language) ? @slf[language][dialect] : nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def generate_language_sequence(alstring)
|
|
32
|
+
seq = []
|
|
33
|
+
alstring.split(C_comma).each do |spec|
|
|
34
|
+
language,qf = spec.split(QFRXP)
|
|
35
|
+
qf.sub!(/q=/,C_empty) if qf
|
|
36
|
+
qf = C_1_0 unless qf.to_s != C_empty
|
|
37
|
+
seq << [language,qf.to_f]
|
|
38
|
+
end
|
|
39
|
+
seq.sort_by {|a| a[1]}.reverse
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def match(alstring)
|
|
43
|
+
return @al_cache[alstring] if @al_cache.include?(alstring)
|
|
44
|
+
r = nil
|
|
45
|
+
seq = generate_language_sequence(alstring)
|
|
46
|
+
seq.each do |litem|
|
|
47
|
+
language,dialect = litem.first.split(C_dash)
|
|
48
|
+
break if @slf[language] and r = @slf[language][dialect]
|
|
49
|
+
end
|
|
50
|
+
r ||= @slf[Cen][nil]
|
|
51
|
+
@al_cache[alstring] = r
|
|
52
|
+
r
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def languages
|
|
56
|
+
r = []
|
|
57
|
+
@slf.each do |language,dlcts|
|
|
58
|
+
dlcts.each_key do |dialect|
|
|
59
|
+
r << (dialect ? "#{language}-#{dialect}" : language)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
r
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def dialects(language)
|
|
66
|
+
r = []
|
|
67
|
+
if @slf.has_key?(language)
|
|
68
|
+
@slf[language].each_key do |dialect|
|
|
69
|
+
r << dialect ? "#{language}-#{dialect}" : language
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
r
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,928 @@
|
|
|
1
|
+
require 'weakref'
|
|
2
|
+
require 'thread'
|
|
3
|
+
#require 'log4r'
|
|
4
|
+
#include Log4r
|
|
5
|
+
require 'iowa/Config'
|
|
6
|
+
require 'iowa/String'
|
|
7
|
+
#require 'iowa/ISAAC'
|
|
8
|
+
require 'iowa/ApplicationStats'
|
|
9
|
+
require 'iowa/IowaComponentMixins'
|
|
10
|
+
require 'iowa/Request'
|
|
11
|
+
|
|
12
|
+
module Iowa
|
|
13
|
+
|
|
14
|
+
class NoDispatcherFound < LoadError; end
|
|
15
|
+
class NoCacheFound < LoadError; end
|
|
16
|
+
class NoPolicyFound < LoadError; end
|
|
17
|
+
class NoLoggerFound < LoadError; end
|
|
18
|
+
|
|
19
|
+
# Application sits at the top of everything. This class represents an
|
|
20
|
+
# entire Iowa application and handles the things relevant to the application
|
|
21
|
+
# as a whole.
|
|
22
|
+
#
|
|
23
|
+
# TODO: Move the configuration object into the Application and lay the
|
|
24
|
+
# groundwork for allowing more than one application in a process.
|
|
25
|
+
class Application
|
|
26
|
+
|
|
27
|
+
DocRootNames = [nil,'docs','doc','htdocs','htdoc'].freeze
|
|
28
|
+
CGIRootNames = [nil,'cgi','cgi-bin'].freeze
|
|
29
|
+
LogRootNames = [nil,'log','logs'].freeze
|
|
30
|
+
|
|
31
|
+
module ContentClasses; end
|
|
32
|
+
Content_Classes = ContentClasses
|
|
33
|
+
|
|
34
|
+
attr_accessor :location, :serial_number, :policy
|
|
35
|
+
|
|
36
|
+
unless Object.const_defined?(:BindingCommentsRegexp)
|
|
37
|
+
BindingCommentsRegexp = /^\s*#.*$/
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@applicationClass = self
|
|
41
|
+
|
|
42
|
+
def self.root_directory
|
|
43
|
+
if RUBY_VERSION =~ /^1\.8/
|
|
44
|
+
Dir.getwd # fix this
|
|
45
|
+
else
|
|
46
|
+
File.dirname( File.expand_path( Process.argv0 ) )
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.applicationClass
|
|
51
|
+
@applicationClass
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.applicationClass=(val)
|
|
55
|
+
@applicationClass = val
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Returns a new instance of Application
|
|
59
|
+
|
|
60
|
+
def self.newApplication(*args)
|
|
61
|
+
@applicationClass.new(*args)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Allows one to specify a subclass to be used when creating new
|
|
65
|
+
# objects with newApplication().
|
|
66
|
+
|
|
67
|
+
def self.inherited(subclass)
|
|
68
|
+
@applicationClass = subclass
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Deprecated. Set/use in the config file/config object.
|
|
72
|
+
def self.cachedSessions
|
|
73
|
+
Iowa.config[Capplication][Csessioncache][Cmaxsize] ||= 300
|
|
74
|
+
Iowa.config[Capplication][Csessioncache][Cmaxsize]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.cachedSessions=(val)
|
|
78
|
+
Iowa.config[Capplication][Csessioncache][Cmaxsize] = val
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Deprecated. Set/use in the config file/config object.
|
|
82
|
+
def self.cacheTTL
|
|
83
|
+
Iowa.config[Capplication][Csessioncache][Cttl]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.cacheTTL=(val)
|
|
87
|
+
Iowa.config[Capplication][Csessioncache][Cttl] = val
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def self.iowa_path
|
|
91
|
+
ic = Iowa.config[Capplication]
|
|
92
|
+
if ic[Ciowa_path].nil? or ic[Ciowa_path].empty?
|
|
93
|
+
ic[Ciowa_path] = [iowa_root]
|
|
94
|
+
end
|
|
95
|
+
ic[Ciowa_path]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def self.iowa_path=(val)
|
|
99
|
+
Iowa.config[Capplication][Ciowa_path] = val.is_a?(Array) ?
|
|
100
|
+
val :
|
|
101
|
+
[val.to_s]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def iowa_path
|
|
105
|
+
self.class.iowa_path
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def iowa_path=(val)
|
|
109
|
+
self.class.iowa_path = val
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.iowa_root
|
|
113
|
+
ic = Iowa.config[Capplication]
|
|
114
|
+
if (ic[Croot_path].nil? or ic[Croot_path].empty?) and (ic[Ciowa_root].nil? or ic[Ciowa_root].empty?)
|
|
115
|
+
ic[Croot_path] = ic[Ciowa_root] = Application.root_directory
|
|
116
|
+
elsif ic[Ciowa_root].nil? or ic[Ciowa_root].empty?
|
|
117
|
+
ic[Ciowa_root] = ic[Croot_path]
|
|
118
|
+
elsif ic[Croot_path].nil? or ic[Croot_path].empty?
|
|
119
|
+
ic[Croot_path] = ic[Ciowa_root]
|
|
120
|
+
end
|
|
121
|
+
Iowa.config[Capplication][Ciowa_root]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def self.iowa_root=(val)
|
|
125
|
+
Iowa.config[Capplication][Croot_path] = Iowa.config[Capplication][Ciowa_root] = val
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def iowa_root
|
|
129
|
+
self.class.iowa_root
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def iowa_root=(val)
|
|
133
|
+
self.class.iowa_root = val
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def self.root_path
|
|
137
|
+
iowa_root
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def self.root_path=(val)
|
|
141
|
+
iowa_root = val
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def root_path
|
|
145
|
+
self.class.root_path
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def root_path=(val)
|
|
149
|
+
self.class.root_path = val
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
def self.find_app_root_dir(names,item)
|
|
154
|
+
ic = Iowa.config[Capplication]
|
|
155
|
+
if ic[item].nil? or ic[item].empty?
|
|
156
|
+
iwabd = File.dirname(iowa_root)
|
|
157
|
+
iwadr = names.inject(nil) {|dr,n| FileTest.exist?(File.join([iwabd,n].select {|x|x})) ? (dr = n) : dr}
|
|
158
|
+
ic[item] = iwadr ? File.join(iwabd,iwadr) : nil
|
|
159
|
+
ic[item]
|
|
160
|
+
else
|
|
161
|
+
ic[item]
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
public
|
|
165
|
+
|
|
166
|
+
def self.doc_root
|
|
167
|
+
dr = Iowa.config[Capplication][Cdoc_root]
|
|
168
|
+
(dr.nil? or dr.empty?) ? find_app_root_dir(DocRootNames,Cdoc_root) : dr
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def self.doc_root=(val)
|
|
172
|
+
Iowa.config[Capplication][Cdoc_root] = val
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def doc_root
|
|
176
|
+
self.class.doc_root
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def doc_root=(val)
|
|
180
|
+
self.class.doc_root = val
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def self.cgi_root
|
|
184
|
+
find_app_root_dir(CGIRootNames,Ccgi_root)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def self.cgi_root=(val)
|
|
188
|
+
Iowa.config[Capplication][Ccgi_root] = val
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def cgi_root
|
|
192
|
+
self.class.cgi_root
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def cgi_root=(val)
|
|
196
|
+
self.class.cgi_root = val
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def self.log_root
|
|
200
|
+
find_app_root_dir(LogRootNames,Clog_root)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def self.log_root=(val)
|
|
204
|
+
Iowa.config[Capplication][Clog_root] = val
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def log_root
|
|
208
|
+
self.class.log_root
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def log_root=(val)
|
|
212
|
+
self.class.log_root = val
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
class << self
|
|
216
|
+
alias_method :iowaroot, :iowa_root
|
|
217
|
+
alias_method :iowaroot=, :iowa_root=
|
|
218
|
+
alias_method :rootpath, :root_path
|
|
219
|
+
alias_method :rootpath=, :root_path=
|
|
220
|
+
alias_method :docroot, :doc_root
|
|
221
|
+
alias_method :docroot=, :doc_root=
|
|
222
|
+
alias_method :cgiroot, :cgi_root
|
|
223
|
+
alias_method :cgiroot=, :cgi_root=
|
|
224
|
+
alias_method :logroot, :log_root
|
|
225
|
+
alias_method :logroot=, :log_root=
|
|
226
|
+
end
|
|
227
|
+
alias_method :iowaroot, :iowa_root
|
|
228
|
+
alias_method :iowaroot=, :iowa_root=
|
|
229
|
+
alias_method :rootpath, :root_path
|
|
230
|
+
alias_method :rootpath=, :root_path=
|
|
231
|
+
alias_method :docroot, :doc_root
|
|
232
|
+
alias_method :docroot=, :doc_root=
|
|
233
|
+
alias_method :cgiroot, :cgi_root
|
|
234
|
+
alias_method :cgiroot=, :cgi_root=
|
|
235
|
+
alias_method :logroot, :log_root
|
|
236
|
+
alias_method :logroot=, :log_root=
|
|
237
|
+
|
|
238
|
+
def self.ViewFileSuffixes
|
|
239
|
+
@view_suffix_src ||= nil
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def self.ViewFileSuffixes=(val)
|
|
243
|
+
@view_suffix_src = val
|
|
244
|
+
@@view_suffixes = val.collect {|s| ".#{s}"}
|
|
245
|
+
@@view_regex = Regexp.new("\.#{val.join('$|\.')}$")
|
|
246
|
+
@@search_regex = Regexp.new("\.#{val.join('$|\.')}$|\\.bnd$")
|
|
247
|
+
@@view_file_regex = Regexp.new(".*\\/(.+)\\.(#{val.join('|')})")
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def self.Daemonize
|
|
251
|
+
Iowa.config[Capplication][Cdaemonize] = false unless Iowa.config[Capplication][Cdaemonize].is_a?(String)
|
|
252
|
+
Iowa.config[Capplication][Cdaemonize]
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def self.Daemonize=(args)
|
|
256
|
+
Iowa.config[Capplication][Cdaemonize] = args
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def self.Config
|
|
260
|
+
@config ||= nil
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def self.Config=(args)
|
|
264
|
+
@config = args
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def self.Dispatcher
|
|
268
|
+
@dispatcher ||= nil
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def self.Models
|
|
272
|
+
Iowa.config[Capplication][Cmodel][Cfiles] ||= []
|
|
273
|
+
Iowa.config[Capplication][Cmodel][Cfiles]
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def self.Models=(args)
|
|
277
|
+
if args.class.kind_of?(String)
|
|
278
|
+
Iowa.config[Capplication][Cmodel][Cfiles] = [args]
|
|
279
|
+
else
|
|
280
|
+
Iowa.config[Capplication][Cmodel][Cfiles] = args
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def self.Dispatcher=(args)
|
|
285
|
+
@dispatcher = Util.get_dispatcher(args)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def self.SessionCache
|
|
289
|
+
@session_cache ||= nil
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def self.SessionCache=(args)
|
|
293
|
+
@session_cache = Util.get_cache(args)
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def self.Policy
|
|
297
|
+
@policy ||= nil
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def self.Policy=(args)
|
|
301
|
+
@policy = Util.get_policy(args)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def self.Logger
|
|
305
|
+
@logger ||= nil
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def self.Logger=(args)
|
|
309
|
+
@logger = Util.get_logger(args)
|
|
310
|
+
Logger[Ciowa_log] = @logger
|
|
311
|
+
Iowa.const_set(:Log,@logger)
|
|
312
|
+
@logger
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def self.serializeCompiledTemplates
|
|
316
|
+
Iowa.config[Capplication][Cserialize_templates]
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def self.serializeCompiledTemplates=(val)
|
|
320
|
+
Iowa.config[Capplication][Cserialize_templates] = val
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# Performs all of the work necessary to start a new Iowa Application.
|
|
324
|
+
|
|
325
|
+
def initialize(docroot)
|
|
326
|
+
@model_mutex = Mutex.new
|
|
327
|
+
self.class.iowa_root
|
|
328
|
+
self.class.log_root
|
|
329
|
+
if self.class.Config && FileTest.exist?(self.class.Config)
|
|
330
|
+
Iowa.readConfiguration(self.class.Config)
|
|
331
|
+
else
|
|
332
|
+
Iowa.checkConfiguration
|
|
333
|
+
end
|
|
334
|
+
self.class.Logger = nil unless self.class.Logger
|
|
335
|
+
|
|
336
|
+
# begin
|
|
337
|
+
# mylog = Logger[Ciowa_log]
|
|
338
|
+
# raise "need a default logger" unless mylog
|
|
339
|
+
# rescue Exception
|
|
340
|
+
# # Logger must not be defined. Make sure a basic default exists!
|
|
341
|
+
# require 'logger'
|
|
342
|
+
# Iowa.const_set(:Logger, {Ciowa_log => ::Logger.new(nil)})
|
|
343
|
+
# mylog = Logger[Ciowa_log]
|
|
344
|
+
# end
|
|
345
|
+
|
|
346
|
+
mylog = Iowa::Log
|
|
347
|
+
@myclass = self.class
|
|
348
|
+
@keep_statistics ||= false
|
|
349
|
+
@docroot = docroot
|
|
350
|
+
Iowa.config[Capplication][Cdocroot_caching] = false if Iowa.config[Capplication][Cdocroot_caching].nil?
|
|
351
|
+
Iowa.config[Capplication][Cdispatcher][Cclass] = 'iowa/Dispatcher' unless Iowa.config[Capplication][Cdispatcher][Cclass]
|
|
352
|
+
Iowa.config[Capplication][Cpolicy][Cclass] = 'iowa/Policy' unless Iowa.config[Capplication][Cpolicy][Cclass]
|
|
353
|
+
unless Iowa.config[Capplication][Csessioncache][Cclass]
|
|
354
|
+
Iowa.config[Capplication][Csessioncache][Cclass] = 'iowa/caches/LRUCache'
|
|
355
|
+
Iowa.config[Capplication][Csessioncache][Cmaxsize] = 300
|
|
356
|
+
Iowa.config[Capplication][Csessioncache][Cttl] = nil
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
Iowa.config[Capplication][Cpath_query_interval] = int_or_nil(Iowa.config[Capplication][Cpath_query_interval])
|
|
360
|
+
Iowa.config[Capplication][Creload_interval] = int_or_nil(Iowa.config[Capplication][Creload_interval])
|
|
361
|
+
|
|
362
|
+
self.class.Dispatcher = nil unless self.class.Dispatcher
|
|
363
|
+
self.class.SessionCache = nil unless self.class.SessionCache
|
|
364
|
+
self.class.SessionCache.add_finalizer {|key, obj| obj.lock = nil}
|
|
365
|
+
self.class.Policy = nil unless self.class.Policy
|
|
366
|
+
@sessions = self.class.SessionCache
|
|
367
|
+
@policy = self.class.Policy
|
|
368
|
+
self.class.ViewFileSuffixes = %w(htm html vew view) unless self.class.ViewFileSuffixes
|
|
369
|
+
Iowa.config[Capplication][Cserialize_templates] = false unless Iowa.config[Capplication][Cserialize_templates] and (Iowa.config[Capplication][Cserialize_templates] == true or !Iowa.config[Capplication][Cserialize_templates].empty?)
|
|
370
|
+
@templateCache = {}
|
|
371
|
+
@templateMTimes = Hash.new {|h,k| h[k] = Time.at(1)}
|
|
372
|
+
@templateLTimes = {}
|
|
373
|
+
@templateRTimes = Hash.new {|h,k| h[k] = Time.at(1)}
|
|
374
|
+
@pathNameCache = {}
|
|
375
|
+
@appLock = Mutex.new
|
|
376
|
+
@statistics = Iowa::ApplicationStats.new(@sessions)
|
|
377
|
+
@reload_scan_mode = Csingular
|
|
378
|
+
$iowa_application = self
|
|
379
|
+
|
|
380
|
+
Iowa.config[Capplication][Cmodel][Cinterval] ||= 300
|
|
381
|
+
Iowa.config[Capplication][Cmodel][Cvariation] ||= 60
|
|
382
|
+
if self.class.Models.empty?
|
|
383
|
+
bn = File.basename($0)
|
|
384
|
+
['models/','model.rb',bn.sub(/\.\w+$/,'.mdl'),bn.sub(/\.\w+$/,'.model')].each do |m|
|
|
385
|
+
self.class.Models << m if FileTest.exist? m
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
model_monitor
|
|
389
|
+
Thread.start {model_monitor(true)}
|
|
390
|
+
|
|
391
|
+
self.class.doc_root
|
|
392
|
+
self.class.cgi_root
|
|
393
|
+
self.class.log_root
|
|
394
|
+
|
|
395
|
+
mylog.info " Application with docroot of #{docroot} initialized."
|
|
396
|
+
mylog.info " docroot_caching is #{Iowa.config[Capplication][Cdocroot_caching] ? 'enabled' : 'disabled'}"
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
private
|
|
400
|
+
def int_or_nil(n)
|
|
401
|
+
Integer(n)
|
|
402
|
+
rescue
|
|
403
|
+
nil
|
|
404
|
+
end
|
|
405
|
+
public
|
|
406
|
+
|
|
407
|
+
def read_model(model)
|
|
408
|
+
Logger[Ciowa_log].info "Loading model #{model}."
|
|
409
|
+
load model
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def model_mtime(path)
|
|
413
|
+
mtime = File.stat(path).mtime
|
|
414
|
+
Logger[Ciowa_log].info "#{path} : #{mtime} != #{@model_mtimes[path]}"
|
|
415
|
+
if mtime != @model_mtimes[path]
|
|
416
|
+
@model_mtimes[path] = mtime
|
|
417
|
+
true
|
|
418
|
+
else
|
|
419
|
+
false
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def model_monitor(doloop = false)
|
|
424
|
+
@model_mtimes = {}
|
|
425
|
+
begin
|
|
426
|
+
if doloop
|
|
427
|
+
sleep_time Iowa.config[Capplication][Cmodel][Cinterval] + rand(Iowa.config[Capplication][Cmodel][Cvariation].to_i)
|
|
428
|
+
Logger[Ciowa_log].info "model monitor sleeping for #{sleep_time} seconds"
|
|
429
|
+
sleep(sleep_time)
|
|
430
|
+
end
|
|
431
|
+
@model_mutex.synchronize do
|
|
432
|
+
self.class.Models.each do |model|
|
|
433
|
+
Logger[Ciowa_log].info "model #{model}"
|
|
434
|
+
next unless FileTest.exist? model
|
|
435
|
+
if FileTest.directory? model
|
|
436
|
+
Logger[Ciowa_log].info " directory"
|
|
437
|
+
require 'find'
|
|
438
|
+
Find.find(model) do |path|
|
|
439
|
+
Logger[Ciowa_log].info " checking #{path}"
|
|
440
|
+
next if FileTest.directory? path
|
|
441
|
+
read_model(path) if model_mtime(path)
|
|
442
|
+
end
|
|
443
|
+
else
|
|
444
|
+
read_model(model) if model_mtime(model)
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
end while doloop
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def rendered_content
|
|
452
|
+
@rendered_content ||= Iowa::Caches::LRUCache.new({:maxsize => 100})
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def rand(num)
|
|
456
|
+
@policy.rand(num)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def statistics
|
|
460
|
+
@statistics
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def reload_scan_mode
|
|
464
|
+
@reload_scan_mode
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# Set the reload scanning mode. The two current settings are 'singular'
|
|
468
|
+
# and 'plural'.
|
|
469
|
+
# singular: only check the named template for loading. This is much
|
|
470
|
+
# more efficient for large applications as it eliminates making a stat()
|
|
471
|
+
# system call on each file for every single request. Most of the time
|
|
472
|
+
# this should be sufficient for detecting any changes that have been
|
|
473
|
+
# made and reloading them. If, in some case, it is found not to be
|
|
474
|
+
# sufficient, one can set the mode to 'plural' which is the old
|
|
475
|
+
# normal mode of operation. 'singular' is the default mode of
|
|
476
|
+
# operation.
|
|
477
|
+
# plural: checks the mtime of every file in the iowa docroot directory
|
|
478
|
+
# every time a request is handled. This is guaranteed to detect
|
|
479
|
+
# and reload changes in every file. For sites that have a lot of
|
|
480
|
+
# files in their docroot, though, this is a performance hit.
|
|
481
|
+
# There really should never be a need to run in plural mode
|
|
482
|
+
# so this is deprecated and will be removed soon.
|
|
483
|
+
def reload_scan_mode=(mode)
|
|
484
|
+
if mode == Csingular
|
|
485
|
+
@reload_scan_mode = Csingular
|
|
486
|
+
else
|
|
487
|
+
@reload_scan_mode = Cplural
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
# Dispatches the request to the session. This can be overridden in order to
|
|
492
|
+
# make more complex decisions about which page to display, but the prefered
|
|
493
|
+
# approach is to leave this method alone and to provide a custom dispatcher.
|
|
494
|
+
|
|
495
|
+
def dispatcher(session,context,dispatch_destination = nil)
|
|
496
|
+
@myclass.Dispatcher.dispatch(session,context,dispatch_destination)
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
# handleRequest() is called whenever a request is made to the application.
|
|
500
|
+
|
|
501
|
+
def handleRequest(context,dispatch_destination = nil)
|
|
502
|
+
session = exception = nil
|
|
503
|
+
@statistics.hit if @keep_statistics
|
|
504
|
+
# ToDo: Clean this up so that we can make it work with only
|
|
505
|
+
# one begin/end block, or even better, with just rescue clauses.
|
|
506
|
+
begin
|
|
507
|
+
unless context.sessionID.to_s != C_empty
|
|
508
|
+
context.sessionID = @policy.new_session_key
|
|
509
|
+
@sessions[context.sessionID] = Session.newSession
|
|
510
|
+
@sessions[context.sessionID].application = self
|
|
511
|
+
end
|
|
512
|
+
session = @sessions[context.sessionID] unless exception
|
|
513
|
+
rescue Exception => exception
|
|
514
|
+
throw :session_error,exception
|
|
515
|
+
end
|
|
516
|
+
if session
|
|
517
|
+
dispatcher(session,context,dispatch_destination)
|
|
518
|
+
else
|
|
519
|
+
begin
|
|
520
|
+
invalidSession(context)
|
|
521
|
+
rescue Exception => exception
|
|
522
|
+
end
|
|
523
|
+
if exception
|
|
524
|
+
throw :session_error,exception
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def search_proc(dirpath)
|
|
530
|
+
r = []
|
|
531
|
+
Dir.foreach(dirpath) do |filename|
|
|
532
|
+
next if filename == C_dot or filename == C_dotdot or filename =~ /^\./ or filename =~ /^[a-z]/
|
|
533
|
+
fullname = "#{dirpath}/#{filename}"
|
|
534
|
+
if FileTest.directory? fullname
|
|
535
|
+
r << search_proc(fullname)
|
|
536
|
+
elsif @@search_regex.match(filename)
|
|
537
|
+
r.push fullname.gsub(/\/\//,C_slash)
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
r
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
# Reload a component if it has changed.
|
|
544
|
+
|
|
545
|
+
def reloadModified(component_class=nil,only_if_singular=nil,import_call=false)
|
|
546
|
+
unless @templateRTimes[component_class.to_s] > Time.now
|
|
547
|
+
@templateRTimes[component_class.to_s] = Time.now + reload_interval
|
|
548
|
+
pathlist = nil
|
|
549
|
+
classname = component_class.to_s.split(ClassSeparator).last.to_s
|
|
550
|
+
if (reload_scan_mode == Csingular and !classname.nil?)
|
|
551
|
+
pathlist = [pathForName(component_class)].compact
|
|
552
|
+
elsif (reload_scan_mode != Csingular and !only_if_singular)
|
|
553
|
+
pathlist = search_proc(@docroot)
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
if pathlist
|
|
557
|
+
if import_call
|
|
558
|
+
reloadLoop(pathlist)
|
|
559
|
+
else
|
|
560
|
+
reloadLoop(pathlist)
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
# Check the modification time on the template files in order to
|
|
567
|
+
# determine if the template needs to be reloaded.
|
|
568
|
+
|
|
569
|
+
def checkMtime(path)
|
|
570
|
+
file = File.new(path)
|
|
571
|
+
fileMtime = file.mtime
|
|
572
|
+
|
|
573
|
+
iwaPath = path.sub(@@view_regex, C_iwa)
|
|
574
|
+
if File.exist?(iwaPath)
|
|
575
|
+
iwaMtime = File.stat(iwaPath).mtime
|
|
576
|
+
fileMtime = iwaMtime if iwaMtime > fileMtime
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
bndPath = path.sub(@@view_regex,C_bnd)
|
|
582
|
+
if File.exist?(bndPath)
|
|
583
|
+
bndMtime = File.stat(bndPath).mtime
|
|
584
|
+
fileMtime = bndMtime if bndMtime > fileMtime
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
fileMtime
|
|
588
|
+
|
|
589
|
+
rescue Exception => e
|
|
590
|
+
Logger['iowa_log'].error e.to_s
|
|
591
|
+
Time.at(1)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def reload_interval
|
|
595
|
+
Iowa.config[Capplication][Creload_interval] || 60
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
def reloadLoop(pathlist)
|
|
599
|
+
return unless pathlist
|
|
600
|
+
mylog = Logger[Ciowa_log]
|
|
601
|
+
pathlist.each do |path|
|
|
602
|
+
next if @templateRTimes[path] > Time.now
|
|
603
|
+
mtime = @templateMTimes[path]
|
|
604
|
+
next if Time.now < (mtime + reload_interval)
|
|
605
|
+
@templateRTimes[path] = Time.now + reload_interval
|
|
606
|
+
|
|
607
|
+
fileMtime = checkMtime(path)
|
|
608
|
+
|
|
609
|
+
unless mtime and mtime >= fileMtime
|
|
610
|
+
mylog.info "Loading template #{path}"
|
|
611
|
+
reload File.new(path)
|
|
612
|
+
@templateMTimes[path] = fileMtime
|
|
613
|
+
end
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
def initialLoad
|
|
618
|
+
mylog = Logger[Ciowa_log]
|
|
619
|
+
# There really shouldn't be any reason to load all of the files
|
|
620
|
+
# initially anymore, but just in case, we'll still allow it via
|
|
621
|
+
# a config setting.
|
|
622
|
+
unless Iowa.config[Capplication][Cdo_initial_load]
|
|
623
|
+
mylog.info "Not loading any files initially."
|
|
624
|
+
return
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
search_proc = proc do |dirpath|
|
|
628
|
+
r = []
|
|
629
|
+
Dir.foreach(dirpath) do |filename|
|
|
630
|
+
next if filename == C_dot or filename == C_dotdot or /^\./.match(filename) or /^[a-z]/.match(filename)
|
|
631
|
+
fullname = "#{dirpath}/#{filename}"
|
|
632
|
+
if FileTest.directory? fullname
|
|
633
|
+
r << search_proc.call(fullname)
|
|
634
|
+
elsif @@view_regex.match(filename)
|
|
635
|
+
r.push fullname
|
|
636
|
+
end
|
|
637
|
+
end
|
|
638
|
+
r.flatten.sort
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
pathlist = search_proc.call(@docroot)
|
|
642
|
+
|
|
643
|
+
reloadLoop(pathlist)
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
# Returns the template that implements the named component.
|
|
647
|
+
|
|
648
|
+
def templateForComponent(name)
|
|
649
|
+
template = nil
|
|
650
|
+
pfn = pathForName(name)
|
|
651
|
+
if @templateCache.has_key? pfn
|
|
652
|
+
if @templateCache[pfn].respond_to? :weakref_alive?
|
|
653
|
+
rtc = 0
|
|
654
|
+
begin
|
|
655
|
+
template = @templateCache[pfn].self
|
|
656
|
+
rescue Exception => e
|
|
657
|
+
Logger[Ciowa_log].info "Error: #{e}\n#{e.backtrace.join("\n")}"
|
|
658
|
+
#reload(File.new(pathForName(name)))
|
|
659
|
+
reload(File.new(pfn))
|
|
660
|
+
rtc += 1
|
|
661
|
+
if rtc < 3
|
|
662
|
+
retry
|
|
663
|
+
else
|
|
664
|
+
raise e
|
|
665
|
+
end
|
|
666
|
+
end
|
|
667
|
+
else
|
|
668
|
+
template = @templateCache[pfn]
|
|
669
|
+
end
|
|
670
|
+
else
|
|
671
|
+
|
|
672
|
+
#reload(File.new(pathForName(name)))
|
|
673
|
+
reload(File.new(pfn)) if pfn
|
|
674
|
+
template = @templateCache[pfn]
|
|
675
|
+
end
|
|
676
|
+
template
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
# import is used to make other templates available within the
|
|
680
|
+
# context of the template where it is called.
|
|
681
|
+
|
|
682
|
+
def import(name,namespace = nil)
|
|
683
|
+
# TODO: Deal with recursion. If A imports B and B imports A, we
|
|
684
|
+
# will get stuck.
|
|
685
|
+
namespace = namespace.gsub(ContentClassesNamespace,C_empty).gsub(/^::/,C_empty)
|
|
686
|
+
ft = File.join(@docroot,namespace.gsub(ClassSeparator,C_slash),name)
|
|
687
|
+
template_class = nil
|
|
688
|
+
if namespace != C_empty
|
|
689
|
+
@@view_suffixes.each do |suffix|
|
|
690
|
+
if FileTest.exist?("#{ft}#{suffix}")
|
|
691
|
+
template_class = "#{namespace}::#{name}"
|
|
692
|
+
break
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
end
|
|
696
|
+
template_class = name unless template_class
|
|
697
|
+
|
|
698
|
+
if reload_scan_mode == Csingular
|
|
699
|
+
reloadModified(template_class,true,true)
|
|
700
|
+
else
|
|
701
|
+
reload File.new(pathForName(template_class))
|
|
702
|
+
end
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
private
|
|
706
|
+
|
|
707
|
+
def path_query_interval
|
|
708
|
+
Iowa.config[Capplication][Cpath_query_interval] || 60
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
# Given a component name, finds the path to it.
|
|
712
|
+
|
|
713
|
+
def pathForName(name)
|
|
714
|
+
name.gsub!(/Iowa::Application::ContentClasses::/,C_empty)
|
|
715
|
+
return @pathNameCache[name] if @templateLTimes.has_key?(name) and (@templateLTimes[name] < Time.now)
|
|
716
|
+
my_docroot = @docroot
|
|
717
|
+
my_docroot << C_slash unless my_docroot[-1,1] == C_slash
|
|
718
|
+
|
|
719
|
+
pfn_pre = my_docroot + name.gsub(/::/,C_slash)
|
|
720
|
+
pfn = nil
|
|
721
|
+
@@view_suffixes.each do |sfx|
|
|
722
|
+
tmp_pfn = pfn_pre + sfx
|
|
723
|
+
if FileTest.exist? tmp_pfn
|
|
724
|
+
pfn = tmp_pfn
|
|
725
|
+
@pathNameCache[name] = pfn
|
|
726
|
+
@templateLTimes[name] = Time.now + path_query_interval
|
|
727
|
+
break
|
|
728
|
+
end
|
|
729
|
+
end
|
|
730
|
+
pfn
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
# Extract the code and bindings from the code data.
|
|
734
|
+
|
|
735
|
+
def get_code_and_bindings(codedata)
|
|
736
|
+
codedata.sub!(/<\?(.*?)\?>/m, C_empty)
|
|
737
|
+
bindings = ''
|
|
738
|
+
bindings = $1.gsub(BindingCommentsRegexp,C_empty) if $1
|
|
739
|
+
if m = /<%(.*?)%>/m.match(codedata)
|
|
740
|
+
code = m[1]
|
|
741
|
+
else
|
|
742
|
+
code = codedata
|
|
743
|
+
end
|
|
744
|
+
[code,bindings]
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
# This method loads (or reloads) a template file.
|
|
748
|
+
# To completely separate the layout (template) from the code,
|
|
749
|
+
# put the HTML in a file Foo.html, and then place the code for
|
|
750
|
+
# that template into another file, Foo.iwa.
|
|
751
|
+
|
|
752
|
+
def reload(file)
|
|
753
|
+
mylog = Logger[Ciowa_log]
|
|
754
|
+
data = file.read
|
|
755
|
+
|
|
756
|
+
code_text = ''
|
|
757
|
+
bindings_text = ''
|
|
758
|
+
|
|
759
|
+
# Read the codefile and check for bindings embedded into it.
|
|
760
|
+
codefile_path = file.path.sub(@@view_regex,C_iwa)
|
|
761
|
+
if FileTest.exist?(codefile_path) and FileTest.readable?(codefile_path)
|
|
762
|
+
File.open(codefile_path) do |codefile|
|
|
763
|
+
codedata = codefile.read.gsub(/\cM/,C_empty)
|
|
764
|
+
code_text, bindings_text = *get_code_and_bindings(codedata)
|
|
765
|
+
end
|
|
766
|
+
else
|
|
767
|
+
codedata = data.gsub(/\cM/,C_empty)
|
|
768
|
+
unless /<%.*?%>/m.match(codedata)
|
|
769
|
+
codedata,codefile_path = defaultScript(file)
|
|
770
|
+
codedata.gsub!(/\cM/,C_empty)
|
|
771
|
+
code_text, bindings_text = *get_code_and_bindings(codedata)
|
|
772
|
+
else
|
|
773
|
+
codefile_path = file.path
|
|
774
|
+
codedata.sub!(/<%(.*?)%>/m, C_empty)
|
|
775
|
+
code_text = $1
|
|
776
|
+
codedata.sub!(/<\?(.*?)\?>/m, C_empty)
|
|
777
|
+
bindings_text = $1.gsub(BindingCommentsRegexp,C_empty) if $1
|
|
778
|
+
data = codedata
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
# Now check for a dedicated bindings file.
|
|
783
|
+
# In a dedicated bindings file, one can have multiple bindings
|
|
784
|
+
# blocks with comments (lines with a first non-whitespace character
|
|
785
|
+
# of #) anywhere. This is just a feature to allow for some intelligent
|
|
786
|
+
# organization of bindings and comments, if desired.
|
|
787
|
+
bindingfile_path = file.path.sub(@@view_regex,C_bnd)
|
|
788
|
+
if FileTest.exist?(bindingfile_path) and FileTest.readable?(bindingfile_path)
|
|
789
|
+
File.open(bindingfile_path) do |bindingfile|
|
|
790
|
+
bindingdata = bindingfile.read.gsub(/\cM/,C_empty)
|
|
791
|
+
bindingdata = bindingdata.gsub(/<\?/,C_empty).gsub(/\?>/,C_empty).gsub(BindingCommentsRegexp,C_empty) if bindingdata
|
|
792
|
+
bindings_text << bindingdata
|
|
793
|
+
end
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
# There's a bit of magic that has to occur, now. In order to
|
|
797
|
+
# support the notion of the subdirectory that the script file
|
|
798
|
+
# is found in relating to the namespace (using modules as
|
|
799
|
+
# namespace) for the component, reload() needs to figure out
|
|
800
|
+
# just what the namespace is supposed to be for the file, then
|
|
801
|
+
# check to see if that namespace has a already been created,
|
|
802
|
+
# create it if it has not, and finally eval the script file
|
|
803
|
+
# content within the context of the namespace (module).
|
|
804
|
+
|
|
805
|
+
# First, what's the namespace? Basically, we subtract the
|
|
806
|
+
# Iowa docroot from the file path and see what is left.
|
|
807
|
+
|
|
808
|
+
my_docroot = @docroot
|
|
809
|
+
my_docroot << C_slash unless my_docroot[-1,1] == C_slash
|
|
810
|
+
script_namespace_parts = file.path.gsub(/^#{my_docroot}/,C_empty).split(C_slash).reject {|x| x == C_empty}
|
|
811
|
+
script_namespace_parts.delete(C_dot)
|
|
812
|
+
script_namespace_parts.delete(C_dotdot)
|
|
813
|
+
class_name = script_namespace_parts.pop.split(C_dot)[0]
|
|
814
|
+
script_namespace_parts.unshift(CContentClasses)
|
|
815
|
+
|
|
816
|
+
script_namespace = (['Iowa::Application'] + script_namespace_parts).join(ClassSeparator)
|
|
817
|
+
|
|
818
|
+
pre = ''
|
|
819
|
+
post = ''
|
|
820
|
+
|
|
821
|
+
script_namespace_parts.each do |sym|
|
|
822
|
+
pre << "module #{sym}; extend IowaComponentMixins;"
|
|
823
|
+
post << "end;"
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
mylog.info "Creating namespace #{script_namespace}"
|
|
827
|
+
eval(pre + post)
|
|
828
|
+
eval(script_namespace)
|
|
829
|
+
namespace_class = script_namespace.split(ClassSeparator).inject(Object) { |o,n| o.const_get n }
|
|
830
|
+
|
|
831
|
+
begin
|
|
832
|
+
# Now execute our code within the namespace.
|
|
833
|
+
|
|
834
|
+
namespace_class.class_eval(code_text,codefile_path)
|
|
835
|
+
new_class = "#{script_namespace}::#{class_name}".split(ClassSeparator).inject(Object) { |o,n| o.const_get n }
|
|
836
|
+
|
|
837
|
+
bindings = BindingsParser.new((bindings_text ? bindings_text : C_empty),new_class).bindings
|
|
838
|
+
|
|
839
|
+
fdn = File.dirname(file.path)
|
|
840
|
+
compiled_template_file = File.join(fdn,".#{new_class.name}.iwt")
|
|
841
|
+
load_precompiled = false
|
|
842
|
+
if FileTest.exist?(compiled_template_file) and File.mtime(compiled_template_file) > checkMtime(file.path)
|
|
843
|
+
begin
|
|
844
|
+
mylog.info "Loading precompiled template: #{compiled_template_file}"
|
|
845
|
+
@templateCache[file.path] = WeakRef.new(Marshal.load(File.read(compiled_template_file)))
|
|
846
|
+
load_recompiled = true
|
|
847
|
+
rescue Exception => e
|
|
848
|
+
mylog.info "Error with precompiled template: #{e}"
|
|
849
|
+
end
|
|
850
|
+
end
|
|
851
|
+
unless load_recompiled
|
|
852
|
+
mylog.info "Parsing #{file.path} into template cache"
|
|
853
|
+
if self.class.serializeCompiledTemplates && new_class.serializeCompiledTemplate
|
|
854
|
+
@templateCache[file.path] = WeakRef.new(TemplateParser.new(data, bindings,new_class,fdn).root)
|
|
855
|
+
else
|
|
856
|
+
@templateCache[file.path] = TemplateParser.new(data, bindings,new_class,fdn).root
|
|
857
|
+
end
|
|
858
|
+
Logger[Ciowa_log].info(" Done parsing #{file.path}")
|
|
859
|
+
end
|
|
860
|
+
rescue Exception => e
|
|
861
|
+
mylog.info "There was an error while processing #{file.path}:\n#{e.to_s}\n#{e.backtrace}\n"
|
|
862
|
+
end
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
# If there is only an HTML file, without either an embedded code section
|
|
866
|
+
# or a corresponding .iwa file, then we apply a basic default.
|
|
867
|
+
# If a file, 'DefaultScriptFile.iwa', exists in the Iowa docroot, the
|
|
868
|
+
# contents of that file will be used for the default script. That file
|
|
869
|
+
# should be written as a standard Iowa .iwa file, with one exception.
|
|
870
|
+
# The exception is that the name of the class should be written as:
|
|
871
|
+
# [--CLASSNAME--]
|
|
872
|
+
# This placeholder will be expanded by Iowa into the actual name of the
|
|
873
|
+
# class to be created.
|
|
874
|
+
|
|
875
|
+
def defaultScript(file)
|
|
876
|
+
mylog = Logger[Ciowa_log]
|
|
877
|
+
|
|
878
|
+
#name = /.*\/(.+)\.(view|vew|html|htm)/.match(file.path)[1]
|
|
879
|
+
name = @@view_file_regex.match(file.path)[1]
|
|
880
|
+
r = ''
|
|
881
|
+
|
|
882
|
+
my_docroot = @docroot
|
|
883
|
+
my_docroot << C_slash unless my_docroot[-1,1] == C_slash
|
|
884
|
+
my_docroot_minus_slash = my_docroot.sub(/\/$/,C_empty)
|
|
885
|
+
filepath = file.path
|
|
886
|
+
filepath.sub!(/#{my_docroot}/,C_empty)
|
|
887
|
+
|
|
888
|
+
path_parts = filepath.split(C_slash)
|
|
889
|
+
# Knock the filename off of the array.
|
|
890
|
+
path_parts.pop
|
|
891
|
+
# And put the docroot path onto the beginning of the array.
|
|
892
|
+
path_parts.unshift my_docroot_minus_slash
|
|
893
|
+
df_found = nil
|
|
894
|
+
search_path = ''
|
|
895
|
+
while path_parts.length > 0
|
|
896
|
+
search_path << "#{path_parts.shift}/"
|
|
897
|
+
default_script_file = search_path + 'DefaultScriptFile.iwa'
|
|
898
|
+
default_script_file.gsub(/\/\//,C_slash)
|
|
899
|
+
if FileTest.exists? default_script_file
|
|
900
|
+
df_found = default_script_file
|
|
901
|
+
end
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
if df_found
|
|
905
|
+
File.open(df_found,'r') do |fh|
|
|
906
|
+
fh.each {|line| r << line}
|
|
907
|
+
end
|
|
908
|
+
mylog.info "Loaded #{df_found} for script file for #{file.path}"
|
|
909
|
+
else
|
|
910
|
+
r << "<%class [--CLASSNAME--] < Iowa::Component; end%>"
|
|
911
|
+
df_found = 'INTERNAL'
|
|
912
|
+
mylog.info "Used basic scriptfile for #{file.path}"
|
|
913
|
+
end
|
|
914
|
+
|
|
915
|
+
r.gsub!(/\[--CLASSNAME--\]/,name)
|
|
916
|
+
[r,df_found]
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
# Make this something that can be configured.
|
|
921
|
+
|
|
922
|
+
def invalidSession(context)
|
|
923
|
+
context.response << "<html><head><meta http-equiv=REFRESH content='1; URL=#{context.baseURL}'></head><body><b>That session no longer exists (#{$$}:#{$$.to_s(16)}).<p>You are being forwarded to a <a href='#{context.baseURL}'>new session</a>.</b></body></html>"
|
|
924
|
+
end
|
|
925
|
+
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
end
|