From b80fa05ed1b6d62a0e24b29d6c4c4963805c5806 Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Tue, 20 May 2003 03:25:31 +0000 Subject: [PATCH] *** empty log message *** --- .cvsignore | 28 + .gitignore | 6 + AUTHORS | 1 + INSTALL | 52 + LICENSE | 470 + NEWS | 0 README | 2 + build.properties.sample | 60 + build.xml | 439 + conf-sso/extra-db-mysql.sql | 33 + conf-sso/sp/dynamo.xml | 182 + conf-sso/sp/logging.xml | 46 + conf-sso/sp/sourceid-sso-providers.xml | 59 + conf-sso/sp/sourceid-sso.xml | 68 + conf-sso/sp/sp-descriptor.xml | 37 + conf-sso/sp/venice-sp.keystore | Bin 0 -> 1395 bytes conf-sso/sp/web.xml | 335 + conf/db-init-mysql.sql | 236 + conf/dynamo-test.xml | 70 + conf/dynamo-venice.xml | 175 + conf/logging-test.xml | 39 + conf/logging-venice.xml | 39 + conf/std_render_macro_library.vm | 31 + conf/venice-db-init-mysql.sql | 573 + conf/web-test.xml | 117 + conf/web-venice.xml | 218 + docs/buttons/.gitignore | 1 + docs/buttons/bn_blank80.png | Bin 0 -> 4362 bytes docs/buttons/bn_delete.png | Bin 0 -> 4622 bytes docs/buttons/bn_save.png | Bin 0 -> 4609 bytes docs/buttons/classic.xcf | Bin 0 -> 9377 bytes docs/buttons/gelcap_green.xcf | Bin 0 -> 5170 bytes docs/buttons/gelcap_pink.xcf | Bin 0 -> 3788 bytes docs/buttons/gelcap_red.xcf | Bin 0 -> 4052 bytes docs/buttons/gelcap_teal.xcf | Bin 0 -> 5147 bytes docs/buttons/gelcap_violet.xcf | Bin 0 -> 3862 bytes docs/buttons/gelcap_yellow.xcf | Bin 0 -> 4835 bytes docs/design-goals.html | 103 + docs/identifiers.html | 46 + docs/user-acl-truth-table.sxc | Bin 0 -> 6612 bytes drivers/.gitignore | 1 + drivers/README.drivers | 6 + resources/dynamo-test-module/res1.txt | 1 + .../com/silverwrist/util/AnyCharMatcher.java | 160 + .../silverwrist/util/BooleanValues.properties | 19 + .../com/silverwrist/util/Country.java | 159 + .../com/silverwrist/util/HardSoftCache.java | 329 + .../com/silverwrist/util/IOUtils.java | 378 + .../com/silverwrist/util/International.java | 267 + .../com/silverwrist/util/Language.java | 159 + .../com/silverwrist/util/MySQLUtils.java | 120 + .../com/silverwrist/util/OptionSet.java | 424 + .../com/silverwrist/util/SQLUtils.java | 127 + .../com/silverwrist/util/StringUtils.java | 349 + .../com/silverwrist/util/countries.properties | 261 + .../util/image/ImageNormalizer.java | 272 + .../util/image/ImageNormalizerException.java | 77 + .../com/silverwrist/util/languages.properties | 254 + .../util/xml/DOMElementHelper.java | 489 + .../util/xml/XMLLoadException.java | 155 + .../com/silverwrist/util/xml/XMLLoader.java | 824 ++ .../com/silverwrist/dynamo/BrowserFlag.java | 189 + .../com/silverwrist/dynamo/DynamoVersion.java | 33 + .../silverwrist/dynamo/HttpStatusCode.java | 482 + .../com/silverwrist/dynamo/Namespaces.java | 77 + .../com/silverwrist/dynamo/RequestType.java | 142 + .../silverwrist/dynamo/UserInfoNamespace.java | 64 + .../com/silverwrist/dynamo/Verb.java | 132 + .../com/silverwrist/dynamo/WebConstants.java | 134 + .../dynamo/app/ApplicationContainer.java | 1292 ++ .../ApplicationContainerMessages.properties | 27 + .../dynamo/app/ApplicationServiceManager.java | 675 + .../dynamo/app/BackgroundProcessor.java | 490 + .../dynamo/app/ComponentResName.java | 123 + .../dynamo/app/ConnectionManager.java | 221 + .../dynamo/app/ConnectionMessages.properties | 23 + .../dynamo/app/ConnectionPoint.java | 179 + .../dynamo/app/DataItemRenderer.java | 52 + .../silverwrist/dynamo/app/HeapContents.java | 88 + .../silverwrist/dynamo/app/ListRenderer.java | 50 + .../app/PropertySerializationSupport.java | 270 + .../silverwrist/dynamo/app/RewriteRule.java | 71 + .../silverwrist/dynamo/app/ServiceKey.java | 62 + .../dynamo/app/WrappedResourceProvider.java | 98 + .../dynamo/db/DBUtilitiesImpl.java | 141 + .../dynamo/db/DBUtilitiesImpl_mysql.java | 201 + .../dynamo/db/DatabaseConnectionPool.java | 652 + .../dynamo/db/DatabaseMessages.properties | 58 + .../dynamo/db/DefaultHashAuthenticator.java | 111 + .../dynamo/db/GlobalBlocksObject.java | 185 + .../dynamo/db/GlobalBlocksOps.java | 76 + .../dynamo/db/GlobalBlocksOps_mysql.java | 284 + .../dynamo/db/GlobalDataManagerObject.java | 207 + .../dynamo/db/GlobalPropertiesObject.java | 201 + .../dynamo/db/GlobalPropertiesOps.java | 76 + .../dynamo/db/GlobalPropertiesOps_mysql.java | 344 + .../silverwrist/dynamo/db/GroupObject.java | 611 + .../silverwrist/dynamo/db/GroupObjectOps.java | 63 + .../dynamo/db/GroupObjectOps_mysql.java | 556 + .../com/silverwrist/dynamo/db/GroupProxy.java | 249 + .../com/silverwrist/dynamo/db/ImageStore.java | 42 + .../dynamo/db/ImageStoreObject.java | 249 + .../silverwrist/dynamo/db/ImageStoreOps.java | 80 + .../dynamo/db/ImageStoreOps_mysql.java | 363 + .../silverwrist/dynamo/db/NamespaceCache.java | 28 + .../dynamo/db/NamespaceCacheObject.java | 143 + .../dynamo/db/NamespaceCacheOps.java | 69 + .../dynamo/db/NamespaceCacheOps_mysql.java | 132 + .../com/silverwrist/dynamo/db/OpsBase.java | 118 + .../silverwrist/dynamo/db/UserManagement.java | 42 + .../dynamo/db/UserManagerObject.java | 987 ++ .../silverwrist/dynamo/db/UserManagerOps.java | 102 + .../dynamo/db/UserManagerOps_mysql.java | 463 + .../dynamo/db/UserMessages.properties | 22 + .../com/silverwrist/dynamo/db/UserObject.java | 527 + .../silverwrist/dynamo/db/UserObjectOps.java | 70 + .../dynamo/db/UserObjectOps_mysql.java | 635 + .../dynamo/db/UserPropertyTranslator.java | 26 + .../db/UserPropertyTranslatorInstall.java | 24 + .../com/silverwrist/dynamo/db/UserProxy.java | 260 + .../dynamo/db/UserProxyManagement.java | 32 + .../dynamo/db/WrappedConnection.java | 498 + .../dynamo/dialog/BaseDialogField.java | 229 + .../dynamo/dialog/ButtonCaptions.properties | 21 + .../dynamo/dialog/CheckBoxField.java | 187 + .../dynamo/dialog/CommonTextField.java | 187 + .../dynamo/dialog/CountryListField.java | 123 + .../dynamo/dialog/DefaultDialogLAF.java | 85 + .../silverwrist/dynamo/dialog/DialogImpl.java | 643 + .../dynamo/dialog/DialogManager.java | 300 + .../dynamo/dialog/DialogMessages.properties | 31 + .../dynamo/dialog/DynamoIDField.java | 73 + .../dynamo/dialog/EmailAddressField.java | 73 + .../silverwrist/dynamo/dialog/HeaderItem.java | 177 + .../dynamo/dialog/HiddenField.java | 148 + .../dynamo/dialog/IntegerField.java | 271 + .../dynamo/dialog/LocaleListField.java | 90 + .../dynamo/dialog/PasswordField.java | 58 + .../dynamo/dialog/PickListField.java | 137 + .../silverwrist/dynamo/dialog/StdButton.java | 118 + .../dynamo/dialog/StdItemFactory.java | 80 + .../silverwrist/dynamo/dialog/TextField.java | 58 + .../dynamo/dialog/TimeZoneListField.java | 116 + .../dynamo/event/ApplicationAdapter.java | 44 + .../dynamo/event/ApplicationEvent.java | 71 + .../dynamo/event/ApplicationEventRequest.java | 189 + .../dynamo/event/ApplicationListener.java | 26 + .../dynamo/event/DynamicUpdateEvent.java | 44 + .../dynamo/event/DynamicUpdateListener.java | 24 + .../dynamo/event/DynamoEventListener.java | 32 + .../dynamo/event/DynamoEventObject.java | 65 + .../dynamo/event/GlobalBlockUpdateEvent.java | 72 + .../event/GlobalPropertyUpdateEvent.java | 72 + .../dynamo/event/GlobalUpdateEvent.java | 44 + .../dynamo/event/ScriptEngineStartEvent.java | 72 + .../event/ScriptEngineStartListener.java | 24 + .../dynamo/event/SessionEventRequest.java | 240 + .../dynamo/event/SessionInfoAdapter.java | 44 + .../dynamo/event/SessionInfoEvent.java | 71 + .../dynamo/event/SessionInfoListener.java | 26 + .../dynamo/event/SessionValueBindEvent.java | 152 + .../event/SessionValueBindListener.java | 59 + .../dynamo/event/UserPropertyUpdateEvent.java | 72 + .../dynamo/event/UserUpdateEvent.java | 63 + .../except/AuthenticationException.java | 39 + .../dynamo/except/CallFailureException.java | 104 + .../dynamo/except/CodeNotFoundException.java | 122 + .../dynamo/except/ConfigException.java | 91 + .../dynamo/except/DatabaseException.java | 65 + .../dynamo/except/DialogException.java | 84 + .../dynamo/except/DynamicObjectException.java | 70 + .../except/DynamicObjectRuntimeException.java | 70 + .../dynamo/except/DynamoException.java | 98 + .../except/DynamoExceptionMessages.properties | 33 + .../dynamo/except/DynamoRuntimeException.java | 98 + .../except/DynamoSecurityException.java | 39 + .../dynamo/except/ExternalException.java | 206 + .../except/ExternalRuntimeException.java | 189 + .../dynamo/except/GroupRuntimeException.java | 78 + .../dynamo/except/MailException.java | 39 + .../dynamo/except/ModuleException.java | 58 + .../dynamo/except/NoSuchObjectException.java | 142 + .../except/NoSuchResourceException.java | 99 + .../dynamo/except/NoSuchServiceException.java | 224 + .../dynamo/except/ObjectStoreException.java | 39 + .../dynamo/except/ProxyException.java | 84 + .../except/RenderClassCreationException.java | 55 + .../dynamo/except/RenderingException.java | 77 + .../dynamo/except/RequestParseException.java | 108 + .../dynamo/except/ScriptingException.java | 118 + .../except/SecurityRuntimeException.java | 78 + .../except/UnknownDialogFieldException.java | 57 + .../dynamo/except/ValidationException.java | 39 + .../silverwrist/dynamo/iface/Application.java | 50 + .../dynamo/iface/ApplicationSubstrate.java | 113 + .../silverwrist/dynamo/iface/AuditRecord.java | 87 + .../dynamo/iface/AuditRecordCompose.java | 26 + .../dynamo/iface/AuditRecordFactory.java | 29 + .../dynamo/iface/AuditRecordRetrieval.java | 31 + .../dynamo/iface/AuditRecordSet.java | 28 + .../dynamo/iface/Authenticator.java | 28 + .../dynamo/iface/AuthenticatorLookup.java | 24 + .../iface/AuthenticatorRegistration.java | 27 + .../dynamo/iface/BackgroundScheduler.java | 132 + .../dynamo/iface/BackgroundTask.java | 38 + .../dynamo/iface/BinaryRenderControl.java | 29 + .../dynamo/iface/BinaryRenderer.java | 27 + .../silverwrist/dynamo/iface/BrowserData.java | 42 + .../dynamo/iface/BrowserDataProvider.java | 24 + .../dynamo/iface/ChainParameterInput.java | 28 + .../dynamo/iface/ComponentInitialize.java | 50 + .../dynamo/iface/ComponentShutdown.java | 37 + .../dynamo/iface/ConnectionBackEnd.java | 26 + .../dynamo/iface/ConnectionFrontEnd.java | 26 + .../dynamo/iface/CookieControl.java | 36 + .../dynamo/iface/DBConnectionPool.java | 63 + .../silverwrist/dynamo/iface/DBUtilities.java | 39 + .../silverwrist/dynamo/iface/DataItem.java | 37 + .../com/silverwrist/dynamo/iface/Dialog.java | 64 + .../dynamo/iface/DialogButton.java | 24 + .../dynamo/iface/DialogFactoryConfig.java | 29 + .../silverwrist/dynamo/iface/DialogField.java | 41 + .../dynamo/iface/DialogHiddenItem.java | 32 + .../silverwrist/dynamo/iface/DialogItem.java | 35 + .../dynamo/iface/DialogItemFactory.java | 27 + .../dynamo/iface/DialogLoader.java | 26 + .../silverwrist/dynamo/iface/DialogPLAF.java | 28 + .../dynamo/iface/DynamicClass.java | 35 + .../dynamo/iface/DynamicObject.java | 35 + .../dynamo/iface/DynamicWrapper.java | 24 + .../silverwrist/dynamo/iface/DynamoAce.java | 26 + .../silverwrist/dynamo/iface/DynamoAcl.java | 40 + .../silverwrist/dynamo/iface/DynamoGroup.java | 48 + .../dynamo/iface/DynamoPermission.java | 28 + .../silverwrist/dynamo/iface/DynamoUser.java | 64 + .../iface/EventListenerRegistration.java | 32 + .../dynamo/iface/ExceptionTranslator.java | 24 + .../ExceptionTranslatorRegistration.java | 24 + .../dynamo/iface/ExternalAppAttributes.java | 70 + .../iface/ExternalSessionAttributes.java | 69 + .../silverwrist/dynamo/iface/HeaderInput.java | 38 + .../dynamo/iface/HeaderOutput.java | 32 + .../dynamo/iface/HookServiceProviders.java | 34 + .../dynamo/iface/MIMETypeMapper.java | 24 + .../com/silverwrist/dynamo/iface/Module.java | 34 + .../dynamo/iface/ModuleFunctions.java | 42 + .../silverwrist/dynamo/iface/ModuleSite.java | 24 + .../silverwrist/dynamo/iface/NamedObject.java | 36 + .../dynamo/iface/ObjectProvider.java | 37 + .../silverwrist/dynamo/iface/ObjectStore.java | 70 + .../dynamo/iface/OutputObjectFilter.java | 26 + .../iface/OutputObjectFilterRegistration.java | 24 + .../dynamo/iface/PostDynamicUpdate.java | 26 + .../dynamo/iface/PropertySerializer.java | 26 + .../iface/PropertySerializerRegistration.java | 24 + .../dynamo/iface/QueryRenderer.java | 24 + .../dynamo/iface/RenderControl.java | 31 + .../silverwrist/dynamo/iface/RenderFlags.java | 58 + .../dynamo/iface/RenderImmediate.java | 27 + .../silverwrist/dynamo/iface/Renderer.java | 22 + .../dynamo/iface/RendererRegistration.java | 28 + .../com/silverwrist/dynamo/iface/Request.java | 170 + .../dynamo/iface/RequestPreprocessor.java | 24 + .../RequestPreprocessorRegistration.java | 24 + .../dynamo/iface/ResourceProvider.java | 29 + .../dynamo/iface/ResourceProviderManager.java | 27 + .../dynamo/iface/ScriptEngineConfig.java | 61 + .../iface/ScriptEngineRegisterObject.java | 24 + .../dynamo/iface/ScriptExecute.java | 36 + .../dynamo/iface/SecureObjectStore.java | 36 + .../dynamo/iface/SelfRenderControl.java | 38 + .../dynamo/iface/SelfRenderable.java | 46 + .../dynamo/iface/ServiceProvider.java | 56 + .../silverwrist/dynamo/iface/SessionInfo.java | 110 + .../dynamo/iface/SessionInfoProvider.java | 39 + .../dynamo/iface/TextRenderControl.java | 30 + .../dynamo/iface/TextRenderer.java | 27 + .../silverwrist/dynamo/iface/URLRewriter.java | 26 + .../silverwrist/dynamo/mail/MailMessage.java | 58 + .../dynamo/mail/MailMessageImpl.java | 415 + .../dynamo/mail/MailMessageProvider.java | 30 + .../dynamo/mail/MailMessages.properties | 35 + .../dynamo/mail/MailProperties.java | 593 + .../dynamo/mail/MailSubSystem.java | 453 + .../dynamo/module/ModuleLoader.java | 354 + .../dynamo/module/ModuleManager.java | 258 + .../dynamo/module/ModuleMessages.properties | 27 + .../dynamo/module/ModuleOperations.java | 31 + .../dynamo/obj/JavaDynamicClass.java | 739 + .../dynamo/obj/JavaDynamicObject.java | 121 + .../dynamo/obj/JavaObjectBindery.java | 126 + .../dynamo/script/DeclaredObject.java | 67 + .../silverwrist/dynamo/script/ExitScript.java | 43 + .../dynamo/script/InternalRequest.java | 68 + .../dynamo/script/LibraryCast.java | 307 + .../dynamo/script/LibraryDynamo.java | 206 + .../dynamo/script/LibraryLogger.java | 117 + .../dynamo/script/ReturnValue.java | 76 + .../dynamo/script/ScriptController.java | 478 + .../dynamo/script/ScriptEngine.java | 527 + .../script/ScriptEngineMessages.properties | 29 + .../dynamo/script/ScriptExecuteHelper.java | 108 + .../silverwrist/dynamo/security/AceCache.java | 27 + .../dynamo/security/AceObject.java | 332 + .../dynamo/security/AceOperations.java | 68 + .../dynamo/security/AceOperations_mysql.java | 327 + .../dynamo/security/AclObject.java | 347 + .../dynamo/security/AclOperations.java | 90 + .../dynamo/security/AclOperations_mysql.java | 859 ++ .../dynamo/security/AuditReadOps.java | 101 + .../dynamo/security/AuditReadOps_mysql.java | 409 + .../dynamo/security/AuditWriteOps.java | 70 + .../dynamo/security/AuditWriteOps_mysql.java | 166 + .../dynamo/security/LibraryAudit.java | 257 + .../dynamo/security/PermObject.java | 153 + .../dynamo/security/PrincipalID.java | 101 + .../dynamo/security/ReadAuditRecord.java | 112 + .../dynamo/security/ReadAuditRecordSet.java | 81 + .../dynamo/security/RegisterNewAce.java | 26 + .../dynamo/security/SRMObject.java | 421 + .../dynamo/security/SRMOperations.java | 116 + .../dynamo/security/SRMOperations_mysql.java | 287 + .../security/SecurityMessages.properties | 24 + .../security/SecurityReferenceMonitor.java | 50 + .../dynamo/security/SystemAuditManager.java | 266 + .../dynamo/security/WriteAuditRecord.java | 179 + .../dynamo/servlet/BrowserDatabase.java | 166 + .../dynamo/servlet/BrowserDatabaseEntry.java | 181 + .../dynamo/servlet/ChainForward.java | 61 + .../dynamo/servlet/FileUploadRequestImpl.java | 488 + .../dynamo/servlet/GetRemapperData.java | 24 + .../dynamo/servlet/HttpMethod.java | 113 + .../dynamo/servlet/HttpSessionInfo.java | 458 + .../dynamo/servlet/ImageServlet.java | 82 + .../dynamo/servlet/NormalRequestImpl.java | 295 + .../dynamo/servlet/NullBrowserData.java | 94 + .../dynamo/servlet/NullResponse.java | 217 + .../silverwrist/dynamo/servlet/Remapper.java | 82 + .../dynamo/servlet/RemapperData.java | 105 + .../dynamo/servlet/RemapperElement.java | 108 + .../dynamo/servlet/RemapperServlet.java | 67 + .../dynamo/servlet/RequestImplBase.java | 330 + .../dynamo/servlet/ScriptExecServlet.java | 128 + .../dynamo/servlet/ServletBase.java | 997 ++ .../servlet/ServletBaseMessages.properties | 34 + .../servlet/ServletBinaryRenderControl.java | 78 + .../dynamo/servlet/ServletBrowserData.java | 140 + .../servlet/ServletBrowserDataProvider.java | 96 + .../servlet/ServletChainParameterInput.java | 95 + .../dynamo/servlet/ServletCookieControl.java | 249 + .../servlet/ServletExternalAppAttributes.java | 155 + .../ServletExternalSessionAttributes.java | 156 + .../dynamo/servlet/ServletHeaderInput.java | 120 + .../dynamo/servlet/ServletHeaderOutput.java | 249 + .../servlet/ServletInitObjectProvider.java | 83 + .../dynamo/servlet/ServletMIMETypeMapper.java | 57 + .../servlet/ServletSelfRenderControl.java | 448 + .../servlet/ServletTextRenderControl.java | 129 + .../servlet/SubObjectSelfRenderControl.java | 135 + .../servlet/SubObjectTextRenderControl.java | 62 + .../dynamo/servlet/URLRewriterImpl.java | 88 + .../silverwrist/dynamo/servlet/browscap.ini | 11833 ++++++++++++++++ .../util/BaseDelegatingObjectProvider.java | 119 + .../util/BaseDelegatingServiceProvider.java | 144 + .../dynamo/util/BufferTextRenderControl.java | 406 + .../util/DefaultSessionInfoProvider.java | 72 + .../silverwrist/dynamo/util/DynamoIDKey.java | 118 + .../dynamo/util/FilterRequest.java | 368 + .../dynamo/util/FilterTextRenderControl.java | 119 + .../dynamo/util/ForwardToPath.java | 68 + .../dynamo/util/ForwardToServlet.java | 68 + .../silverwrist/dynamo/util/Forwarder.java | 142 + .../dynamo/util/GetObjectMessages.properties | 22 + .../dynamo/util/GetObjectUtils.java | 174 + .../dynamo/util/HttpErrorMessage.java | 157 + .../dynamo/util/IDNameCacheObject.java | 106 + .../com/silverwrist/dynamo/util/IDUtils.java | 114 + .../dynamo/util/MemoryObjectStore.java | 248 + .../NamespaceDelegatingObjectProvider.java | 140 + .../silverwrist/dynamo/util/NoContent.java | 84 + .../dynamo/util/NullSessionInfo.java | 325 + .../dynamo/util/ObjectVisitor.java | 38 + .../silverwrist/dynamo/util/PropertyKey.java | 85 + .../dynamo/util/PropertyUtils.java | 330 + .../dynamo/util/QualifiedNameKey.java | 85 + .../com/silverwrist/dynamo/util/Redirect.java | 127 + .../util/RenderingExceptionWrapper.java | 54 + .../dynamo/util/RequestHelper.java | 442 + .../dynamo/util/ShutdownHashtableRemove.java | 56 + .../dynamo/util/ShutdownVectorRemove.java | 56 + .../dynamo/util/SimpleServiceProvider.java | 203 + .../util/SingleNamespaceObjectProvider.java | 130 + .../dynamo/util/SingletonServiceProvider.java | 109 + .../dynamo/util/StaticDataItem.java | 151 + .../dynamo/util/UtilityMessages.properties | 25 + .../dynamo/velocity/RenderableContext.java | 121 + .../dynamo/velocity/StdObject.java | 98 + .../VelocityDynamoResourceLoader.java | 100 + .../velocity/VelocityMessages.properties | 31 + .../dynamo/velocity/VelocityOwnTemplate.java | 54 + .../velocity/VelocityParamSupplier.java | 45 + .../dynamo/velocity/VelocityRenderable.java | 50 + .../dynamo/velocity/VelocityRenderer.java | 664 + .../velocity/VelocityRendererConfig.java | 29 + .../dynamo/xmlrpc/Capabilities.java | 136 + .../silverwrist/dynamo/xmlrpc/FaultCode.java | 172 + .../xmlrpc/IntrospectionDispatcher.java | 234 + .../dynamo/xmlrpc/MultiCallDispatcher.java | 190 + .../dynamo/xmlrpc/MultiCallRequest.java | 72 + .../dynamo/xmlrpc/RegisteredDispatcher.java | 97 + .../dynamo/xmlrpc/RegisteredFaultMapper.java | 79 + .../dynamo/xmlrpc/ReplaceSessionRequest.java | 68 + .../dynamo/xmlrpc/ScriptDispatcher.java | 171 + .../dynamo/xmlrpc/SystemFaultCode.java | 98 + .../dynamo/xmlrpc/Validator1Suite.java | 411 + .../dynamo/xmlrpc/XMLMetadata.java | 174 + .../dynamo/xmlrpc/XmlRpcConfiguration.java | 31 + .../dynamo/xmlrpc/XmlRpcCreateSession.java | 27 + .../dynamo/xmlrpc/XmlRpcDispatcher.java | 37 + .../dynamo/xmlrpc/XmlRpcFaultMapper.java | 26 + .../dynamo/xmlrpc/XmlRpcMessages.properties | 81 + .../dynamo/xmlrpc/XmlRpcMethodNotFound.java | 33 + .../dynamo/xmlrpc/XmlRpcParameterError.java | 39 + .../dynamo/xmlrpc/XmlRpcRequest.java | 700 + .../dynamo/xmlrpc/XmlRpcResult.java | 619 + .../dynamo/xmlrpc/XmlRpcSelfSerializing.java | 27 + .../dynamo/xmlrpc/XmlRpcServlet.java | 160 + .../dynamo/xmlrpc/XmlRpcSessionInfo.java | 463 + .../dynamo/xmlrpc/XmlRpcSubSystem.java | 790 ++ .../dynamo/xmlrpc/XmlRpcTypeNames.java | 38 + .../com/silverwrist/dynamo/testmod/Main.java | 109 + .../dynamo/testmod/TestMod1DClass.java | 103 + .../dynamo/testmod/TestMod1DObject.java | 109 + .../dynamo/test/SimpleVelocityObject.java | 88 + .../dynamo/test/TestApplication.java | 214 + .../silverwrist/dynamo/test/TestServlet1.java | 101 + .../silverwrist/dynamo/test/TestServlet2.java | 71 + .../dynamo/test/TestServlet2Output.java | 90 + .../com/silverwrist/venice/ButtonType.java | 73 + .../silverwrist/venice/VeniceNamespaces.java | 61 + .../com/silverwrist/venice/VeniceVersion.java | 24 + .../venice/app/StartupShutdownAuditor.java | 148 + .../app/UserDefaultNamespaceHolder.java | 167 + .../venice/app/VeniceAppMessages.properties | 28 + .../venice/app/VeniceApplication.java | 262 + .../venice/app/VeniceExceptionTranslator.java | 91 + .../app/VeniceUserPropertyTranslator.java | 61 + .../venice/content/ButtonSupplier.java | 408 + .../venice/content/ButtonToken.java | 77 + .../venice/content/ContentMessages.properties | 29 + .../content/DateFormatterBottomHalf.java | 42 + .../venice/content/DateFormatterTopHalf.java | 162 + .../DefaultDateFormatterBottomHalf.java | 117 + .../silverwrist/venice/content/ErrorBox.java | 326 + .../content/StandardContentSupplier.java | 307 + .../venice/content/StdTextMessage.java | 205 + .../content/UserDateFormatterBottomHalf.java | 168 + .../venice/content/UserPhotoRenderer.java | 323 + .../venice/content/VelocityView.java | 230 + .../venice/dialog/UserPhotoField.java | 163 + .../dialog/VeniceDialogItemFactory.java | 50 + .../venice/dialog/VeniceDialogManager.java | 187 + .../dialog/VeniceDialogMessages.properties | 19 + .../venice/except/StyleSheetException.java | 41 + .../venice/frame/FrameAssembler.java | 441 + .../silverwrist/venice/frame/FrameDialog.java | 109 + .../venice/frame/FrameMessages.properties | 23 + .../venice/frame/FrameParameters.java | 60 + .../venice/frame/FrameRendering.java | 102 + .../venice/frame/FramedContent.java | 61 + .../venice/frame/StyleSheetData.java | 59 + .../venice/frame/StyleSheetServlet.java | 288 + .../venice/frame/TempFramedContent.java | 58 + .../venice/iface/ButtonProvider.java | 26 + .../venice/iface/ContentBlock.java | 24 + .../venice/iface/ContentBlockProvider.java | 26 + .../venice/iface/MenuProvider.java | 31 + .../venice/iface/MenuRenderObject.java | 24 + .../silverwrist/venice/iface/RenderImage.java | 30 + .../venice/iface/StylesheetMapper.java | 24 + .../iface/UserDefaultPropertyNamespace.java | 26 + ...rDefaultPropertyNamespaceRegistration.java | 26 + .../venice/menu/LeftMenuRendering.java | 239 + .../venice/menu/MenuDatabaseOps.java | 92 + .../venice/menu/MenuDatabaseOps_mysql.java | 118 + .../venice/menu/MenuDefinition.java | 125 + .../venice/menu/MenuItemDefinition.java | 167 + .../silverwrist/venice/menu/MenuManager.java | 188 + .../venice/menu/StandardMenuRendering.java | 290 + .../venice/script/LibraryVenice.java | 215 + .../venice/script/LibraryVeniceCast.java | 107 + .../venice/servlet/BinaryPageData.java | 76 + .../venice/servlet/FrameServlet.java | 179 + .../servlet/FrameServletMessages.properties | 21 + .../silverwrist/venice/servlet/PageData.java | 70 + .../venice/servlet/TextPageData.java | 145 + .../venice/servlet/UserServlet.java | 52 + .../venice/session/CookieAuthenticator.java | 51 + .../PasswordRecoveryAuthenticator.java | 78 + .../session/PasswordRecoveryRequest.java | 65 + .../session/PasswordRecoveryServlet.java | 69 + .../venice/session/SessionInfoParams.java | 38 + .../venice/session/SessionMessages.properties | 22 + .../venice/session/VeniceSessionManager.java | 466 + .../util/StringTemplateContentBlock.java | 123 + .../venice/xmlrpc/VeniceCreateSession.java | 99 + .../venice/xmlrpc/VeniceFaultCodes.java | 34 + .../xmlrpc/VeniceXmlRpcMessages.properties | 19 + .../venice/sourceid/FederationManager.java | 34 + .../sourceid/FederationManagerObject.java | 190 + .../venice/sourceid/LibrarySourceID.java | 79 + .../sourceid/SourceIDMessages.properties | 19 + .../venice/sourceid/VeniceAccountHandler.java | 191 + .../venice/sourceid/VeniceAccountOps.java | 75 + .../sourceid/VeniceAccountOps_mysql.java | 214 + test-data/scripts/module_test1.js | 26 + test-data/scripts/module_test2.js | 26 + test-data/scripts/script_test1.js | 46 + test-data/scripts/script_test1a.js | 46 + test-data/scripts/script_test2.js | 46 + test-data/velocity/hitcount.vm | 23 + test-data/velocity/test2.vm | 28 + test-data/velocity/test2a.vm | 29 + venice-data-sso/sp/scripts/login.js | 248 + .../sp/scripts/sourceid/defederate.js | 40 + .../sp/scripts/sourceid/errorHandler.js | 25 + .../sp/scripts/sourceid/federate.js | 43 + .../sp/scripts/sourceid/login_sso.js | 40 + .../sp/scripts/sourceid/login_sso_fail.js | 34 + .../sp/scripts/sourceid/login_sso_ok.js | 77 + .../sp/scripts/sourceid/logout_sso.js | 42 + venice-data-sso/sp/scripts/top.js | 72 + .../sp/velocity/sourceid/login_dialog.vm | 33 + venice-data-sso/sp/velocity/sourceid/top.vm | 59 + venice-data/dialogs/login.dlg.xml | 33 + venice-data/dialogs/new_account.dlg.xml | 46 + venice-data/dialogs/user_profile.dlg.xml | 65 + venice-data/dialogs/verify.dlg.xml | 33 + venice-data/scripts/login.js | 219 + venice-data/scripts/logout.js | 48 + venice-data/scripts/new_account.js | 55 + venice-data/scripts/new_account_2.js | 173 + venice-data/scripts/profile.js | 274 + venice-data/scripts/profile_photo.js | 109 + venice-data/scripts/quick_email.js | 48 + venice-data/scripts/top.js | 43 + venice-data/scripts/verify_email.js | 152 + venice-data/util/create_profile.js | 120 + venice-data/util/password_recovery.js | 62 + venice-data/util/session_init.js | 67 + venice-data/util/setup_user.js | 45 + venice-data/velocity/VM_global_library.vm | 43 + venice-data/velocity/common/stdtextmessage.vm | 33 + venice-data/velocity/frame.vm | 135 + venice-data/velocity/password_changed.vm | 24 + venice-data/velocity/stylesheets/adv_base.vm | 95 + .../velocity/stylesheets/normal_base.vm | 99 + venice-data/velocity/user/profile.vm | 73 + venice-data/velocity/user/user_photo.vm | 39 + venice-data/xmlrpc/session-metadata.xml | 45 + venice-data/xmlrpc/session.js | 97 + venice-data/xmlrpc/siteinfo-metadata.xml | 33 + venice-data/xmlrpc/siteinfo.js | 53 + venice-web/default.jsp | 22 + venice-web/images/buttons/classic/add.jpg | Bin 0 -> 2429 bytes .../images/buttons/classic/add_to_hotlist.jpg | Bin 0 -> 3278 bytes .../images/buttons/classic/add_topic.jpg | Bin 0 -> 2769 bytes .../images/buttons/classic/archive_topic.jpg | Bin 0 -> 2964 bytes .../images/buttons/classic/arrow_next.jpg | Bin 0 -> 2524 bytes .../images/buttons/classic/arrow_previous.jpg | Bin 0 -> 2867 bytes venice-web/images/buttons/classic/cancel.jpg | Bin 0 -> 2437 bytes .../buttons/classic/conference_list.jpg | Bin 0 -> 3079 bytes .../images/buttons/classic/configure.jpg | Bin 0 -> 2743 bytes venice-web/images/buttons/classic/create.jpg | Bin 0 -> 2435 bytes .../images/buttons/classic/create_new.jpg | Bin 0 -> 2865 bytes .../images/buttons/classic/delete_topic.jpg | Bin 0 -> 3245 bytes .../images/buttons/classic/filter_user.jpg | Bin 0 -> 2944 bytes venice-web/images/buttons/classic/find.jpg | Bin 0 -> 2434 bytes .../images/buttons/classic/freeze_topic.jpg | Bin 0 -> 3245 bytes venice-web/images/buttons/classic/go.jpg | Bin 0 -> 2271 bytes venice-web/images/buttons/classic/hide.jpg | Bin 0 -> 2398 bytes .../images/buttons/classic/hide_topic.jpg | Bin 0 -> 3037 bytes venice-web/images/buttons/classic/invite.jpg | Bin 0 -> 2411 bytes .../images/buttons/classic/join_now.jpg | Bin 0 -> 2898 bytes venice-web/images/buttons/classic/login.jpg | Bin 0 -> 2656 bytes venice-web/images/buttons/classic/manage.jpg | Bin 0 -> 2776 bytes venice-web/images/buttons/classic/move.jpg | Bin 0 -> 2408 bytes .../images/buttons/classic/next_keep_new.jpg | Bin 0 -> 3257 bytes .../images/buttons/classic/next_topic.jpg | Bin 0 -> 2746 bytes venice-web/images/buttons/classic/no.jpg | Bin 0 -> 2165 bytes venice-web/images/buttons/classic/nuke.jpg | Bin 0 -> 2410 bytes venice-web/images/buttons/classic/ok.jpg | Bin 0 -> 2139 bytes venice-web/images/buttons/classic/post.jpg | Bin 0 -> 2371 bytes .../images/buttons/classic/post_go_next.jpg | Bin 0 -> 3110 bytes .../images/buttons/classic/post_go_topics.jpg | Bin 0 -> 3198 bytes .../images/buttons/classic/post_reload.jpg | Bin 0 -> 2999 bytes venice-web/images/buttons/classic/preview.jpg | Bin 0 -> 2745 bytes venice-web/images/buttons/classic/publish.jpg | Bin 0 -> 2732 bytes .../images/buttons/classic/read_new.jpg | Bin 0 -> 2672 bytes .../images/buttons/classic/reminder.jpg | Bin 0 -> 2673 bytes venice-web/images/buttons/classic/remove.jpg | Bin 0 -> 2881 bytes .../images/buttons/classic/scribble.jpg | Bin 0 -> 2665 bytes venice-web/images/buttons/classic/search.jpg | Bin 0 -> 2448 bytes .../images/buttons/classic/send_again.jpg | Bin 0 -> 2955 bytes .../images/buttons/classic/send_email.jpg | Bin 0 -> 2857 bytes venice-web/images/buttons/classic/set.jpg | Bin 0 -> 2396 bytes venice-web/images/buttons/classic/show.jpg | Bin 0 -> 2409 bytes .../images/buttons/classic/show_topic.jpg | Bin 0 -> 3191 bytes .../images/buttons/classic/topic_list.jpg | Bin 0 -> 2718 bytes .../images/buttons/classic/transparent.gif | Bin 0 -> 76 bytes .../buttons/classic/unarchive_topic.jpg | Bin 0 -> 3494 bytes .../images/buttons/classic/unfreeze_topic.jpg | Bin 0 -> 3431 bytes venice-web/images/buttons/classic/update.jpg | Bin 0 -> 2600 bytes venice-web/images/buttons/classic/upload.jpg | Bin 0 -> 2503 bytes .../images/buttons/classic/user_accept.jpg | Bin 0 -> 2678 bytes .../images/buttons/classic/user_decline.jpg | Bin 0 -> 2849 bytes venice-web/images/buttons/classic/yes.jpg | Bin 0 -> 2213 bytes venice-web/images/buttons/gelcap/add.jpg | Bin 0 -> 3078 bytes .../images/buttons/gelcap/add_to_hotlist.jpg | Bin 0 -> 3394 bytes .../images/buttons/gelcap/add_topic.jpg | Bin 0 -> 3618 bytes .../images/buttons/gelcap/archive_topic.jpg | Bin 0 -> 3660 bytes .../images/buttons/gelcap/arrow_next.jpg | Bin 0 -> 3329 bytes .../images/buttons/gelcap/arrow_previous.jpg | Bin 0 -> 3506 bytes venice-web/images/buttons/gelcap/cancel.jpg | Bin 0 -> 2581 bytes .../images/buttons/gelcap/conference_list.jpg | Bin 0 -> 3703 bytes .../images/buttons/gelcap/configure.jpg | Bin 0 -> 3456 bytes venice-web/images/buttons/gelcap/create.jpg | Bin 0 -> 3022 bytes .../images/buttons/gelcap/create_new.jpg | Bin 0 -> 3711 bytes .../images/buttons/gelcap/delete_topic.jpg | Bin 0 -> 3896 bytes .../images/buttons/gelcap/filter_user.jpg | Bin 0 -> 3376 bytes venice-web/images/buttons/gelcap/find.jpg | Bin 0 -> 2973 bytes .../images/buttons/gelcap/freeze_topic.jpg | Bin 0 -> 3488 bytes venice-web/images/buttons/gelcap/go.jpg | Bin 0 -> 2687 bytes venice-web/images/buttons/gelcap/hide.jpg | Bin 0 -> 3088 bytes .../images/buttons/gelcap/hide_topic.jpg | Bin 0 -> 3513 bytes venice-web/images/buttons/gelcap/invite.jpg | Bin 0 -> 3030 bytes venice-web/images/buttons/gelcap/join_now.jpg | Bin 0 -> 3145 bytes venice-web/images/buttons/gelcap/login.jpg | Bin 0 -> 3060 bytes venice-web/images/buttons/gelcap/manage.jpg | Bin 0 -> 3282 bytes venice-web/images/buttons/gelcap/move.jpg | Bin 0 -> 2853 bytes .../images/buttons/gelcap/next_keep_new.jpg | Bin 0 -> 3704 bytes .../images/buttons/gelcap/next_topic.jpg | Bin 0 -> 3367 bytes venice-web/images/buttons/gelcap/no.jpg | Bin 0 -> 2388 bytes venice-web/images/buttons/gelcap/nuke.jpg | Bin 0 -> 3281 bytes venice-web/images/buttons/gelcap/ok.jpg | Bin 0 -> 2728 bytes venice-web/images/buttons/gelcap/post.jpg | Bin 0 -> 3084 bytes .../images/buttons/gelcap/post_go_next.jpg | Bin 0 -> 3968 bytes .../images/buttons/gelcap/post_go_topics.jpg | Bin 0 -> 3872 bytes .../images/buttons/gelcap/post_reload.jpg | Bin 0 -> 3808 bytes venice-web/images/buttons/gelcap/preview.jpg | Bin 0 -> 3273 bytes venice-web/images/buttons/gelcap/publish.jpg | Bin 0 -> 3224 bytes venice-web/images/buttons/gelcap/read_new.jpg | Bin 0 -> 3378 bytes venice-web/images/buttons/gelcap/reminder.jpg | Bin 0 -> 3418 bytes venice-web/images/buttons/gelcap/remove.jpg | Bin 0 -> 3281 bytes venice-web/images/buttons/gelcap/scribble.jpg | Bin 0 -> 3431 bytes venice-web/images/buttons/gelcap/search.jpg | Bin 0 -> 3125 bytes .../images/buttons/gelcap/send_again.jpg | Bin 0 -> 3552 bytes .../images/buttons/gelcap/send_email.jpg | Bin 0 -> 3657 bytes venice-web/images/buttons/gelcap/set.jpg | Bin 0 -> 2965 bytes venice-web/images/buttons/gelcap/show.jpg | Bin 0 -> 3036 bytes .../images/buttons/gelcap/show_topic.jpg | Bin 0 -> 3498 bytes .../images/buttons/gelcap/topic_list.jpg | Bin 0 -> 3397 bytes .../images/buttons/gelcap/transparent.gif | Bin 0 -> 76 bytes .../images/buttons/gelcap/unarchive_topic.jpg | Bin 0 -> 3759 bytes .../images/buttons/gelcap/unfreeze_topic.jpg | Bin 0 -> 3548 bytes venice-web/images/buttons/gelcap/update.jpg | Bin 0 -> 3354 bytes venice-web/images/buttons/gelcap/upload.jpg | Bin 0 -> 3295 bytes .../images/buttons/gelcap/user_accept.jpg | Bin 0 -> 3259 bytes .../images/buttons/gelcap/user_decline.jpg | Bin 0 -> 2828 bytes venice-web/images/buttons/gelcap/yes.jpg | Bin 0 -> 2881 bytes venice-web/images/photo_not_avail.gif | Bin 0 -> 5948 bytes venice-web/images/powered-by-venice.gif | Bin 0 -> 8797 bytes venice-web/images/purple-ball.gif | Bin 0 -> 926 bytes venice-web/images/temp/.xvpics/banner-ad.jpg | Bin 0 -> 868 bytes venice-web/images/temp/.xvpics/site-logo.jpg | Bin 0 -> 3667 bytes venice-web/images/temp/banner-ad.jpg | Bin 0 -> 10297 bytes venice-web/images/temp/site-logo.jpg | Bin 0 -> 3004 bytes venice-web/images/venice-favicon.ico | Bin 0 -> 1078 bytes venice-web/images/venice-icon.png | Bin 0 -> 1074 bytes venice-web/static/about-venice.html | 38 + venice-web/static/images/sw-main.gif | Bin 0 -> 4544 bytes venice-web/static/images/venicelogo.jpg | Bin 0 -> 9323 bytes 682 files changed, 85738 insertions(+) create mode 100644 .cvsignore create mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 NEWS create mode 100644 README create mode 100644 build.properties.sample create mode 100644 build.xml create mode 100644 conf-sso/extra-db-mysql.sql create mode 100644 conf-sso/sp/dynamo.xml create mode 100644 conf-sso/sp/logging.xml create mode 100644 conf-sso/sp/sourceid-sso-providers.xml create mode 100644 conf-sso/sp/sourceid-sso.xml create mode 100644 conf-sso/sp/sp-descriptor.xml create mode 100644 conf-sso/sp/venice-sp.keystore create mode 100644 conf-sso/sp/web.xml create mode 100644 conf/db-init-mysql.sql create mode 100644 conf/dynamo-test.xml create mode 100644 conf/dynamo-venice.xml create mode 100644 conf/logging-test.xml create mode 100644 conf/logging-venice.xml create mode 100644 conf/std_render_macro_library.vm create mode 100644 conf/venice-db-init-mysql.sql create mode 100644 conf/web-test.xml create mode 100644 conf/web-venice.xml create mode 100644 docs/buttons/.gitignore create mode 100644 docs/buttons/bn_blank80.png create mode 100644 docs/buttons/bn_delete.png create mode 100644 docs/buttons/bn_save.png create mode 100644 docs/buttons/classic.xcf create mode 100644 docs/buttons/gelcap_green.xcf create mode 100644 docs/buttons/gelcap_pink.xcf create mode 100644 docs/buttons/gelcap_red.xcf create mode 100644 docs/buttons/gelcap_teal.xcf create mode 100644 docs/buttons/gelcap_violet.xcf create mode 100644 docs/buttons/gelcap_yellow.xcf create mode 100644 docs/design-goals.html create mode 100644 docs/identifiers.html create mode 100644 docs/user-acl-truth-table.sxc create mode 100644 drivers/.gitignore create mode 100644 drivers/README.drivers create mode 100644 resources/dynamo-test-module/res1.txt create mode 100644 src/baseutil/com/silverwrist/util/AnyCharMatcher.java create mode 100644 src/baseutil/com/silverwrist/util/BooleanValues.properties create mode 100644 src/baseutil/com/silverwrist/util/Country.java create mode 100644 src/baseutil/com/silverwrist/util/HardSoftCache.java create mode 100644 src/baseutil/com/silverwrist/util/IOUtils.java create mode 100644 src/baseutil/com/silverwrist/util/International.java create mode 100644 src/baseutil/com/silverwrist/util/Language.java create mode 100644 src/baseutil/com/silverwrist/util/MySQLUtils.java create mode 100644 src/baseutil/com/silverwrist/util/OptionSet.java create mode 100644 src/baseutil/com/silverwrist/util/SQLUtils.java create mode 100644 src/baseutil/com/silverwrist/util/StringUtils.java create mode 100644 src/baseutil/com/silverwrist/util/countries.properties create mode 100644 src/baseutil/com/silverwrist/util/image/ImageNormalizer.java create mode 100644 src/baseutil/com/silverwrist/util/image/ImageNormalizerException.java create mode 100644 src/baseutil/com/silverwrist/util/languages.properties create mode 100644 src/baseutil/com/silverwrist/util/xml/DOMElementHelper.java create mode 100644 src/baseutil/com/silverwrist/util/xml/XMLLoadException.java create mode 100644 src/baseutil/com/silverwrist/util/xml/XMLLoader.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/BrowserFlag.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/DynamoVersion.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/HttpStatusCode.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/RequestType.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/UserInfoNamespace.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/Verb.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/WebConstants.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainerMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationServiceManager.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/BackgroundProcessor.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ComponentResName.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionManager.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionPoint.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/DataItemRenderer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/HeapContents.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ListRenderer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/PropertySerializationSupport.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/RewriteRule.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/ServiceKey.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/app/WrappedResourceProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseConnectionPool.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/DefaultHashAuthenticator.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GlobalDataManagerObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GroupObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/GroupProxy.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/ImageStore.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCache.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/OpsBase.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserManagement.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslator.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslatorInstall.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserProxy.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/UserProxyManagement.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/db/WrappedConnection.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/BaseDialogField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/ButtonCaptions.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/CheckBoxField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/CommonTextField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/CountryListField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/DefaultDialogLAF.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogManager.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/DynamoIDField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/EmailAddressField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/HeaderItem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/HiddenField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/IntegerField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/LocaleListField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/PasswordField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/PickListField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/StdButton.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/StdItemFactory.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/TextField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dialog/TimeZoneListField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationAdapter.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEventRequest.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationListener.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateListener.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventListener.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/GlobalBlockUpdateEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/GlobalPropertyUpdateEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/GlobalUpdateEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartListener.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/SessionEventRequest.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoAdapter.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoListener.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindListener.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/UserPropertyUpdateEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/event/UserUpdateEvent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/AuthenticationException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/CallFailureException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/CodeNotFoundException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ConfigException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DatabaseException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DialogException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectRuntimeException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DynamoException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DynamoExceptionMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DynamoRuntimeException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DynamoSecurityException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ExternalException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ExternalRuntimeException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/GroupRuntimeException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/MailException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ModuleException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchObjectException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchResourceException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchServiceException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ObjectStoreException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ProxyException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/RenderClassCreationException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/RenderingException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/RequestParseException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ScriptingException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/SecurityRuntimeException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/UnknownDialogFieldException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/ValidationException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/Application.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ApplicationSubstrate.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecord.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordCompose.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordFactory.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordRetrieval.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordSet.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/Authenticator.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/AuthenticatorLookup.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/AuthenticatorRegistration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/BackgroundScheduler.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/BackgroundTask.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/BinaryRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/BinaryRenderer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/BrowserData.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/BrowserDataProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ChainParameterInput.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ComponentInitialize.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ComponentShutdown.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ConnectionBackEnd.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ConnectionFrontEnd.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/CookieControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DBConnectionPool.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DBUtilities.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DataItem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/Dialog.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogButton.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogFactoryConfig.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogField.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogHiddenItem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogItem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogItemFactory.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogLoader.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DialogPLAF.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamicClass.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamicObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamicWrapper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoAce.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoAcl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoGroup.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoPermission.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoUser.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/EventListenerRegistration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ExceptionTranslator.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ExceptionTranslatorRegistration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ExternalAppAttributes.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ExternalSessionAttributes.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/HeaderInput.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/HeaderOutput.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/HookServiceProviders.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/MIMETypeMapper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/Module.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ModuleFunctions.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ModuleSite.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/NamedObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ObjectProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ObjectStore.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/OutputObjectFilter.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/OutputObjectFilterRegistration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/PostDynamicUpdate.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/PropertySerializer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/PropertySerializerRegistration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/QueryRenderer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/RenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/RenderFlags.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/RenderImmediate.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/Renderer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/RendererRegistration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/Request.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/RequestPreprocessor.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/RequestPreprocessorRegistration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ResourceProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ResourceProviderManager.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ScriptEngineConfig.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ScriptEngineRegisterObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ScriptExecute.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/SecureObjectStore.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/SelfRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/SelfRenderable.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/ServiceProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/SessionInfo.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/SessionInfoProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/TextRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/TextRenderer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/URLRewriter.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/mail/MailMessage.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/mail/MailMessageImpl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/mail/MailMessageProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/mail/MailMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/mail/MailProperties.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/mail/MailSubSystem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/module/ModuleLoader.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/module/ModuleManager.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/module/ModuleMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/module/ModuleOperations.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/obj/JavaDynamicClass.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/obj/JavaDynamicObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/obj/JavaObjectBindery.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/DeclaredObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/ExitScript.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/InternalRequest.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/LibraryCast.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/LibraryDynamo.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/LibraryLogger.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/ReturnValue.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/ScriptController.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngine.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngineMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/script/ScriptExecuteHelper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AceCache.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AceObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AceOperations.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AceOperations_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AclObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AclOperations.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AclOperations_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AuditReadOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AuditReadOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AuditWriteOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/AuditWriteOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/LibraryAudit.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/PermObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/PrincipalID.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/ReadAuditRecord.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/ReadAuditRecordSet.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/RegisterNewAce.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/SRMObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/SRMOperations.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/SRMOperations_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/SecurityMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/SecurityReferenceMonitor.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/SystemAuditManager.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/security/WriteAuditRecord.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/BrowserDatabase.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/BrowserDatabaseEntry.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ChainForward.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/FileUploadRequestImpl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/GetRemapperData.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/HttpMethod.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/HttpSessionInfo.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ImageServlet.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/NormalRequestImpl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/NullBrowserData.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/NullResponse.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/Remapper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/RemapperData.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/RemapperElement.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/RemapperServlet.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/RequestImplBase.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ScriptExecServlet.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletBase.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletBaseMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletBinaryRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletBrowserData.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletBrowserDataProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletChainParameterInput.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletCookieControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletExternalAppAttributes.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletExternalSessionAttributes.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletHeaderInput.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletHeaderOutput.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletInitObjectProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletMIMETypeMapper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletSelfRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/ServletTextRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/SubObjectSelfRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/SubObjectTextRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/URLRewriterImpl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/servlet/browscap.ini create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/BaseDelegatingObjectProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/BaseDelegatingServiceProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/BufferTextRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/DefaultSessionInfoProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/DynamoIDKey.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/FilterRequest.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/FilterTextRenderControl.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/ForwardToPath.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/ForwardToServlet.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/Forwarder.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/GetObjectMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/GetObjectUtils.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/HttpErrorMessage.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/IDNameCacheObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/IDUtils.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/MemoryObjectStore.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/NamespaceDelegatingObjectProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/NoContent.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/NullSessionInfo.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/ObjectVisitor.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/PropertyKey.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/PropertyUtils.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/QualifiedNameKey.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/Redirect.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/RenderingExceptionWrapper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/RequestHelper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/ShutdownHashtableRemove.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/ShutdownVectorRemove.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/SimpleServiceProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/SingleNamespaceObjectProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/SingletonServiceProvider.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/StaticDataItem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/UtilityMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/RenderableContext.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/StdObject.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/VelocityDynamoResourceLoader.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/VelocityMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/VelocityOwnTemplate.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/VelocityParamSupplier.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/VelocityRenderable.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/VelocityRenderer.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/velocity/VelocityRendererConfig.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/Capabilities.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/FaultCode.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/IntrospectionDispatcher.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/MultiCallDispatcher.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/MultiCallRequest.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/RegisteredDispatcher.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/RegisteredFaultMapper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/ReplaceSessionRequest.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/ScriptDispatcher.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/SystemFaultCode.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/Validator1Suite.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XMLMetadata.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcConfiguration.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcCreateSession.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcDispatcher.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcFaultMapper.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcMethodNotFound.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcParameterError.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcRequest.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcResult.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcSelfSerializing.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcServlet.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcSessionInfo.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcSubSystem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/xmlrpc/XmlRpcTypeNames.java create mode 100644 src/dynamo-test-module/com/silverwrist/dynamo/testmod/Main.java create mode 100644 src/dynamo-test-module/com/silverwrist/dynamo/testmod/TestMod1DClass.java create mode 100644 src/dynamo-test-module/com/silverwrist/dynamo/testmod/TestMod1DObject.java create mode 100644 src/dynamo-test/com/silverwrist/dynamo/test/SimpleVelocityObject.java create mode 100644 src/dynamo-test/com/silverwrist/dynamo/test/TestApplication.java create mode 100644 src/dynamo-test/com/silverwrist/dynamo/test/TestServlet1.java create mode 100644 src/dynamo-test/com/silverwrist/dynamo/test/TestServlet2.java create mode 100644 src/dynamo-test/com/silverwrist/dynamo/test/TestServlet2Output.java create mode 100644 src/venice-base/com/silverwrist/venice/ButtonType.java create mode 100644 src/venice-base/com/silverwrist/venice/VeniceNamespaces.java create mode 100644 src/venice-base/com/silverwrist/venice/VeniceVersion.java create mode 100644 src/venice-base/com/silverwrist/venice/app/StartupShutdownAuditor.java create mode 100644 src/venice-base/com/silverwrist/venice/app/UserDefaultNamespaceHolder.java create mode 100644 src/venice-base/com/silverwrist/venice/app/VeniceAppMessages.properties create mode 100644 src/venice-base/com/silverwrist/venice/app/VeniceApplication.java create mode 100644 src/venice-base/com/silverwrist/venice/app/VeniceExceptionTranslator.java create mode 100644 src/venice-base/com/silverwrist/venice/app/VeniceUserPropertyTranslator.java create mode 100644 src/venice-base/com/silverwrist/venice/content/ButtonSupplier.java create mode 100644 src/venice-base/com/silverwrist/venice/content/ButtonToken.java create mode 100644 src/venice-base/com/silverwrist/venice/content/ContentMessages.properties create mode 100644 src/venice-base/com/silverwrist/venice/content/DateFormatterBottomHalf.java create mode 100644 src/venice-base/com/silverwrist/venice/content/DateFormatterTopHalf.java create mode 100644 src/venice-base/com/silverwrist/venice/content/DefaultDateFormatterBottomHalf.java create mode 100644 src/venice-base/com/silverwrist/venice/content/ErrorBox.java create mode 100644 src/venice-base/com/silverwrist/venice/content/StandardContentSupplier.java create mode 100644 src/venice-base/com/silverwrist/venice/content/StdTextMessage.java create mode 100644 src/venice-base/com/silverwrist/venice/content/UserDateFormatterBottomHalf.java create mode 100644 src/venice-base/com/silverwrist/venice/content/UserPhotoRenderer.java create mode 100644 src/venice-base/com/silverwrist/venice/content/VelocityView.java create mode 100644 src/venice-base/com/silverwrist/venice/dialog/UserPhotoField.java create mode 100644 src/venice-base/com/silverwrist/venice/dialog/VeniceDialogItemFactory.java create mode 100644 src/venice-base/com/silverwrist/venice/dialog/VeniceDialogManager.java create mode 100644 src/venice-base/com/silverwrist/venice/dialog/VeniceDialogMessages.properties create mode 100644 src/venice-base/com/silverwrist/venice/except/StyleSheetException.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/FrameAssembler.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/FrameDialog.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/FrameMessages.properties create mode 100644 src/venice-base/com/silverwrist/venice/frame/FrameParameters.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/FrameRendering.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/FramedContent.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/StyleSheetData.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/StyleSheetServlet.java create mode 100644 src/venice-base/com/silverwrist/venice/frame/TempFramedContent.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/ButtonProvider.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/ContentBlock.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/ContentBlockProvider.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/MenuProvider.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/MenuRenderObject.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/RenderImage.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/StylesheetMapper.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/UserDefaultPropertyNamespace.java create mode 100644 src/venice-base/com/silverwrist/venice/iface/UserDefaultPropertyNamespaceRegistration.java create mode 100644 src/venice-base/com/silverwrist/venice/menu/LeftMenuRendering.java create mode 100644 src/venice-base/com/silverwrist/venice/menu/MenuDatabaseOps.java create mode 100644 src/venice-base/com/silverwrist/venice/menu/MenuDatabaseOps_mysql.java create mode 100644 src/venice-base/com/silverwrist/venice/menu/MenuDefinition.java create mode 100644 src/venice-base/com/silverwrist/venice/menu/MenuItemDefinition.java create mode 100644 src/venice-base/com/silverwrist/venice/menu/MenuManager.java create mode 100644 src/venice-base/com/silverwrist/venice/menu/StandardMenuRendering.java create mode 100644 src/venice-base/com/silverwrist/venice/script/LibraryVenice.java create mode 100644 src/venice-base/com/silverwrist/venice/script/LibraryVeniceCast.java create mode 100644 src/venice-base/com/silverwrist/venice/servlet/BinaryPageData.java create mode 100644 src/venice-base/com/silverwrist/venice/servlet/FrameServlet.java create mode 100644 src/venice-base/com/silverwrist/venice/servlet/FrameServletMessages.properties create mode 100644 src/venice-base/com/silverwrist/venice/servlet/PageData.java create mode 100644 src/venice-base/com/silverwrist/venice/servlet/TextPageData.java create mode 100644 src/venice-base/com/silverwrist/venice/servlet/UserServlet.java create mode 100644 src/venice-base/com/silverwrist/venice/session/CookieAuthenticator.java create mode 100644 src/venice-base/com/silverwrist/venice/session/PasswordRecoveryAuthenticator.java create mode 100644 src/venice-base/com/silverwrist/venice/session/PasswordRecoveryRequest.java create mode 100644 src/venice-base/com/silverwrist/venice/session/PasswordRecoveryServlet.java create mode 100644 src/venice-base/com/silverwrist/venice/session/SessionInfoParams.java create mode 100644 src/venice-base/com/silverwrist/venice/session/SessionMessages.properties create mode 100644 src/venice-base/com/silverwrist/venice/session/VeniceSessionManager.java create mode 100644 src/venice-base/com/silverwrist/venice/util/StringTemplateContentBlock.java create mode 100644 src/venice-base/com/silverwrist/venice/xmlrpc/VeniceCreateSession.java create mode 100644 src/venice-base/com/silverwrist/venice/xmlrpc/VeniceFaultCodes.java create mode 100644 src/venice-base/com/silverwrist/venice/xmlrpc/VeniceXmlRpcMessages.properties create mode 100644 src/venice-sso-helper/com/silverwrist/venice/sourceid/FederationManager.java create mode 100644 src/venice-sso-helper/com/silverwrist/venice/sourceid/FederationManagerObject.java create mode 100644 src/venice-sso-helper/com/silverwrist/venice/sourceid/LibrarySourceID.java create mode 100644 src/venice-sso-helper/com/silverwrist/venice/sourceid/SourceIDMessages.properties create mode 100644 src/venice-sso-helper/com/silverwrist/venice/sourceid/VeniceAccountHandler.java create mode 100644 src/venice-sso-helper/com/silverwrist/venice/sourceid/VeniceAccountOps.java create mode 100644 src/venice-sso-helper/com/silverwrist/venice/sourceid/VeniceAccountOps_mysql.java create mode 100644 test-data/scripts/module_test1.js create mode 100644 test-data/scripts/module_test2.js create mode 100644 test-data/scripts/script_test1.js create mode 100644 test-data/scripts/script_test1a.js create mode 100644 test-data/scripts/script_test2.js create mode 100644 test-data/velocity/hitcount.vm create mode 100644 test-data/velocity/test2.vm create mode 100644 test-data/velocity/test2a.vm create mode 100644 venice-data-sso/sp/scripts/login.js create mode 100644 venice-data-sso/sp/scripts/sourceid/defederate.js create mode 100644 venice-data-sso/sp/scripts/sourceid/errorHandler.js create mode 100644 venice-data-sso/sp/scripts/sourceid/federate.js create mode 100644 venice-data-sso/sp/scripts/sourceid/login_sso.js create mode 100644 venice-data-sso/sp/scripts/sourceid/login_sso_fail.js create mode 100644 venice-data-sso/sp/scripts/sourceid/login_sso_ok.js create mode 100644 venice-data-sso/sp/scripts/sourceid/logout_sso.js create mode 100644 venice-data-sso/sp/scripts/top.js create mode 100644 venice-data-sso/sp/velocity/sourceid/login_dialog.vm create mode 100644 venice-data-sso/sp/velocity/sourceid/top.vm create mode 100644 venice-data/dialogs/login.dlg.xml create mode 100644 venice-data/dialogs/new_account.dlg.xml create mode 100644 venice-data/dialogs/user_profile.dlg.xml create mode 100644 venice-data/dialogs/verify.dlg.xml create mode 100644 venice-data/scripts/login.js create mode 100644 venice-data/scripts/logout.js create mode 100644 venice-data/scripts/new_account.js create mode 100644 venice-data/scripts/new_account_2.js create mode 100644 venice-data/scripts/profile.js create mode 100644 venice-data/scripts/profile_photo.js create mode 100644 venice-data/scripts/quick_email.js create mode 100644 venice-data/scripts/top.js create mode 100644 venice-data/scripts/verify_email.js create mode 100644 venice-data/util/create_profile.js create mode 100644 venice-data/util/password_recovery.js create mode 100644 venice-data/util/session_init.js create mode 100644 venice-data/util/setup_user.js create mode 100644 venice-data/velocity/VM_global_library.vm create mode 100644 venice-data/velocity/common/stdtextmessage.vm create mode 100644 venice-data/velocity/frame.vm create mode 100644 venice-data/velocity/password_changed.vm create mode 100644 venice-data/velocity/stylesheets/adv_base.vm create mode 100644 venice-data/velocity/stylesheets/normal_base.vm create mode 100644 venice-data/velocity/user/profile.vm create mode 100644 venice-data/velocity/user/user_photo.vm create mode 100644 venice-data/xmlrpc/session-metadata.xml create mode 100644 venice-data/xmlrpc/session.js create mode 100644 venice-data/xmlrpc/siteinfo-metadata.xml create mode 100644 venice-data/xmlrpc/siteinfo.js create mode 100644 venice-web/default.jsp create mode 100644 venice-web/images/buttons/classic/add.jpg create mode 100644 venice-web/images/buttons/classic/add_to_hotlist.jpg create mode 100644 venice-web/images/buttons/classic/add_topic.jpg create mode 100644 venice-web/images/buttons/classic/archive_topic.jpg create mode 100644 venice-web/images/buttons/classic/arrow_next.jpg create mode 100644 venice-web/images/buttons/classic/arrow_previous.jpg create mode 100644 venice-web/images/buttons/classic/cancel.jpg create mode 100644 venice-web/images/buttons/classic/conference_list.jpg create mode 100644 venice-web/images/buttons/classic/configure.jpg create mode 100644 venice-web/images/buttons/classic/create.jpg create mode 100644 venice-web/images/buttons/classic/create_new.jpg create mode 100644 venice-web/images/buttons/classic/delete_topic.jpg create mode 100644 venice-web/images/buttons/classic/filter_user.jpg create mode 100644 venice-web/images/buttons/classic/find.jpg create mode 100644 venice-web/images/buttons/classic/freeze_topic.jpg create mode 100644 venice-web/images/buttons/classic/go.jpg create mode 100644 venice-web/images/buttons/classic/hide.jpg create mode 100644 venice-web/images/buttons/classic/hide_topic.jpg create mode 100644 venice-web/images/buttons/classic/invite.jpg create mode 100644 venice-web/images/buttons/classic/join_now.jpg create mode 100644 venice-web/images/buttons/classic/login.jpg create mode 100644 venice-web/images/buttons/classic/manage.jpg create mode 100644 venice-web/images/buttons/classic/move.jpg create mode 100644 venice-web/images/buttons/classic/next_keep_new.jpg create mode 100644 venice-web/images/buttons/classic/next_topic.jpg create mode 100644 venice-web/images/buttons/classic/no.jpg create mode 100644 venice-web/images/buttons/classic/nuke.jpg create mode 100644 venice-web/images/buttons/classic/ok.jpg create mode 100644 venice-web/images/buttons/classic/post.jpg create mode 100644 venice-web/images/buttons/classic/post_go_next.jpg create mode 100644 venice-web/images/buttons/classic/post_go_topics.jpg create mode 100644 venice-web/images/buttons/classic/post_reload.jpg create mode 100644 venice-web/images/buttons/classic/preview.jpg create mode 100644 venice-web/images/buttons/classic/publish.jpg create mode 100644 venice-web/images/buttons/classic/read_new.jpg create mode 100644 venice-web/images/buttons/classic/reminder.jpg create mode 100644 venice-web/images/buttons/classic/remove.jpg create mode 100644 venice-web/images/buttons/classic/scribble.jpg create mode 100644 venice-web/images/buttons/classic/search.jpg create mode 100644 venice-web/images/buttons/classic/send_again.jpg create mode 100644 venice-web/images/buttons/classic/send_email.jpg create mode 100644 venice-web/images/buttons/classic/set.jpg create mode 100644 venice-web/images/buttons/classic/show.jpg create mode 100644 venice-web/images/buttons/classic/show_topic.jpg create mode 100644 venice-web/images/buttons/classic/topic_list.jpg create mode 100644 venice-web/images/buttons/classic/transparent.gif create mode 100644 venice-web/images/buttons/classic/unarchive_topic.jpg create mode 100644 venice-web/images/buttons/classic/unfreeze_topic.jpg create mode 100644 venice-web/images/buttons/classic/update.jpg create mode 100644 venice-web/images/buttons/classic/upload.jpg create mode 100644 venice-web/images/buttons/classic/user_accept.jpg create mode 100644 venice-web/images/buttons/classic/user_decline.jpg create mode 100644 venice-web/images/buttons/classic/yes.jpg create mode 100644 venice-web/images/buttons/gelcap/add.jpg create mode 100644 venice-web/images/buttons/gelcap/add_to_hotlist.jpg create mode 100644 venice-web/images/buttons/gelcap/add_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/archive_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/arrow_next.jpg create mode 100644 venice-web/images/buttons/gelcap/arrow_previous.jpg create mode 100644 venice-web/images/buttons/gelcap/cancel.jpg create mode 100644 venice-web/images/buttons/gelcap/conference_list.jpg create mode 100644 venice-web/images/buttons/gelcap/configure.jpg create mode 100644 venice-web/images/buttons/gelcap/create.jpg create mode 100644 venice-web/images/buttons/gelcap/create_new.jpg create mode 100644 venice-web/images/buttons/gelcap/delete_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/filter_user.jpg create mode 100644 venice-web/images/buttons/gelcap/find.jpg create mode 100644 venice-web/images/buttons/gelcap/freeze_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/go.jpg create mode 100644 venice-web/images/buttons/gelcap/hide.jpg create mode 100644 venice-web/images/buttons/gelcap/hide_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/invite.jpg create mode 100644 venice-web/images/buttons/gelcap/join_now.jpg create mode 100644 venice-web/images/buttons/gelcap/login.jpg create mode 100644 venice-web/images/buttons/gelcap/manage.jpg create mode 100644 venice-web/images/buttons/gelcap/move.jpg create mode 100644 venice-web/images/buttons/gelcap/next_keep_new.jpg create mode 100644 venice-web/images/buttons/gelcap/next_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/no.jpg create mode 100644 venice-web/images/buttons/gelcap/nuke.jpg create mode 100644 venice-web/images/buttons/gelcap/ok.jpg create mode 100644 venice-web/images/buttons/gelcap/post.jpg create mode 100644 venice-web/images/buttons/gelcap/post_go_next.jpg create mode 100644 venice-web/images/buttons/gelcap/post_go_topics.jpg create mode 100644 venice-web/images/buttons/gelcap/post_reload.jpg create mode 100644 venice-web/images/buttons/gelcap/preview.jpg create mode 100644 venice-web/images/buttons/gelcap/publish.jpg create mode 100644 venice-web/images/buttons/gelcap/read_new.jpg create mode 100644 venice-web/images/buttons/gelcap/reminder.jpg create mode 100644 venice-web/images/buttons/gelcap/remove.jpg create mode 100644 venice-web/images/buttons/gelcap/scribble.jpg create mode 100644 venice-web/images/buttons/gelcap/search.jpg create mode 100644 venice-web/images/buttons/gelcap/send_again.jpg create mode 100644 venice-web/images/buttons/gelcap/send_email.jpg create mode 100644 venice-web/images/buttons/gelcap/set.jpg create mode 100644 venice-web/images/buttons/gelcap/show.jpg create mode 100644 venice-web/images/buttons/gelcap/show_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/topic_list.jpg create mode 100644 venice-web/images/buttons/gelcap/transparent.gif create mode 100644 venice-web/images/buttons/gelcap/unarchive_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/unfreeze_topic.jpg create mode 100644 venice-web/images/buttons/gelcap/update.jpg create mode 100644 venice-web/images/buttons/gelcap/upload.jpg create mode 100644 venice-web/images/buttons/gelcap/user_accept.jpg create mode 100644 venice-web/images/buttons/gelcap/user_decline.jpg create mode 100644 venice-web/images/buttons/gelcap/yes.jpg create mode 100644 venice-web/images/photo_not_avail.gif create mode 100644 venice-web/images/powered-by-venice.gif create mode 100644 venice-web/images/purple-ball.gif create mode 100644 venice-web/images/temp/.xvpics/banner-ad.jpg create mode 100644 venice-web/images/temp/.xvpics/site-logo.jpg create mode 100644 venice-web/images/temp/banner-ad.jpg create mode 100644 venice-web/images/temp/site-logo.jpg create mode 100644 venice-web/images/venice-favicon.ico create mode 100644 venice-web/images/venice-icon.png create mode 100644 venice-web/static/about-venice.html create mode 100644 venice-web/static/images/sw-main.gif create mode 100644 venice-web/static/images/venicelogo.jpg diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..40caffa --- /dev/null +++ b/.cvsignore @@ -0,0 +1,28 @@ +# CVS default ignores begin +tags +TAGS +.make.state +.nse_depinfo +*~ +#* +.#* +,* +_$* +*$ +*.old +*.bak +*.BAK +*.orig +*.rej +.del-* +*.a +*.olb +*.o +*.obj +*.so +*.exe +*.Z +*.elc +*.ln +core +# CVS default ignores end diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..956db13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +assembly +build.properties +jars +javadocs +OLD +workingarea diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..969b331 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Eric J. Bowersox diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..823a123 --- /dev/null +++ b/INSTALL @@ -0,0 +1,52 @@ +INSTALLATION INSTRUCTIONS +========================= + +THE JDK INSTALLATION +-------------------- +This version of Venice runs under JDK 1.4.1. The following extensions should +be installed to the $JAVA_HOME/jre/lib/ext directory: +- JavaMail 1.3 +- JavaBeans Activation Framework 1.0.2 +- Java Advanced Imaging 1.1.1, plus the JAI ImageIO extensions + +In addition, the Xalan 2.4.1 and Xerces 2.2.1 XML tools should be installed +as "endorsed standards overrides" in the $JAVA_HOME/jre/lib/endorsed directory. + +APACHE TOMCAT +------------- +A recent version of Apache Tomcat, such as version 4.1.24, must be installed. + +JAKARTA ANT +----------- +A recent version of Jakarta Ant, such as 1.5.1, must be installed to build +Venice. + +PACKAGES REQUIRED FOR VENICE +---------------------------- +The following packages must be referenced from within build.properties: +- Java Servlet API 2.3 (use the servlet.jar file from Tomcat) +- Jakarta Bean Scripting Framework 2.3 +- Jakarta Commons Collections Library, 2.1 +- Jakarta Commons Lang Library, 1.0.1 +- Mozilla.org Rhino, 1.5R3 +- Jakarta Log4J, 1.2.7 +- Jakarta Velocity, 1.3.1 + +Optionally: +- SourceID-SSO 1.0 + +DATABASE DRIVERS REQUIRED FOR VENICE +------------------------------------ +Currently, the only database supported with Venice is MySQL. The MySQL +Connector 3.0.7 should be copied to the drivers/ subdirectory. + +BUILDING AND DEPLOYING +---------------------- +When built, the complete installation of Venice will be copied to the +subdirectory "assembly/venice". This directory may be deployed into Tomcat +directly by editing $CATALINA_HOME/conf/server.xml. + +INITIALIZING THE DATABASE +------------------------- +The script "conf/venice-db-init-mysql.sql" can be used to initialize the +database. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7714141 --- /dev/null +++ b/LICENSE @@ -0,0 +1,470 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..00fcde6 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +This branch of the code is not really usable yet. New instructions will +be posted when it is. diff --git a/build.properties.sample b/build.properties.sample new file mode 100644 index 0000000..8ed6685 --- /dev/null +++ b/build.properties.sample @@ -0,0 +1,60 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +######################################################################################### + +# [Compilation control flags] +# compile.debug=on +# compile.deprecation=off +# compile.optimize=on +# build.compiler=modern + +# [Location of Servlet API 2.3] +servlet.base=/usr/local/jakarta/jakarta-tomcat-4.1.24-LE-jdk14 +servlet.lib=${servlet.base}/common/lib +# servlet.jarfile=servlet.jar + +# [Location of Bean Scripting Framework 2.3] +bsf.base=/usr/local/jakarta/bsf-2.3.0 +# bsf.lib=${bsf.base}/lib +# bsf.jarfile=bsf.jar + +# [Location of Commons Collections Library 2.1] +collections.base=/usr/local/jakarta/commons-collections-2.1 +# collections.lib=${collections.base} +# collections.jarfile=commons-collections.jar + +# [Location of Commons Lang Library 1.0.1] +commlang.base=/usr/local/jakarta/commons-lang-1.0.1 +# commlang.lib=${commlang.base} +commlang.jarfile=commons-lang-1.0.1.jar + +# [Location of Rhino 1.5R3] +rhino.base=/usr/local/java/rhino1_5R3 +# rhino.lib=${rhino.base} +# rhino.jarfile=js.jar + +# [Location of Log4J 1.2.7] +log4j.base=/usr/local/jakarta/jakarta-log4j-1.2.7 +# log4j.lib=${log4j.base}/dist/lib +log4j.jarfile=log4j-1.2.7.jar + +# [Location of Velocity 1.3.1] +velocity.base=/usr/local/jakarta/velocity-1.3.1 +# velocity.lib=${velocity.base} +velocity.jarfile=velocity-1.3.1.jar + +# [Location of SourceID SSO 1.0b7/1.0 (optional)] +# sourceid.base=${user.home}/sso diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..e4196d4 --- /dev/null +++ b/build.xml @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf-sso/extra-db-mysql.sql b/conf-sso/extra-db-mysql.sql new file mode 100644 index 0000000..831f84f --- /dev/null +++ b/conf-sso/extra-db-mysql.sql @@ -0,0 +1,33 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# + +USE venice; + +############################################################################## +# Table Creation +############################################################################## + +# The table which stores federations for a user ID. Each user ID may federate to one or more providers. +CREATE TABLE sso_federate ( + uid INT NOT NULL, + provider VARCHAR(249) NOT NULL, + local_name VARCHAR(249) NOT NULL, + remote_name VARCHAR(249) NOT NULL, + PRIMARY KEY (uid, provider), + UNIQUE INDEX by_local (provider, local_name), + UNIQUE INDEX by_remote (provider, remote_name) +); diff --git a/conf-sso/sp/dynamo.xml b/conf-sso/sp/dynamo.xml new file mode 100644 index 0000000..ea723bb --- /dev/null +++ b/conf-sso/sp/dynamo.xml @@ -0,0 +1,182 @@ + + + + + + + + ${code.path} + + ${url} + ${context.path}/${url} + ${context.path}/images/${url} + ${context.path}/imagedata/${url} + ${context.path}/frame/${url} + + + + + + mysql + + com.mysql.jdbc.Driver + jdbc:mysql://localhost/venice + veniceuser + XYZZY0099 + + + + + + + + + + + ${code.path}/modules + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + top.js.vs + verify_email.js.vs?tgt=${tgt} + + + + + /velocity + + + + + + + + /xmlrpc/siteinfo-metadata.xml + + + + + + /xmlrpc/session-metadata.xml + + + + + /dialogs + + + + + + + + + + /mailmessages + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf-sso/sp/logging.xml b/conf-sso/sp/logging.xml new file mode 100644 index 0000000..df3b1bb --- /dev/null +++ b/conf-sso/sp/logging.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf-sso/sp/sourceid-sso-providers.xml b/conf-sso/sp/sourceid-sso-providers.xml new file mode 100644 index 0000000..fe4f8fa --- /dev/null +++ b/conf-sso/sp/sourceid-sso-providers.xml @@ -0,0 +1,59 @@ + + + + + + SourceID-Sample-IDP + + + + + MIICSjCCAbMCBD4coSAwDQYJKoZIhvcNAQEEBQAwbDEQMA4GA1UEBhMHVW5rbm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UEChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjAeFw0wMzAxMDgyMjA3MjhaFw0wMzA0MDgyMjA3MjhaMGwxEDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEDAOBgNVBAoTB1Vua25vd24xEDAOBgNVBAsTB1Vua25vd24xEDAOBgNVBAMTB1Vua25vd24wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMJhokczPBJlZe48d5oKZiX6vo7DBU5b54t9JjSHLOEZd0XK5w81BY4iX8QADMc7GyTrqDDrehfh4S5eQO89Fll50D4f6HpSI2QGtionDrj3kuET9nW9n98IzWc3eiLLH+5q3VGm04rylo4PTnJCeMYmDRqYJkWR1xQbNsrv9HHJAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAI16O969XJkYRJaTiPXMcJg8XRM9oHKqc4L6YEDXGvnQ8NfTPDuJEzKIcU8QWNnprcY+MOue+O2YvP7u9NQuKK4zDA14CcIRb8G+VMLFa2A+BYiD66yIBWsb89YNFYnvH379wGp+ankQBTdljpgFo6Bt+fXmZxB6mToBdXy0h5b8= + + + + + + http://localhost:8080/sso-sample-idp/sso/soap/endpoint + http://localhost:8080/sso-sample-idp/sso/logout + http://localhost:8080/sso-sample-idp/sso/logout + http://localhost:8080/sso-sample-idp/sso/fedterm + http://localhost:8080/sso-sample-idp/sso/fedterm + http://localhost:8080/sso-sample-idp/sso/authn + + + http://projectliberty.org/profiles/rni-sp-soap + http://projectliberty.org/profiles/fedterm-sp-soap + http://projectliberty.org/profiles/fedterm-sp-http + http://projectliberty.org/profiles/slo-sp-soap + http://projectliberty.org/profiles/slo-sp-http + http://projectliberty.org/profiles/brws-art + http://projectliberty.org/profiles/brws-post + http://projectliberty.org/profiles/wml-post + http://projectliberty.org/profiles/lecp + + + diff --git a/conf-sso/sp/sourceid-sso.xml b/conf-sso/sp/sourceid-sso.xml new file mode 100644 index 0000000..0937d86 --- /dev/null +++ b/conf-sso/sp/sourceid-sso.xml @@ -0,0 +1,68 @@ + + + + + + Venice-SSO-SP + + + sp + /WEB-INF/sourceid-sso-providers.xml + + + /sourceid/errorHandler.js.vs + + + + /WEB-INF/venice-sp.keystore + numenor + mykey + mithrandir + + + + /idp/logon.jsp + 1800 + /idp/idpLogoutRender.jsp + /idp/checkmark.png + /idp/idpPost.jsp + + + dynamo.session + + + 60 + 300 + + + com.silverwrist.venice.sourceid.VeniceAccountHandler + + org.sourceid.sso.handlers.ArtifactHandlerInMemoryImpl + + + diff --git a/conf-sso/sp/sp-descriptor.xml b/conf-sso/sp/sp-descriptor.xml new file mode 100644 index 0000000..a9bedcd --- /dev/null +++ b/conf-sso/sp/sp-descriptor.xml @@ -0,0 +1,37 @@ + + + + + + Venice-SSO-SP + + + + MIICbjCCAdcCBD7AlmwwDQYJKoZIhvcNAQEEBQAwfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNPMQ8wDQYDVQQHEwZEZW52ZXIxIzAhBgNVBAoTGlNpbHZlcndyaXN0IERlc2lnbiBTdHVkaW9zMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEWMBQGA1UEAxMNRXJpYyBCb3dlcnNveDAeFw0wMzA1MTMwNjUzMzJaFw0wMzA4MTEwNjUzMzJaMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMSMwIQYDVQQKExpTaWx2ZXJ3cmlzdCBEZXNpZ24gU3R1ZGlvczEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFjAUBgNVBAMTDUVyaWMgQm93ZXJzb3gwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvjYZPJwt16vTVIKleltTVDyvswVr2vCd9aHg7rKPhNKN+iVS2XY+Y5IopgcVtshQx/SbWnPNldtpGtFewaSQzCud/Lhja1xoGO/nTbjRr7MrPlR3yub8KO90tgslZ9yjEPZDWDEr3Y59ieDpMtAnYjS2GQ2LFRHq63kzd4AXg1AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAVhJqkLZd59BiTjvRF0ZtBKXe+kxnvyclc0MeIzkzGFmnpMuSpSyZ3LlYp0uvFn5OADM6KkXj7DgXIqb1bqIvXmlwDds+oO3KL+WdHBO9KHW0KjR2jpIujpmJ8Eaf/cefcOxxA00CMrwBeL8EXyAaynpcT78nrT5iN3FZwMkBi9o= + + + + http://localhost:8080/venice-sp/sso/authnRequest + http://localhost:8080/venice-sp/sso/soap/endpoint + http://localhost:8080/venice-sp/sso/logout + http://localhost:8080/venice-sp/sso/logout + http://localhost:8080/venice-sp/sso/fedterm + http://localhost:8080/venice-sp/sso/fedterm + + http://projectliberty.org/profiles/fedterm-idp-soap + http://projectliberty.org/profiles/fedterm-idp-http + http://projectliberty.org/profiles/slo-idp-soap + http://projectliberty.org/profiles/slo-idp-http + http://projectliberty.org/profiles/slo-idp-http-get + http://projectliberty.org/profiles/rni-idp-soap + http://localhost:9080/sourceid-sso/sso/rni + http://localhost:9080/sourceid-sso/sso/rni + http://projectliberty.org/profiles/rni-idp-http + false + + + + diff --git a/conf-sso/sp/venice-sp.keystore b/conf-sso/sp/venice-sp.keystore new file mode 100644 index 0000000000000000000000000000000000000000..929b6504e16f4e80febd2e0718483827927cdc6a GIT binary patch literal 1395 zcmezO_TO6u1_mY|W&~r_+{*0KN+9#Ag7>L@pv-QACZ_EMd~96WY>X_7T1q2~I6z~6bVd*8I0A9Of75-jBrj!DO)y^^x>wc(y>x$dhXSwqCu5iB#?9XS# z^V@`{xT<|_*#AT&ukN<=3E>q!%r$)$x;mS(mG@*@99hiw?V#zzU8P%ljH}rhY_t{^ zor_@fei;~TbdRa?zWxP=uiKNFZ`(cWY0h}3^xlX!s_#PW=a?#Cc7YsjmC^!>jSFA5 z@h2tk$cVYW>!NGofY3u)Y8x~^J&W6qe}!QFzlIpVUc`9->=-&fi~CPy3S>CSoc9k%TqC>cVA$t_a;`Tp*`&n^#DEI-L;&l(wR&v4Ir z<%egR!&ezTv$Bsge83A;nOf}GI((|eD-vGEZ2oB8J_t z_aE$i#Cd<^!G!@6%&jf#L;PE$`4i{O?{->!Zjx*Gq)#dnEg&g6LeJE|5}1;UfGIi8 zpo#H16N}w}X*mYGY@Awc9&O)w85vnv84T(SxeYkkm_u3EgqcEvVH^%&CTD*`exPEY z47)I!OKM(OYLTI`fg(tNOIRv6GY2S8UX)o}qTrHRoSB}d5L{B4l9^v@C}JQ4Qp7FH z?UGuSnv-9Uo0?Z*C}to65@iP}C7W~tPbP#B%l%2V&Tb-B&W*liQnioTKZTet;ZVs z{*~PBmHKV8`Kf!&y8J_Z-@Owyh1H%iw{H7n z^9sfaQzm9c21aD(0V9+d=&mrKtO?s< literal 0 HcmV?d00001 diff --git a/conf-sso/sp/web.xml b/conf-sso/sp/web.xml new file mode 100644 index 0000000..5483072 --- /dev/null +++ b/conf-sso/sp/web.xml @@ -0,0 +1,335 @@ + + + + + Venice Web Communities System + + Venice Web Communities System (TODO: fill out description) + Contains SourceID-SSO, configured as Service Provider + + + + + + logging.config + WEB-INF/logging.xml + + The path and file name of the Log4J logger configuration file, relative to the application root. + + + + + dynamo.config + WEB-INF/dynamo.xml + + The path and file name of the base Dynamo configuration file, relative to the application root. + The default, if not specified, is "WEB-INF/dynamo.xml". + + + + + SSO.config.attrs + object=sso + + + + + + ScriptExec + Executes a scripting file as a servlet. + com.silverwrist.dynamo.servlet.ScriptExecServlet + + remove.extension + vs + + The extension which is used in the servlet mapping to distinguish scripts to execute. This + extension is removed from the servlet path to create the script name. + + + + script.prefix + /scripts + + The resource prefix to use for scripts. This is prepended to the servlet path to create the + script name which is executed. + + + 1 + + + + XmlRpc + Executes XML-RPC requests. + com.silverwrist.dynamo.xmlrpc.XmlRpcServlet + + subsystem.object + xmlrpc + + The object name of the XML-RPC subsystem object. Must match the name configured for the + com.silverwrist.dynamo.xmlrpc.XmlRpcSubSystem object in dynamo.xml. + + + + + + Remapper + Remaps URLs to other URLs programmatically. + com.silverwrist.dynamo.servlet.RemapperServlet + + data.object + remapper + + The object name of the remapper data object. Must match the name configured for the + com.silverwrist.dynamo.servlet.RemapperData object in dynamo.xml. + + + + + + Image + Serves up images from the ImageStore. + com.silverwrist.dynamo.servlet.ImageServlet + + image.store + images + + The object name of the image store object. Must match the name configured for the + com.silverwrist.dynamo.db.ImageStoreObject object in dynamo.xml. + + + + + + StyleSheet + Serves up CSS stylesheets for use by the frame. + com.silverwrist.venice.frame.StyleSheetServlet + + + + Frame + Frames static pages within the outer Venice frame. + com.silverwrist.venice.servlet.FrameServlet + + content.prefix + static + + The prefix to apply to the static content path before retrieving it. Interpreted + relative to the Web application root (i.e. where Web content normally gets linked from). + + + + cache.hard.limit + 5 + + Maximum number of documents that will be hard-cached by this servlet. Must be at least 1. + + + + cache.soft.limit + 10 + + Maximum number of documents that will be soft-cached by this servlet. Will always be at least + twice the number of hard-cached documents. + + + + + + PasswordRecovery + Used to access the password recovery feature; changes user passwords. + com.silverwrist.venice.session.PasswordRecoveryServlet + + + + User + Displays user profiles. + com.silverwrist.venice.servlet.UserServlet + + + + + + + SourceID-SSO-Manager + Loads configuration at boot time, and provides instrumentation and admin control + org.sourceid.sso.servlets.Manager + 15 + + + + + SourceID-SSO-Authenticator + Provides Identity Provider (IDP) Authentication Services + org.sourceid.sso.servlets.Authenticator + + + + + SourceID-SSO-AuthnRequestor + Provides Service Provider (SP) Authentication Request Services + org.sourceid.sso.servlets.AuthnRequestor + + + + + SourceID-SSO-FederationTerminator + Provides Federation Termination Services + org.sourceid.sso.servlets.FederationTerminator + + + + + SourceID-SSO-Logout + Provides Single Logout Services + org.sourceid.sso.servlets.Logout + + + + + SourceID-SSO-NameRegistrar + Provides Single Logout Services + org.sourceid.sso.servlets.NameRegistrar + + + + + AxisServlet + Apache-Axis Servlet + org.apache.axis.transport.http.AxisServlet + + + AdminServlet + Axis Admin Servlet + org.apache.axis.transport.http.AdminServlet + 100 + + + SOAPMonitorService + SOAPMonitorService + org.apache.axis.monitor.SOAPMonitorService + + SOAPMonitorPort + 5001 + + 100 + + + + + + + + ScriptExec + *.vs + + + + XmlRpc + /RPC2 + + + + Remapper + /verifyemail + + + + Image + /imagedata/* + + + + StyleSheet + /stylesheet-base.css + + + + StyleSheet + /stylesheet-advanced.css + + + + Frame + /frame/* + + + + PasswordRecovery + /passrecovery/* + + + + User + /user/* + + + + + + + SourceID-SSO-Authenticator + /sso/authn + + + + + SourceID-SSO-AuthnRequestor + /sso/authnRequest + + + + + SourceID-SSO-FederationTerminator + /sso/fedterm + + + + + SourceID-SSO-Logout + /sso/logout + + + + + SourceID-SSO-NameRegistrar + /sso/rni + + + + + AxisServlet + /sso/soap/* + + + + + + + 60 + + + + + default.jsp + index.html + + + diff --git a/conf/db-init-mysql.sql b/conf/db-init-mysql.sql new file mode 100644 index 0000000..2181ba1 --- /dev/null +++ b/conf/db-init-mysql.sql @@ -0,0 +1,236 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# + +############################################################################## +# Database Creation +############################################################################## + +DROP DATABASE IF EXISTS dbname; +CREATE DATABASE dbname; +USE dbname; + +############################################################################## +# Table Creation +############################################################################## + +# The "namespace cache" table, used to map string namespaces (used in the code) to integer IDs +# (used in the database). +CREATE TABLE namespaces ( + nsid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + namespace VARCHAR(255) BINARY NOT NULL, + UNIQUE INDEX on_namespace (namespace) +); + +# The global properties table. +CREATE TABLE globalprop ( + nsid INT NOT NULL, + prop_name VARCHAR(255) BINARY NOT NULL, + prop_value VARCHAR(255), + PRIMARY KEY (nsid, prop_name) +); + +# The global "blocks" table, used to store fragments of text/HTML for later use. +CREATE TABLE globalblock ( + nsid INT NOT NULL, + block_name VARCHAR(255) BINARY NOT NULL, + block TEXT, + PRIMARY KEY (nsid, block_name) +); + +# The main user information table. +CREATE TABLE users ( + uid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(64) NOT NULL, + email VARCHAR(255) NOT NULL, + is_anon TINYINT DEFAULT 0, + locked TINYINT DEFAULT 0, + nospam TINYINT DEFAULT 0, + created DATETIME NOT NULL, + last_accessed DATETIME, + UNIQUE INDEX on_username (username) +); + +# The user authentication data table. We identify authentication methods by namespace ID +# and name, and provide "source data" to allow multiple sources for the same type of +# authentication (such as browser cookies for multiple browsers). +CREATE TABLE userauth ( + uid INT NOT NULL, + nsid INT NOT NULL, + method VARCHAR(255) BINARY NOT NULL, + source_data VARCHAR(255), + auth_data VARCHAR(255), + PRIMARY KEY (uid, nsid, method) +); + +# The user properties table. +CREATE TABLE userprop ( + uid INT NOT NULL, + nsid INT NOT NULL, + prop_name VARCHAR(255) BINARY NOT NULL, + prop_value VARCHAR(255), + PRIMARY KEY (uid, nsid, prop_name) +); + +# The groups table. +CREATE TABLE groups ( + gid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + groupname VARCHAR(64) NOT NULL, + gaclid INT NOT NULL DEFAULT -1, + UNIQUE INDEX on_groupname (groupname) +); + +# The group membership table. +CREATE TABLE groupmembers ( + gid INT NOT NULL, + uid INT NOT NULL, + PRIMARY KEY (gid, uid), + UNIQUE INDEX reverse_index (uid, gid) +); + +# The group properties table. +CREATE TABLE groupprop ( + gid INT NOT NULL, + nsid INT NOT NULL, + prop_name VARCHAR(255) BINARY NOT NULL, + prop_value VARCHAR(255), + PRIMARY KEY (gid, nsid, prop_name) +); + +# The main ACL table. Each ACL has a numeric ID, a name, an unordered collection of owners (which may +# be groups or users), and an ordered collection of entries (ACEs). +CREATE TABLE acl ( + aclid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + aclname VARCHAR(255) NOT NULL, + INDEX on_name (aclname) +); + +# The table of owners for ACLs. Each ACL has one or more owners. +# Flags Bit 0: 0=user, 1=group +CREATE TABLE aclowner ( + aclid INT NOT NULL, + ownerid INT NOT NULL, + flags TINYINT NOT NULL, + INDEX on_acl (aclid) +); + +# The table mapping ACLs to ACEs. Each ACL has zero or more ACEs. +CREATE TABLE acldata ( + aclid INT NOT NULL, + seq INT NOT NULL, + aceid INT NOT NULL, + PRIMARY KEY (aclid, seq) +); + +# The main ACE table. Each ACE has a numeric ID, a principal reference (which may be a user or +# group ID), a "negative" flag, and an unordered collection of permissions. +# Flags Bit 0: 0=user, 1=group +# Flags Bit 4: 0=positive ACE, 1=negative ACE +CREATE TABLE ace ( + aceid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + pri INT, + flags TINYINT NOT NULL DEFAULT 0 +); + +# The table mapping permissions into ACEs. Permissions are identified by namespace and name. +CREATE TABLE acedata ( + aceid INT NOT NULL, + perm_nsid INT NOT NULL, + perm_name VARCHAR(255) BINARY NOT NULL, + INDEX on_ace (aceid) +); + +# Global security data table. +CREATE TABLE globalsec ( + admin_uid INT NOT NULL, + admin_gid INT NOT NULL, + global_aclid INT NOT NULL, + alluser_gid INT NOT NULL, + verified_gid INT NOT NULL +); + +# The audit information table. Each audit "event" can have up to 8 properties defined with it, +# which are serialized as other "properties." +CREATE TABLE audit ( + record BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, + on_date DATETIME NOT NULL, + event INT NOT NULL, + uid INT NOT NULL, + subid INT NOT NULL DEFAULT 0, + ip VARCHAR(48), + prop0 VARCHAR(255), + prop1 VARCHAR(255), + prop2 VARCHAR(255), + prop3 VARCHAR(255), + prop4 VARCHAR(255), + prop5 VARCHAR(255), + prop6 VARCHAR(255), + prop7 VARCHAR(255), + INDEX by_date (on_date), + INDEX sub_view (subid, on_date) +); + +# The table where events are assigned "event IDs" in the master audit record, +# to cut down on space usage in the audit table. Event IDs can be predefined +# at database create time, or defined dynamically, or both. +CREATE TABLE auditevent ( + eventid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + event_nsid INT NOT NULL, + event_name VARCHAR(255) BINARY NOT NULL, + descr TINYTEXT, + UNIQUE INDEX by_event (event_nsid, event_name) +); + +# The image store table. This is used to store relatively small images like +# user photos and logos. +CREATE TABLE imagestore ( + imageid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + typecode INT NOT NULL, + ownerid INT NOT NULL, + ownerflag TINYINT NOT NULL DEFAULT 0, + mimetype VARCHAR(128), + length INT, + data MEDIUMBLOB +); + +# The image type table, used to differentiate between images stored in the table. +CREATE TABLE imagetype ( + typecode INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + nsid INT NOT NULL, + name VARCHAR(255) BINARY NOT NULL +); + +############################################################################## +# Set table access rights +############################################################################## + +# this is a test only - remove when we go to production +GRANT ALL PRIVILEGES ON dbname.* + TO erbo@localhost IDENTIFIED BY 'meesatest' + WITH GRANT OPTION; +GRANT ALL PRIVILEGES ON dbname.* + TO erbo@'10.29.99.%' IDENTIFIED BY 'meesatest' + WITH GRANT OPTION; + +GRANT INSERT, DELETE, UPDATE, SELECT ON dbname.* + TO testuser@localhost IDENTIFIED BY 'TestPassword'; + +############################################################################## +# Initialization data +############################################################################## + +INSERT INTO users (uid, username, email, is_anon, nospam, created) + VALUES (1, 'Anonymous_Honyak', 'nobody@localhost', 1, 1, '2002-12-15 12:00:00'); diff --git a/conf/dynamo-test.xml b/conf/dynamo-test.xml new file mode 100644 index 0000000..850eae0 --- /dev/null +++ b/conf/dynamo-test.xml @@ -0,0 +1,70 @@ + + + + + + + ${code.path} + + ${url} + ${context.path}/${url} + + + + + mysql + + com.mysql.jdbc.Driver + jdbc:mysql://localhost/dbname + testuser + TestPassword + + + + + ${code.path}/modules + + + + /velocity + + + + + + + + janelane + Venice Mail System + nobody@delenn.silverwrist.internal + Venice AutoMail System + /mailmessages + +The Venice Project is not responsible for the contents of this message +Report abuses to: + ]]> + X-Venice-User-Info + + + + + + diff --git a/conf/dynamo-venice.xml b/conf/dynamo-venice.xml new file mode 100644 index 0000000..3be3c0f --- /dev/null +++ b/conf/dynamo-venice.xml @@ -0,0 +1,175 @@ + + + + + + + + ${code.path} + + ${url} + ${context.path}/${url} + ${context.path}/images/${url} + ${context.path}/imagedata/${url} + ${context.path}/frame/${url} + + + + + + mysql + + com.mysql.jdbc.Driver + jdbc:mysql://localhost/venice + veniceuser + XYZZY0099 + + + + + + + + + + ${code.path}/modules + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + top.js.vs + verify_email.js.vs?tgt=${tgt} + + + + + /velocity + + + + + + + + /xmlrpc/siteinfo-metadata.xml + + + + + + /xmlrpc/session-metadata.xml + + + + + /dialogs + + + + + + + + + + /mailmessages + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/logging-test.xml b/conf/logging-test.xml new file mode 100644 index 0000000..525cb17 --- /dev/null +++ b/conf/logging-test.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/logging-venice.xml b/conf/logging-venice.xml new file mode 100644 index 0000000..e5f935b --- /dev/null +++ b/conf/logging-venice.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/std_render_macro_library.vm b/conf/std_render_macro_library.vm new file mode 100644 index 0000000..f84e493 --- /dev/null +++ b/conf/std_render_macro_library.vm @@ -0,0 +1,31 @@ +#* + The contents of this file are subject to the Mozilla Public License Version 1.1 + (the "License"); you may not use this file except in compliance with the License. + You may obtain a copy of the License at . + + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + WARRANTY OF ANY KIND, either express or implied. See the License for the specific + language governing rights and limitations under the License. + + The Original Code is the Venice Web Communities System. + + The Initial Developer of the Original Code is Eric J. Bowersox , + for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + + Contributor(s): +*# + +## Define macros around the "std" object. +#macro( formatURL $type $url )$std.formatURL($type,$url)#end + +#macro( encodeHTML $data )$std.encodeHTML($data)#end + +#macro( encodeURL $data )$std.encodeURL($data)#end + +#macro( render $obj )$std.renderObject($obj)#end + +#macro( renderDialog $dlg )$std.renderDialog($dlg)#end + +#macro( stacktrace $thr )$std.getStackTrace($thr)#end + diff --git a/conf/venice-db-init-mysql.sql b/conf/venice-db-init-mysql.sql new file mode 100644 index 0000000..6b2668d --- /dev/null +++ b/conf/venice-db-init-mysql.sql @@ -0,0 +1,573 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# + +############################################################################## +# Database Creation +############################################################################## + +DROP DATABASE IF EXISTS venice; +CREATE DATABASE venice; +USE venice; + +############################################################################## +# Table Creation +############################################################################## + +# The "namespace cache" table, used to map string namespaces (used in the code) to integer IDs +# (used in the database). +CREATE TABLE namespaces ( + nsid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + namespace VARCHAR(255) BINARY NOT NULL, + UNIQUE INDEX on_namespace (namespace) +); + +# The global properties table. +CREATE TABLE globalprop ( + nsid INT NOT NULL, + prop_name VARCHAR(255) BINARY NOT NULL, + prop_value VARCHAR(255), + PRIMARY KEY (nsid, prop_name) +); + +# The global "blocks" table, used to store fragments of text/HTML for later use. +CREATE TABLE globalblock ( + nsid INT NOT NULL, + block_name VARCHAR(255) BINARY NOT NULL, + block TEXT, + PRIMARY KEY (nsid, block_name) +); + +# The main user information table. +CREATE TABLE users ( + uid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(64) NOT NULL, + email VARCHAR(255) NOT NULL, + is_anon TINYINT DEFAULT 0, + locked TINYINT DEFAULT 0, + nospam TINYINT DEFAULT 0, + created DATETIME NOT NULL, + last_accessed DATETIME, + UNIQUE INDEX on_username (username) +); + +# The user authentication data table. We identify authentication methods by namespace ID +# and name, and provide "source data" to allow multiple sources for the same type of +# authentication (such as browser cookies for multiple browsers). +CREATE TABLE userauth ( + uid INT NOT NULL, + nsid INT NOT NULL, + method VARCHAR(255) BINARY NOT NULL, + source_data VARCHAR(255), + auth_data VARCHAR(255), + PRIMARY KEY (uid, nsid, method) +); + +# The user properties table. +CREATE TABLE userprop ( + uid INT NOT NULL, + nsid INT NOT NULL, + prop_name VARCHAR(255) BINARY NOT NULL, + prop_value VARCHAR(255), + PRIMARY KEY (uid, nsid, prop_name) +); + +# The groups table. +CREATE TABLE groups ( + gid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + groupname VARCHAR(64) NOT NULL, + gaclid INT NOT NULL DEFAULT -1, + UNIQUE INDEX on_groupname (groupname) +); + +# The group membership table. +CREATE TABLE groupmembers ( + gid INT NOT NULL, + uid INT NOT NULL, + PRIMARY KEY (gid, uid), + UNIQUE INDEX reverse_index (uid, gid) +); + +# The group properties table. +CREATE TABLE groupprop ( + gid INT NOT NULL, + nsid INT NOT NULL, + prop_name VARCHAR(255) BINARY NOT NULL, + prop_value VARCHAR(255), + PRIMARY KEY (gid, nsid, prop_name) +); + +# The main ACL table. Each ACL has a numeric ID, a name, an unordered collection of owners (which may +# be groups or users), and an ordered collection of entries (ACEs). +CREATE TABLE acl ( + aclid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + aclname VARCHAR(255) NOT NULL, + INDEX on_name (aclname) +); + +# The table of owners for ACLs. Each ACL has one or more owners. +# Flags Bit 0: 0=user, 1=group +CREATE TABLE aclowner ( + aclid INT NOT NULL, + ownerid INT NOT NULL, + flags TINYINT NOT NULL, + INDEX on_acl (aclid) +); + +# The table mapping ACLs to ACEs. Each ACL has zero or more ACEs. +CREATE TABLE acldata ( + aclid INT NOT NULL, + seq INT NOT NULL, + aceid INT NOT NULL, + PRIMARY KEY (aclid, seq) +); + +# The main ACE table. Each ACE has a numeric ID, a principal reference (which may be a user or +# group ID), a "negative" flag, and an unordered collection of permissions. +# Flags Bit 0: 0=user, 1=group +# Flags Bit 4: 0=positive ACE, 1=negative ACE +CREATE TABLE ace ( + aceid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + pri INT, + flags TINYINT NOT NULL DEFAULT 0 +); + +# The table mapping permissions into ACEs. Permissions are identified by namespace and name. +CREATE TABLE acedata ( + aceid INT NOT NULL, + perm_nsid INT NOT NULL, + perm_name VARCHAR(255) BINARY NOT NULL, + INDEX on_ace (aceid) +); + +# Global security data table. +CREATE TABLE globalsec ( + admin_uid INT NOT NULL, + admin_gid INT NOT NULL, + global_aclid INT NOT NULL, + alluser_gid INT NOT NULL, + verified_gid INT NOT NULL +); + +# The audit information table. Each audit "event" can have up to 8 properties defined with it, +# which are serialized as other "properties." +CREATE TABLE audit ( + record BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, + on_date DATETIME NOT NULL, + event INT NOT NULL, + uid INT NOT NULL, + subid INT NOT NULL DEFAULT 0, + ip VARCHAR(48), + prop0 VARCHAR(255), + prop1 VARCHAR(255), + prop2 VARCHAR(255), + prop3 VARCHAR(255), + prop4 VARCHAR(255), + prop5 VARCHAR(255), + prop6 VARCHAR(255), + prop7 VARCHAR(255), + INDEX by_date (on_date), + INDEX sub_view (subid, on_date) +); + +# The table where events are assigned "event IDs" in the master audit record, +# to cut down on space usage in the audit table. Event IDs can be predefined +# at database create time, or defined dynamically, or both. +CREATE TABLE auditevent ( + eventid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + event_nsid INT NOT NULL, + event_name VARCHAR(255) BINARY NOT NULL, + descr TINYTEXT, + UNIQUE INDEX by_event (event_nsid, event_name) +); + +# The image store table. This is used to store relatively small images like +# user photos and logos. +CREATE TABLE imagestore ( + imageid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + typecode INT NOT NULL, + ownerid INT NOT NULL, + ownerflag TINYINT NOT NULL DEFAULT 0, + mimetype VARCHAR(128), + length INT, + data MEDIUMBLOB +); + +# The image type table, used to differentiate between images stored in the table. +CREATE TABLE imagetype ( + typecode INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + nsid INT NOT NULL, + name VARCHAR(255) BINARY NOT NULL +); + +#### following this line are Venice-specific tables #### + +# The table which defines menus. +CREATE TABLE menus ( + menuid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + menu_nsid INT NOT NULL, + menu_name VARCHAR(255) BINARY NOT NULL, + title VARCHAR(255) NOT NULL, + subtitle VARCHAR(255) NULL, + UNIQUE INDEX by_name (menu_nsid, menu_name) +); + +# Definitions of variables for menus. +CREATE TABLE menuvars ( + menuid INT NOT NULL, + var_name VARCHAR(255) NOT NULL, + default_val VARCHAR(255) NULL, + PRIMARY KEY (menuid, var_name) +); + +# Definitions of menu items. +CREATE TABLE menuitems ( + menuid INT NOT NULL, + sequence INT NOT NULL, + itemtype VARCHAR(32) NOT NULL, + enable TINYINT NOT NULL DEFAULT 1, + indent INT NOT NULL DEFAULT 0, + text VARCHAR(255) NULL, + linktype VARCHAR(32) NULL, + link VARCHAR(255) NULL, + target VARCHAR(255) NULL, + title VARCHAR(255) NULL, + on_click VARCHAR(255) NULL, + perm_nsid INT NULL, + perm_name VARCHAR(255) BINARY NULL, + ifdef_var VARCHAR(255) NULL, + ifndef_var VARCHAR(255) NULL, + PRIMARY KEY (menuid, sequence) +); + +############################################################################## +# Set table access rights +############################################################################## + +# this is a test only - remove when we go to production +GRANT ALL PRIVILEGES ON venice.* + TO erbo@localhost IDENTIFIED BY 'meesatest' + WITH GRANT OPTION; + +GRANT INSERT, DELETE, UPDATE, SELECT, LOCK TABLES ON venice.* + TO veniceuser@localhost IDENTIFIED BY 'XYZZY0099'; + +############################################################################## +# Initialization data +############################################################################## + +# Initial namespaces setup +INSERT INTO namespaces (nsid, namespace) VALUES + (1, 'http://www.silverwrist.com/NS/venice/2002/12/21/frame.look.and.feel' ), + (2, 'http://www.silverwrist.com/NS/venice/2002/12/22/stylesheets' ), + (3, 'http://www.silverwrist.com/NS/dynamo/2002/12/13/user.information' ), + (4, 'http://www.silverwrist.com/NS/dynamo/2002/12/27/group.permissions' ), + (5, 'http://www.silverwrist.com/NS/venice/2002/12/28/mail.properties' ), + (6, 'http://www.silverwrist.com/NS/venice/2002/12/28/content.look.and.feel'), + (7, 'http://www.silverwrist.com/NS/venice/2002/12/30/session.control' ), + (8, 'http://www.silverwrist.com/NS/venice/2002/12/31/system.events' ), + (9, 'http://www.silverwrist.com/NS/venice/2002/12/31/user.events' ), + (10, 'http://www.silverwrist.com/NS/venice/2002/12/31/user.settings' ), + (11, 'http://www.silverwrist.com/NS/venice/2002/12/31/user.profile' ), + (12, 'http://www.silverwrist.com/NS/venice/2003/01/03/system.mail.messages' ); + +# Initial global properties setup +INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES + (1, 'site.title', '!Venice Test' ), + (1, 'optionset', '_OS:AC' ), + (1, 'site.url', '!http://localhost:8080/venice/' ), + (1, 'site.logo.url', '!temp/site-logo.jpg' ), + (1, 'site.logo.url.type', '!IMAGE' ), + (1, 'site.logo.width', 'I140' ), + (1, 'site.logo.height', 'I80' ), + (1, 'frame.template', '!frame.vm' ), + (1, 'footer.logo.scale', 'I100' ), + (1, 'page.icon.url', '!venice-icon.png' ), + (1, 'page.icon.url.type', '!IMAGE' ), + (1, 'page.icon.type', '!image/png' ), + (1, 'page.favicon.url', '!venice-favicon.ico' ), + (1, 'page.favicon.url.type', '!IMAGE' ), + (2, 'sheet.base.normal', '!stylesheets/normal_base.vm' ), + (2, 'sheet.adv.normal', '!stylesheets/adv_base.vm' ), + (5, 'smtp.host', '!localhost' ), + (5, 'system.mail.from.addr', '!nobody@delenn.silverwrist.internal'), + (5, 'system.mail.from.name', '!Venice Mail System' ), + (5, 'mailer.name', '!Venice AutoMail System' ), + (5, 'user.info.header', '!X-Venice-User-Info' ), + (6, 'subdir.buttons', '!buttons/classic' ), + (6, 'std.button.width', 'I80' ), + (6, 'std.button.height', 'I24' ), + (6, 'bn.cancel', '!cancel.jpg' ), + (6, 'bnc.cancel', '!Cancel' ), + (6, 'bn.create', '!create.jpg' ), + (6, 'bnc.create', '!Create' ), + (6, 'bn.i.accept', '!user_accept.jpg' ), + (6, 'bnc.i.accept', '!I Accept' ), + (6, 'bn.i.decline', '!user_decline.jpg' ), + (6, 'bnc.i.decline', '!I Decline' ), + (6, 'bn.login', '!login.jpg' ), + (6, 'bnc.login', '!Log In' ), + (6, 'bn.ok', '!ok.jpg' ), + (6, 'bnc.ok', '!OK' ), + (6, 'bn.reminder', '!reminder.jpg' ), + (6, 'bnc.reminder', '!Reminder' ), + (6, 'bn.send.again', '!send_again.jpg' ), + (6, 'bnc.send.again', '!Send Again' ), + (6, 'bn.send.email', '!send_email.jpg' ), + (6, 'bnc.send.email', '!Send E-Mail' ), + (6, 'bn.set', '!set.jpg' ), + (6, 'bnc.set', '!Set' ), + (6, 'bn.update', '!update.jpg' ), + (6, 'bnc.update', '!Update' ), + (6, 'user.agreement.title', '!Venice User Agreement' ), + (6, 'user.photo.width', 'I100' ), + (6, 'user.photo.height', 'I100' ), + (6, 'user.nophoto.url', '!photo_not_avail.gif' ), + (6, 'user.nophoto.url.type', '!IMAGE' ), + (7, 'session.init.script', '!/util/session_init.js' ), + (7, 'login.cookie', '!VeniceAuth' ), + (7, 'login.cookie.maxage', 'I365' ), + (7, 'password.recovery.time', 'I60' ), + (10, 'timezone', '_TZ:UTC' ), + (10, 'locale', '_LOC:en_US' ), + (10, 'admin.flags', '_OS:' ), + (11, 'privacy', '_OS:' ), + (12, 'confirm.message.title', '!Venice E-Mail Confirmation' ), + (12, 'password.change.message.title', '!Venice Password Changed' ), + (12, 'reminder.message.title', '!Venice Password Reminder Message' ); + +# Initial global blocks setup +INSERT INTO globalblock (nsid, block_name, block) VALUES + (1, 'footer', +'All trademarks and copyrights on this page are owned by their respective companies. +All messages posted by users on this page are owned by those users. +The rest: Copyright © 2002-2003 Silverwrist Design Studios, All Rights Reserved. +See our Policy Page for our copyright and privacy policies.'), + (5, 'user.disclaimer', +'Message sent via Venice Web Communities System - +The Venice Project is not responsible for the contents of this message +Report abuses to: '), + (5, 'signature', +'Venice - community services, conferencing and more. '), + (6, 'content.header', +'$title +#if( $subtitle ) +   $subtitle +#end +
'), + (6, 'std.bullet', +'*'), + (6, 'error.box', +'

+ + +
+ #encodeHTML( $title ) +
+

#encodeHTML( $message )

+

+ #if( $back ) + Go back. + #else + Use your browser''s Back button to go back. + #end +

+

+#if( $except ) + +#end'), + (6, 'user.agreement', +'Text of this agreement is to be determined.'), + (12, 'confirm.message', +'Welcome to the Venice Web Communities System! In order to fully activate your +account after you register or change your E-mail address, you must provide a +confirmation number to the system. Please enter this number into the "Confirm +E-mail Address" dialog on the system when indicated. + +Your confirmation number for your account "$username" is $confnum. + +Access the E-mail verification dialog at . + +Thank you, and enjoy the Venice Web Communities System! + +-- The Management'), + (12, 'password.change.message', +'The password for your account "$username" has been changed. The new +password is "$password". + +You should log into Venice immediately and change the password to something +else. You can change the password for your account, once you are logged in, +by clicking on the "Profile" link in the top bar. + +If you did NOT request a password change on your account, please notify the +system administrator IMMEDIATELY. + +-- The Management'), + (12, 'reminder.message', +'Here is the password reminder for your account "$username" as you requested: + +$reminder + +If this reminder is not sufficient for you to remember what your password is, +then the system can change your password for you. To do so, please visit +the following URL: + +http://localhost/venice/passrecovery/$uid/$auth + +Your password will be changed and a new password will be E-mailed to you +at this address. + +If you did NOT request a password reminder, then this message was sent +by someone attempting to access your account without your knowledge. Do +not panic! Nothing has happened to your account or password yet, but +please do notify the system administrator. + +-- The Management'); + +# Initial users setup +# (UID 1 and 2) +INSERT INTO users (uid, username, email, is_anon, nospam, created) VALUES + (1, 'Anonymous_Honyak', 'nobody@localhost', 1, 1, '2002-12-15 12:00:00'), + (2, 'Administrator', 'root@localhost', 0, 0, '2002-12-26 18:00:00'); + +# Set up properties for Anonymous_Honyak. +INSERT INTO userprop (uid, nsid, prop_name, prop_value) VALUES + (1, 10, 'timezone', '_TZ:UTC' ), + (1, 10, 'locale', '_LOC:en_US'), + (1, 10, 'admin.flags', '_OS:A' ), + (1, 11, 'privacy', '_OS:' ), + (1, 11, 'name.given', '!Anonymous'), + (1, 11, 'name.family', '!Honyak' ), + (1, 11, 'locality', '!Nowhere' ), + (1, 11, 'region', '!XX' ), + (1, 11, 'postal.code', '!00000' ), + (1, 11, 'country', '_CTRY:US' ); + +# Add authentication for Administrator (no password by default) +INSERT INTO userauth (uid, nsid, method, source_data, auth_data) VALUES + (2, 3, 'default.hash.password', '', ''); + +# Set up properties for Administrator. +INSERT INTO userprop (uid, nsid, prop_name, prop_value) VALUES + (2, 10, 'timezone', '_TZ:UTC' ), + (2, 10, 'locale', '_LOC:en_US' ), + (2, 10, 'admin.flags', '_OS:' ), + (2, 11, 'privacy', '_OS:' ), + (2, 11, 'name.given', '!System' ), + (2, 11, 'name.family', '!Administrator'), + (2, 11, 'locality', '!Nowhere' ), + (2, 11, 'region', '!XX' ), + (2, 11, 'postal.code', '!00000' ), + (2, 11, 'country', '_CTRY:US' ); + +# Create a group for site administrators. +# (GID 1) +INSERT INTO groups (gid, groupname) VALUES (1, 'Site_Administration'); +INSERT INTO groupmembers (gid, uid) VALUES (1, 2); + +# Create an ACL for the site administrator group. The ACL is owned by Administrator +# and grants "add" and "remove" permissions to Administrator only. +# (ACL 1, ACE 1) +INSERT INTO acl (aclid, aclname) VALUES (1, 'Site_Administration'); +INSERT INTO aclowner (aclid, ownerid, flags) VALUES (1, 2, 0); +INSERT INTO ace (aceid, pri, flags) VALUES (1, 2, 0); +INSERT INTO acldata (aclid, seq, aceid) VALUES (1, 0, 1); +INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES + (1, 4, 'add.member' ), + (1, 4, 'remove.member'); +UPDATE groups SET gaclid = 1 WHERE gid = 1; + +# Create the "all users" group. +# (GID 2) +INSERT INTO groups (gid, groupname) VALUES (2, 'All_Users'); +INSERT INTO groupmembers (gid, uid) VALUES (2, 2); + +# Create the "all verified users" group. +# (GID 3) +INSERT INTO groups (gid, groupname) VALUES (3, 'Verified_Users'); +INSERT INTO groupmembers (gid, uid) VALUES (3, 2); + +# Create the global ACL. This ACL is owned by the Administrator and grants +# permissions to the site administration group and to the Administrator specifically. +# (ACL 2, ACEs 2 and 3) +INSERT INTO acl (aclid, aclname) VALUES (2, 'Global_Permissions'); +INSERT INTO aclowner (aclid, ownerid, flags) VALUES (2, 2, 0); +INSERT INTO ace (aceid, pri, flags) VALUES (2, 1, 1); +INSERT INTO acldata (aclid, seq, aceid) VALUES (2, 0, 2); +INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES + (2, 1, 'set.property' ), + (2, 1, 'set.block' ), + (2, 2, 'set.property' ), + (2, 3, 'edit.all' ), + (2, 3, 'bypass.email.verify'), + (2, 3, 'view.all' ), + (2, 5, 'set.property' ), + (2, 5, 'set.block' ), + (2, 6, 'set.property' ), + (2, 6, 'set.block' ), + (2, 7, 'set.property' ), + (2, 10, 'set.property' ), + (2, 10, 'remove.property' ), + (2, 11, 'set.property' ), + (2, 11, 'remove.property' ), + (2, 12, 'set.property' ), + (2, 12, 'set.block' ); +INSERT INTO ace (aceid, pri, flags) VALUES (3, 2, 0); +INSERT INTO acldata (aclid, seq, aceid) VALUES (2, 1, 3); +INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES + (3, 1, 'remove.property'), + (3, 1, 'remove.block' ), + (3, 2, 'remove.property'), + (3, 5, 'remove.property'), + (3, 5, 'remove.block' ), + (3, 6, 'remove.property'), + (3, 6, 'remove.block' ), + (3, 7, 'remove.property'), + (3, 12, 'remove.property'), + (3, 12, 'remove.block' ); + +# Create the entries in the global security table. +INSERT INTO globalsec (admin_uid, admin_gid, global_aclid, alluser_gid, verified_gid) + VALUES (2, 1, 2, 2, 3); + +# Insert some audit event type records. +INSERT INTO auditevent (eventid, event_nsid, event_name, descr) VALUES + (1, 8, 'system.startup', 'Venice Server Startup' ), + (2, 8, 'system.shutdown', 'Venice Server Shutdown' ), + (3, 9, 'login.ok', 'Successful User Login' ), + (4, 9, 'login.fail', 'Failed User Login' ), + (5, 9, 'verify.ok', 'Successful E-Mail Address Verification'), + (6, 9, 'verify.fail', 'Failed E-Mail Address Verification' ), + (7, 9, 'resend.confirm.email', 'Re-Sent E-Mail Confirmation Message' ), + (8, 9, 'send.confirm.email', 'Sent E-Mail Confirmation Message' ), + (9, 9, 'user.created', 'New User Created' ); + +# Insert some image types. +INSERT INTO imagetype (typecode, nsid, name) VALUES + (1, 11, 'user.photo'); + +#### following this line is initialization of Venice-specific tables #### + +# Create the "global" menu. +INSERT INTO menus (menuid, menu_nsid, menu_name, title, subtitle) + VALUES (1, 1, 'fixed.menu', 'About This Site', NULL); +INSERT INTO menuitems (menuid, sequence, itemtype, text, linktype, link) VALUES + (1, 0, 'TEXT', 'Documentation', 'ABSOLUTE', 'TODO' ), + (1, 1, 'TEXT', 'About Venice', 'FRAME', 'about-venice.html'); +UPDATE menuitems SET enable = 0 WHERE menuid = 1 AND sequence = 0; + diff --git a/conf/web-test.xml b/conf/web-test.xml new file mode 100644 index 0000000..24e3bda --- /dev/null +++ b/conf/web-test.xml @@ -0,0 +1,117 @@ + + + + + Dynamo Test Application + This is an application used to test components of the Dynamo framework. + + + + + logging.config + WEB-INF/logging.xml + + The path and file name of the Log4J logger configuration file, relative to the application root. + + + + + dynamo.config + WEB-INF/dynamo.xml + + The path and file name of the base Dynamo configuration file, relative to the application root. + The default, if not specified, is "WEB-INF/dynamo.xml". + + + + + + + ScriptExec + Executes a scripting file as a servlet. + com.silverwrist.dynamo.servlet.ScriptExecServlet + + remove.extension + vs + + The extension which is used in the servlet mapping to distinguish scripts to execute. This + extension is removed from the servlet path to create the script name. + + + + script.prefix + /scripts + + The resource prefix to use for scripts. This is prepended to the servlet path to create the + script name which is executed. + + + + + + XmlRpc + Executes XML-RPC requests. + com.silverwrist.dynamo.xmlrpc.XmlRpcServlet + + subsystem.object + xmlrpc + + The object name of the XML-RPC subsystem object. Must match the name configured for the + com.silverwrist.dynamo.xmlrpc.XmlRpcSubSystem object in dynamo.xml. + + + + + + TestServlet1 + Servlet test 1 + com.silverwrist.dynamo.test.TestServlet1 + + + + TestServlet2 + Servlet test 2 + com.silverwrist.dynamo.test.TestServlet2 + + + + + + ScriptExec + *.vs + + + + XmlRpc + /RPC2 + + + + TestServlet1 + /test1 + + + + TestServlet2 + /test2 + + + diff --git a/conf/web-venice.xml b/conf/web-venice.xml new file mode 100644 index 0000000..47c8132 --- /dev/null +++ b/conf/web-venice.xml @@ -0,0 +1,218 @@ + + + + + Venice Web Communities System + + Venice Web Communities System (TODO: fill out description) + + + + + + logging.config + WEB-INF/logging.xml + + The path and file name of the Log4J logger configuration file, relative to the application root. + + + + + dynamo.config + WEB-INF/dynamo.xml + + The path and file name of the base Dynamo configuration file, relative to the application root. + The default, if not specified, is "WEB-INF/dynamo.xml". + + + + + + + ScriptExec + Executes a scripting file as a servlet. + com.silverwrist.dynamo.servlet.ScriptExecServlet + + remove.extension + vs + + The extension which is used in the servlet mapping to distinguish scripts to execute. This + extension is removed from the servlet path to create the script name. + + + + script.prefix + /scripts + + The resource prefix to use for scripts. This is prepended to the servlet path to create the + script name which is executed. + + + + + + XmlRpc + Executes XML-RPC requests. + com.silverwrist.dynamo.xmlrpc.XmlRpcServlet + + subsystem.object + xmlrpc + + The object name of the XML-RPC subsystem object. Must match the name configured for the + com.silverwrist.dynamo.xmlrpc.XmlRpcSubSystem object in dynamo.xml. + + + + + + Remapper + Remaps URLs to other URLs programmatically. + com.silverwrist.dynamo.servlet.RemapperServlet + + data.object + remapper + + The object name of the remapper data object. Must match the name configured for the + com.silverwrist.dynamo.servlet.RemapperData object in dynamo.xml. + + + + + + Image + Serves up images from the ImageStore. + com.silverwrist.dynamo.servlet.ImageServlet + + image.store + images + + The object name of the image store object. Must match the name configured for the + com.silverwrist.dynamo.db.ImageStoreObject object in dynamo.xml. + + + + + + StyleSheet + Serves up CSS stylesheets for use by the frame. + com.silverwrist.venice.frame.StyleSheetServlet + + + + Frame + Frames static pages within the outer Venice frame. + com.silverwrist.venice.servlet.FrameServlet + + content.prefix + static + + The prefix to apply to the static content path before retrieving it. Interpreted + relative to the Web application root (i.e. where Web content normally gets linked from). + + + + cache.hard.limit + 5 + + Maximum number of documents that will be hard-cached by this servlet. Must be at least 1. + + + + cache.soft.limit + 10 + + Maximum number of documents that will be soft-cached by this servlet. Will always be at least + twice the number of hard-cached documents. + + + + + + PasswordRecovery + Used to access the password recovery feature; changes user passwords. + com.silverwrist.venice.session.PasswordRecoveryServlet + + + + User + Displays user profiles. + com.silverwrist.venice.servlet.UserServlet + + + + + + ScriptExec + *.vs + + + + XmlRpc + /RPC2 + + + + Remapper + /verifyemail + + + + Image + /imagedata/* + + + + StyleSheet + /stylesheet-base.css + + + + StyleSheet + /stylesheet-advanced.css + + + + Frame + /frame/* + + + + PasswordRecovery + /passrecovery/* + + + + User + /user/* + + + + + 60 + + + + + default.jsp + index.html + + + diff --git a/docs/buttons/.gitignore b/docs/buttons/.gitignore new file mode 100644 index 0000000..5c165d9 --- /dev/null +++ b/docs/buttons/.gitignore @@ -0,0 +1 @@ +.xvpics diff --git a/docs/buttons/bn_blank80.png b/docs/buttons/bn_blank80.png new file mode 100644 index 0000000000000000000000000000000000000000..100bbd64e9063a1e9bb0cdfe6a99e9b41f069453 GIT binary patch literal 4362 zcmV+l5%ungP)87gcuA;HqZk&)|V3ULd43K~c z40s2gf)`+bcm&2wJYWDq7Dxz?jB)7b>QH^}x%cEh@4Pny!y9}{Yklx<{`yz{{4f4& zdG+GW=dTyb^*r|Hu6_Re1;%t3W{Q(@AloQVw^N5(7KR` zOey1?C4|lMAh>YeQA#1=2!$AvnpFf5K}Z=-F$gK7$d9K3C6r)5nRMP1Wj#-QmY2p_ z001QzVlFuL-gWH-Lh3x^)aPXtd~DlGp64k=1c48sT3lTYkDQCkbAU1a{f9sL=c0bbDcn9jZmw^uvTnPP;i$D^ zjOF!a|M02ERtN^C6~eeZAFHZqyCLIrn)RYuwCyE^m;hAsD1`_yWLfTfa!vz)tT72D zMrlld5|ZT-L%iERN?CA*5#ceqvTEAPv8oqJD}*t{7!saIqP6b3mhx;Kt(35=Ywtqe zbzE>taE!@0lUK|Bd=Nrj+P111jFUA6VuA@9+A}3YWVs8;TlKWJ_z!-IefPKjB&f@z z)OvF*xd?znH_gg2f}73r$2XsFQDF?tJYvGS^Kr3QUD{qU@_)3KbMOHotfqle7E_Wk z^DbCtAizfJ1QG-=0f-SS$^s^^-|sljIL8Q42xHx>PKRC9ER@y=0g6Zjq{!JgjYHoP z!mS02hN^D7^W!)&&KM=$hY(y*uZGJp%k%T)QrAm@lQo7=1|S~WGa*>W%=r+VL6D8p zjK25%?*VXX`@X0a7-2|rHJq$Vxs=W3t^3bEq%=ne>uErkp7)QTU6hy8 z$yoycoQ9qe5@O_xhY+>VDL`j!NCBh-0iXnDGV{jl_d7~C#sDFfK&3L|kX@|S-uYQ6#u-M?Sr>vUn{{{E3n|-6S5^y>G$|%J`WFffa zdb8brnHNQh2@y;Q)i#y|*IJFkz(uCD;T$)swbRx*O9%lVdglR1WwX8Lgn2eikso$X&Zq?NG;~sMgee!o7-x)j)~DzbNGU}^Fr|zTl46|Z ziE)7uAeb7Xn#Jn=%P*vmF(g7MhPWS9CdjPj_Hv<2%(Fr;ELIycn|Yo90L~g`973>c z*6ne}xHzBALP$c8GlmH{O9Y8h}fPU>e$@Y@9aD z=J^Nz^Pgo|rv#j8A>^n1<6?Dn*q=!9#)f5GpU-Uwo)DqtS#pLjVLThhIRqa9h|&8H zLkJK;N+`w%#Hh8#5T)oTrN-#hYQ25W znH+~Mrr>=7DI^F1_~ma2#yC2!jR624grtzp`}JnM-QMSUZj9lANAD(W>$1>Bx92lN zM5`Gi&@4B>xxTvykp*jwHk4pOWp~;WLNDh_QPcoLt2Lo)nv@zl!8xIPnpAK$cz|KF z&R1nY7@LOP7>58rKmGTAc=7y|F?MtN>Tv%_mX(wiUU!(t!_!06EO$=_P7uVbDT>qa zY>dH}P2&LNvs$gT+iji~*4nbF zgR{e=%ObPhjl+Nt@z!937OSfi<1|irQGytZv4S&1*wmd7BB$f2C~E{$a1J7(jhp*c zZ~-BnW)-}%#xsf&M1pfn+1&SPHk1+ky>IF7|KT4WpHAzm+s7|I_AYVJjO`YY{Cs$* z>gICpIYBX@D$kFHqjQ#0sr5`TrkrzG&Ql*^K$sDNtoI;AjEN9Agb}0=6Y$PL2#car zN?%=HJv=-VWf6R+n#Nl@X;&4Qb51KALx{l>LYAAW=>5=jMP0#^hJFy7AxzacAWXWh zZ<-}Y0RmuMa6XLfImTUGAH4Hi#yaO?cRpq^lR^&DY>kQDQ_AwZ zzz{)1yfx!6GA-bVxxjPal5r+*u?7zY*Xxu|cCkDp1I&)T8jl+st5>&NXjh9E?d zQW*O_FH4@4)7V+7F_oMXM6l7`J0)b!8BQ@_LZ+c7gk_oRy5aeY=lAz-q|BYu&2p{h zX;ymCG+HYFQQx(M5K2j2*1_4K@0aThLTK!#7%gEuItvl*x=v;}BRGWML+}C2Lst|< zmSz1odGD>(c~QtLBLqWC07$39L1q$T91}<}?hX@r{o^0xx8ImmnEJ=8y6cYjSy2wN zMbQnzcz65k>G3JWm={e;fG=r6`-0BN2H%9+tV1fAtYmT?Fm6GF`sWjrtP zOV_>i^2Pnb8<}NVPphjNYm{+ry(XM;3}X)v9{P@PMkp0o z2~r&Te!02gLbjJSMGFx^5MV_1yC)&@Uk+AU&(k!Iqu@dcsf=^Z>3J3+%gc&0>LZ|( z>>eM5ln7(*gSDDq1R>PMqc1=B;p4~u`kTM=r|teV&+_f|sS@P4+yB}(zV*dtpT`&| zm6*WG@o;l@$7DH;oi-X1QC2x3cpMY}j*Co6>a3-V&0|j}&GW1u=C|H{_O#nE&H;#b zZ@rj@ew^*1DZ8%2giXUhDG?&$LSl@yR`qhlDDT@Y1shW$2opk|o*uKjpcpYqwbp8y zwbD|Gq9~NHMjLAkA*8Guit(%rCFp6prHoO^oOQu_!5BhFX)7f|m-G4d-M{?s$N#ci zU+td`i?V!t*na)JZ`{ARpN5`L31RBb=bO7bB8v8MRBB29FIF{|LMa!cky(*t%xJ@f z&}!mBmQ{H^cei&}yWNg)nn1jJ@#1nkPTH+jbwBo)(s`N)C5#J%5o1EDF|Qhe@jOl5 zo0yUm0u%ahf6qDRj0q{nX>!)i(@ZJNvRr99PqVj%64ESI7{OU7&e`_<0U^vNbIyD3 zrQjIjc~*i`kPwXVKZg4soX+znAAj=l?U$$h@hk7X_sRP|ch2Y43M4=EUA4$ztGw^>xJa=FkIbSm&>dD_KR`sW5PFgSCAm* zk}*SBEiev7o2)3jvzXwbY|iKN=4O379yw>u*=KLPb=dEW3zB2&0bwMD#5v(YB8v08 zaK_3aCl~=pW0-GnQiNyEe}x<>Gug3c(SCN^6i3Mg)KRtL8i3d~f%3e(#&V{?X5V3L)(KA+IVk zPt9_XHJkmzXUdoe@b%4xa;9c)%~(_o1kPEX7e(+EW0K|7@p!nsy*?ffjIor!vlq{I z+lP>l6vX<(rI@FgQG^f;!IxESv@V+p#0UU&cARIG=NSO-bUHF25P)28=bW<^A_O3) z>uOSZR_d2-7t0ld;BslJx;h_E0K&Y;Aprf*FBXd|&-c5hEYBbSN-2mSW84LTe($$` zmr?%Sw}0c4_kUJ5P1|<$auvP3zP%||H&0)_Rz}B!uWvRylhfq1YKy9Yz#C)Bx(?nk zE<{$IPN%!)cf0+LF%A)a_SWwPDX}Q@%XV;r`qS<+W@4RyXtyVQA z*jO-)=ek*?WVO4RF8}}l literal 0 HcmV?d00001 diff --git a/docs/buttons/bn_delete.png b/docs/buttons/bn_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..084742ad0ed1efa179cfd6bd8028c2546342fc32 GIT binary patch literal 4622 zcmV+p67lVcP)C-o0OslG;I2hyNI2Ot9@cQMf zI01uET>~KO>WXnuH$5j%8yAVF>y$N`5Z1Pp;KEo#DTRn5(}d59LFJe1c7xf z8*Hy;N1Th*YL%u1MBW<9r9hajmkS7d6sMDU4TJwH0MD!szFh2_05H6G>C&0o&jJ(! zuR+kjSil8a!Ig~;|=r~KX?ef8>Dpy%PXxkQI%rM3*LIMG!%Jl{!+I3Da zn+=9myVY`$<{1PbIA@(rhCA!YA?ISbT4h;*kax~g#vrEa<%}RGqtpd({rU`g|Bn~H z^Mxco#VI^IIvVes$kKehsTuZtZx~~7KAs+2710PmXZj9dyk5?;tXOZVh|{L+2iah~ zUU}yOfL&WlA)I$n6dN0i=>b4msQ?3`)CWKbiDHQ%o=lIVOgO`caPLi;73J%r!QKaBRGbaV$b)_k_!ijH%;4VMsP7ceRTaY7a7J-wKXPe zvz!kGqt&{UjQn5iYU!+l2zO1zDf1yn8Cm1BQ4nC&_W=Y5U;q#!n4}2|U^<;}9&wHl zq7eGL7%gU#tQd5Cj}V}UctDbv)lFTMB_UjEz^Kde!WvuGHRFs?Vy$z|B>AXX&7(M8 zu2y+IBsgfL2xS1`dc7nB3mF;fyio|Ux@pm?e&AIAEY@Y2WCM&aq;Xd*vYURMIcwpDqOt`-ZU6#%fQN=AtDo-^*8?^PchG+MjhKnM^3 zN^m42tJHKlp_F3`5MlxNEFT{1UrW-oZ5t3gBh&^IM|88K*%uiUEf3Begw*>tyDD4JWu~;m;)e!TxE+feyB9t*} zy)oLk06?(Lh7btBlu|}%@V>5VLK&r4h{!oJ+!`Mq?!`$Gd_V+KLVNAgg!g?{R}~jg z-z&~>G1@Y{)5RwpNlwv|QP2ZJk zLI^@sX$yi69upkewi^@!h%kvqTL7$_2W_=Z(!%s=w0q5OpgYm z?b&p}F;F@T^L)8nJ7)@!tgSP>|o$dJS%SMz?j1lm@R|-QE zyk(p}{Dq6}eEWTe2YYc6hX92XR`pG<2Su*5D%WeucvCk7gJQU=I^DLlkdZaoS;qwv zQM#T_38BlyBF_gH!>(zWkag9mw&I*IA$w(<)fjWmVArWUD==kkJw*T{01W2Sqex~( z+u`m_S1&%9=c5p)ZkCwH^&g^(fy&c1BxcYotPLP%NpUwrR>+;evK z>}^}XdxSCLtXFDlyafP=<3wwnX1O!E=}nqMdxv|EKe_kgZ@tB8g)th8wu5(V)5J*% zyi-aG&JbbEW{EIa%okZ+AQ+sn5RqP)wp_QT2U&yu4RM}#+XQ& zy0p$B%m_u!djJ3-RET(I9KGTGGynDI3)bk5eDpi_z3m^~`p$oLKpY$#004|Jt;Rq7 zu20@BhcDK#pJ4p25q^B<8-yE1;x(8L6*&?Q>7GTvg$hkyQiUvbml|I_2;x@43kdWn2ml5oxNj?>a&Wgg|S9E$T;Fr+BKEZ3KPaTb>3mj0PqMA zOaep@6XKnN5I*|N!_k00d7*yfE9alNIJeFM0J^6B+?Sr0f`8`o7mug)lTROFf*^!x zKKSexE~&o%#uJOlwEp%Jdz4~CnQChQ(0a9!G9n0q5R^8?`pt44$w&%WHLX_4TT3a6 z;{-zl5wTj;Rn53W5L)XIMC8ps@t)@Bu_)WFtIp}=_{2*l2Un$xn@%$Xx=!zG?;ai; zc;|#nLU2a)ahmcdt*edJJ*JXS1TeHcu%;u7BLpCTgwdud&p)>~eWKVqSgk8NnSU2! z{D#+@DTX5eK-;UytaX{lC`rqzr@&TKed7%`?eFae@8hH}Ms1eMVmOpZwq7la(Gbx%5|E&_ zQO@;IoN%@T05T!!ack(o!@`v(jqtuAzm&PQJfM45kguUtxVT8NsZbGFcTF8dv5*lZ#QH!nm>eA?X$k;z4mf87X9z-a%RO%fLG8cr)Gc>>Upc!flVrJW z5b-yZ!t_1w z|96DY(-)>c`6GAy@LOJa`s8!J^M_x4_POP1W6qr&YZCwfRb9UK*IxabAAERc96xh$ z_GcgZAqc{g&m8Sd+y~$L#$S2hU$?iSr!P$Z^uae_M2-#*lB^&YL5RA(@0wQiN=hk( z?36LasJ;^-iqniUYFwa{OpcC(ln7(3jrW=}3L)&3h1bsiHpQkmaqrb-w9yJKmyqxp1t=bd-I zaOH)%+(hXB1lLyO*7i0L$zpb_RObQS8V?Djb=_Oj$|&I+t6m8yyQZd$ODPuf^@&qE z^Vytn=A7L$>0_AtWmX5Q4t%qd1-%9T7^SD01FAXQkj6boC{j3B$gQCvZ|9LMhIPfafV-a@8;z0_=)d4eakH`Rc-&0TW-64<$0|Q zVG(7hDK~@BD9T5R`ElDdKH!t5b^(G$`@S#ZG-nK|u8)#ftDZ6*$LVHM?VQ-2FBVb? zrTUYnZH9+*RDL@_sVE1ByX!~dv_-tZch)d)ph9u-aWYu2{I-qRi)Vg zW2br*C5bf}6P%>Qa=9GuZq4U&&Y3a#)QvaJrW0kH(lUt& zMgUUp+NNoQ5CFjSYKaKujB&<$rMk9*5Fw1yIH}vNscR4d03a_00EEq^jG}0EJfWO( z#)1#!W*tY8a@h2RLnuJ1tz7!iE;%hWyR&Q6Y(XV1O-(lbv(2+OjHvrM&3F&sq2 zczWsqT-on!?B#%LQSiL)AG62;kkK09$@XFi`X#zFw6Za6(TJa7R? zL9`8AineJPMF>&nY?|e&@6#d!-UC35uG_YY;|Kt_Sj?Fa2tY2lF~(>O5dsk8dDe7& z+jakII~a~21gq6L%d_Qt0U(T%7y?jM64S`gfR{gK6T^i{p;5pq?{pbf{>zZTFwa}%zK;Wh0!KX6RR}<#OS*3I~mCU zU|DXWC=Sj=apaxXN;~HP0C|=*ZLhWd|C4is(Q>g&vvfJ1`w)tv2;QyNtL^cYkkP^3 z^(cx!2wmG!N*UuqNC-Uq)@R?Hr|i=6lcuR>v&C>c_C{}ww*rlp(|u!&acDHkF~LfM zre5a7C#?F z-g+*DH5vpQys64EPGW0p-*w)5XDwsgIcK!>&LM<3quRQ*X+a1O!X!;Y0A*PwY1%fm zu`Wv!?|t8Od66?FX4B&&O@sG+-%&;(#6k#6VBg#S0f`>OU!C*o)&Kwi07*qoM6N<$ Eg3+1AKL7v# literal 0 HcmV?d00001 diff --git a/docs/buttons/bn_save.png b/docs/buttons/bn_save.png new file mode 100644 index 0000000000000000000000000000000000000000..49df817b65c3c3a169bea3a8f0ca435deec855df GIT binary patch literal 4609 zcmV+c68`OpP)HGiy5q?QTK~#90HPZRdWoJRa@n>JodhdJReWqnfOADn?g~o*E0|XaBC-FWs2#><(R1ZR^XI@4}e2?Lcv~)~9JIvYoTr*Ne#! zj8>~2K&ZNwanbc7C(u}*h(syvtRaLALo2wj&QeMt;t2T=q8d~H0YOL^kHHHmq)1om zB_)(#K$)~oXL&jFO_Ju?7ytkz7-B9scFu0=4TRJ>$f-;7!n;t{n>0;h3S%L%tRyXw)BC3=Z%oWoe zXZ)sG=VbvwjNUu%vYmr^e#W_|Hk+cDAQZe0lre~DT`dWMGRb`ew{I_D2p@j-@lR&u zB~Ibl`T5?#QIVJRwqrPqqh*Yx<=*1-rbuQ8dOIqFab2y7Vp4D0gwuW)r^U3cH^GMp zpc*T~R_r zl3E{~Q5Oq?-})$f{Ttuu)uvZ!cke)Q;Qt0U^)06?#3*IrtT$Fefb}>=5FvmOK#X9PXE1`rV$ONOIYx*=7|O|P zy_^@5sTxOw07WDKlBKNcyS8Zv;l=<)eNj%FbzRpn&KM=mdGBpj&f3i?Nz-bxDa### zqtTjB1|aV0iV!ShVx13GBgndbKwtTWuLNLSH%(SdF~X3hs$Cl!Qz<8Vcb~lUETt(z zc&AAK_b(@Ma#<(1{4bDQyFbZlMVHiFHWiqsb9mfz^yE%u5 zaY~b7=l0EK^L#hP7@fhCuIFbvyZcqOr6_9Sr^RHwUI%9&=0n#cl0!r&W6lL@jrS3N z=)8+D5`rnEjM5lF*L8$4O0f`$_jYG@@9gYOnq@IWL@*_EG$GIUII6B~xk$!QbB-so zT{{|M4Iu=8;H(26=9Asc@q-bo2(nr;A^Uz*O-%?vh-%|N z3^8DW<1nb{WC{^R>1-E(jSrx2>nxwxQBU?RUwi7ad0xf{tg0d8>&5wWw!d7gNp#xy zowBT|+IvTcP{SZOLzpn0blu>+^B#oYoDbgnYuDGG`pn6Cqd*AbIAVxmaFkN5$JuQ6 z?DS5WrZGY;M6kALyE03((aol&l=oc^qnqsPX=R3?V_XF9o%NVtkref6K?tqZ>pU+B zMyekO6J4wN?FJ#lg&d7_R>y!Cg-YqNm|)6=u7e?b1VVoGiGSVQ**C`QUwZkA&pyGJ zL|Ay;Aj~(bi(;~~TC6!mKH^E1R_n?+hcF$6L2|~pAWRH>8$b*mg6Mq=AjS{=+J7u7 zb-15DeQo}WKk=rA9@s??3L&&Lv)ODuzsRy&8=V(r48HAEnP1+?g z&~;s!<=&c6YbiLBS>IHQ%S}~fd5JOb)*?dHX!Ot~Qew)~s6h&wdgZ>?)tk-!@jc6v>q(MBDDQLnlagR ztzZ-rLYPoP=e&cEVjPVP-n-{-)~n6<$G`cm82lHmE&lwkpZ=wv`fA46sP*pN?%CN{ zQ543QyePdj{b=(nG0t{vix6=}V~nP={TTev_i2`c;I%e_GelUwtq>;b)w(Dr2u5!m zL}b)_VWH9sjQll5vN8SxQiLavr8V>G2wseutf7-J&qyT*BkFe4OM?*WK}(9PBZ0Ag?< z##i23e%rfVm89vN)B4@-`|JC@{MX+9flpd%f8fXe;qj+V`q6&+v!_4&fsd;}{r2zw z_Zz<9Pu}}|e`8`2oNekl$x;|Y+q8@lh{(`v0Yr7ZEz2p09>i!}7`16PYbhmyXf(!K zYevmE0T6LUDdX*StCS`LgBa1PUiqqezM36ee(CuyAV@_rThDKbWI8nKG|e}gPEhOv zoEF7$vCvvmCe^4w2wVy#v!QRC_W%;ciM9p+h!B!8ecPL^ELQzHzxywK>-RtV*k?|@ z{E?S8&Gz^H?CB5w=o>!&iSLUMeERX_Tfgd_&pmlkWXa=CpT6adSDtw4bg}CH>mR=7 zBY*H6KlIao+idG{I)NcJb;Brum>Sh%LbvrcO;YbP2w@y`2%z0mQc8l!FlwWXvz9VO z8JB`XMEbTFl_Hct2#m4l+SO~5!+Xwdd?7FQ03eIA=XMWX)^6rPCf%Spfy1D7cXpPG zrL&HU)EWc4m1)A0T=lIs8WYAj^}%DzK=hm^m_&%+$3Oh-Klr{!AcP}SXIjC@s;=QK6`y_oqg(y7mq%2_}G8mIo!`a{rTnNPu_m&ix<wBl=$qd;fA{zP<@?|Fx)1*Pe_kxw zZ+yqA_jeOx?4w`y>JR+Vznsro?>!-CxgJ)PUR9%W?(4qheh6XL4iH9&i5nF{c)Q)o zB&8TxYn}JbgQ4AKStg}y+CKPTwMnx~$^=0OG4bA2>q;gP#9$qWAwUq(jVC{r9z8TD z-#6z;alBofBw5}L1_j%;-SN?-i}Q;ZLYhrN^mSEbMUmuX+ibKR0ixMv)x|0>j(fKljNTtyZO;S``+((&x0YxyvVf~-}cq_{n3X% z_trOEAp{>EP2cgB`+ok%-tfD>`W}Q(+w>tAOlb5DLR_uaoJ)crLdg4IwC$TZO;aI6 z*Q*eM>O0Q4kO?Kk2LJ(BoS#c60f62EXDuZdK}hcXlDC7XPhR}Oy|4PRW_eR)SylI$ zAg8y_U-Q~8z4^k85Ih%IjJ~Zmdk6cNCC#?dS`jMCNscLLwtb8yNpm5nGnR7RH`~`e zeECCv`1$ks-zACs+!MFI^S!SP!5<$M@Bi_?I=g6BYxQ^k_{^Ihz5D)q@}K*aCqMq@ z-zt*)yT0YMKk~DG|J2p_V%a}<|11Ur5ke3^NY2krvtmLpf)J^3RQ;ewEv1w~Ds8Q` zdQ?IrXeD&xf2NPU;7G->CiXbh@ZK( zDl`1xeT9#aQ${E~Jvosw;f!(4`(e=III1y8WR~Tlv058zG{&fy>`;ufbx9&F&d(X= zLI~%ab505l5j56swgx`=Z{Pp$8-L)5PyOEE@#R}D-YU{$wOBm#(8Dj@c(H4?Nj?S9 z4{fu%zfVNAUS4Re0>Ha_JA~4%8=W0wl5vjpsD+fO?egCADT4r>ot|1>vi zv-Rp?P<@E__|hRj(3&ugO`4aCL9NClON|~W<7t|2x9!2v{%XCJQfNIMU%qR#SQr-* zNe5*D2+n$h03{3&oMf3+gGf>YKnU2o-e}D^_dZsu6`_=KCb&>a4gC<~?f`b^Db?U}1b2S?Rn zb?L5qZrylc9JMu0NItaf{^3Esv%fgI)pbpX`0#ii5@c=Ey3LCz#$Jy)$uegRCOFF{ zRaNaB?ygoV&Y895(%pA27jtdB_hraKH5CFh> zQz3#mW1R6(Yc(hc5yCi6vu;p**MS%T0Oe!~K-_MdBuSPRbILhqEQZ)@>ok#+i)y_R zf+GmkID!~4BKYC^^_RTn!TCk?;A_70xi3BqA#9p9EebvKlbvZY*;|~xsI(3M9~|yc z&eY(H?y_P6fwjh^S>~O=m?UYjS}l)`4pyrrV=P8+>8{K3vr`|D6vVj5r5O5wQG^in z-sMH9$1$H2AOrxYHQg|%G)(}2>-CBWfdJ%!TWhT`5Fr3TSr)w-2c`bkcDgfz5NtMe zQ5Mx|4IoUj6avt+&2&0V(sVJuNYVrXpp=3LGRCbZ=*@3@6QlgWhab6q^^4_XQrFvZ zXBM0}I6BN{hZlElC_RRV4-WTuBKzKss?LfD1Ws#{m!)@>aUqg?y6`+K`WCZ~69CrJWgRKq|iWsD0U zAqenu|M>ngXV1Mb@B41KT<`4d1#5Qqb|X!y#ff#+dNiArm|$%{-&N&g7NZ%}SWc$a zjD%23c)i)|?e8rX=R!yX@$UZaVtx@L!YBejD5s-RgkT7u^G+sdaDhwVtN{_nVB4li zv(#BPDiuQT&N0Tl_tv=JJwli>YMdYX0mKL)%@{Ttd!$@BQ7stCcL+nQyJ7-E;1}@0|PYdxL*K;5$?HZ{9j( zYrsxF1H882`3Jqh>koJg4e_5p;d#mNsDS}Jc>NjA^LSpw^A|iucwY4f)U3_B0t5Ym z_Tc{w=!>r@-t+U_2?@Vq466Wnjbd;Bo?o$UR~viGmZ-oGk)|9iYAEa^oV5(mAc ztR;T@%FvnpMHB9C@Vj*e25*FD|K9Lj1B1U_qu*sD=A~ukyu8rKjdw=xX?|=OH$={zGd|~L9pMU)RyKhGy+`DrtS*2!a!pFONIm>W2Z(ZX z^zrD!2lwvYzIkK#`qj&qE)JeQcc#A=QMRU)NlAjfgVPUP;q-Uz-n)k+C!lX{NiWYW zC@Lwhs^#>3oc=oKHAN!&M|$boPGwe!8cX!&FEDx*z7{=-b#r9++Lg=5{yehp?e1)E zJ(*R_=^L6`+B2r*JL|%Lu{fKV%Cz~1yn}l{a{os%mJ!$7Lv@JdXagnkhKQ|{kGd(RODKS1aCOR@AEHorI?#qzF$AZJ7ViQu*vvLch zt*oQF@67pu!HYweE?>ENZFuAcc3pG;>fY4+d&vJVP)%i7Xi`#oR$d|6U|my7JH9q> z@yhiZckYjV_rs4r{rt=Sp1ktp;ER9!<)YM1}p%Kw>NvRpxnk}rer~mB0-~}G`_2Ch0Bv8*a+OufK?Iz!o@+wM; z55)$DMS?y}Lk}nPVlD7}mNn7eLfgldEwb(+-;?snRLUc9A)rqLeV%#?8;AbNB|+aw zZHLnr9!m&|i~)V7I(rTM5EWfUKXic=9rFTw5BhSIGXHo|IOtPA&*u;7f;!owlT-Gz zXe@gZT{^k@2MUZ5=p*_RaM=VXRw5IvNqC0U7{B&*3@(6>_0 zudXa3`i#h|_#|n>WE;4K{_?NU7vyB7M`i1w9}v>xj**H_i^rxVPOl>R)R?@aRIS-l zws^>%q|2lyq|2ryNVlq@q^KY_D?KGPpA4&={iF=5Qi47$IleG8LpFQLwIk?nk@Cl* zPfAd7CHfn~YI>P*S@x+(@yV)57*}dna^pffX~~Ik zsin_mTq-{3W7Ep?7+1G%4DoKMrYGZa`sj?xyh3)mc}nBvW@V%%CB#N$R!z#d)T}jq zgN&P*mXa736PaD3tsTiZke-%v*sv!vuAq<1seMM{rZf5oK6%shrPVj|8duPBa9wq(&l zZ_fp8GmPh&Sy<1v$9KJa7B5@5dff(JKmUN8yWZWs`~AIp_wC>R!G{M9eEi9$A0PN& z-`?Hty%Q9;eVf1Erj6^@tzNl&>7uE#L2pX*4if!xz4U>CexsmY%;;UF8O=5}F}JX` zwO2U1E%5YNv}D_PfT?PFrWKZ;b@mThT zL7$2AeK)KleypC47x63Xjm%BWiC;nKGk#h^S^0LNd_jRbwr|_Y_}5AND4&aygPrj_ z8UI35f7KfBtIH?n-@0X!j34SD{`qq(W&DefzaIWwf}dmq{^iJ@me0k>(av_R74o;^ z`7d0o%TM(SqWpIR_%nXUXCZ?g`+EAd;K z*$_X}>k0D^|2kRzg8$%iRy+dk9~J=#OAdfgQu0mCDb*9^bxHeKV6ej-J#$n0={z zNbzg&>$fkJ-*oOAg%`Dt$=lakvM=YK)QIpV$8(s5)D^? zJ)IqGbRxomkY7U46&kKjTWMUuDX+3Z8wT?#PKpfXWG)?LaFVMiFQq}DATKvNDV=`HTd69osH&-NY;MV8^q4oaVdzvQU{1E=Nzs(5ij{08K~jLh zu~~v?%@_AMV_=F($||dC8=6kGv=)dv8x2f`45qHJ`BZCL0g8c(5iJ-TQ8B8jVcHAD z-HSRJg27RwxU{^ghQqWMiu)D546HT+rlPvGo}y{%P>MSgDJj6vfr`U4P&DoM47;Y$ zT}|AUs9`#l{3=Ep2E%cAWlbGmS^(2kq!&h7O^T+ot4On&xM#^oqtm4X)5KspyNh+T zB^L#U=~hi73W}z)yGJ#SwwNf8cxP94Z;AFYWNL|`mBI9u;0~&o-3*b^bwt5ndiqMW zR+C`ltBJ&Wdixj**Vb53P&7S#{cI$bluq{+V_{C0Pb7*C27}LN45K3oBt_BmpDCBE zrbb&r6oBdNKYgY`$KqO|;4o(^jvqUETXzlUseRI2;R@kg+i7S)tMiG%6BIA&lzqp+iTHhu}aGmync#h7~5AGFdbd z%;94v5KRn41E++GgKQMP2xL?e49+!x$;yr3r$wGrNH9-|V8Wwf;y6rRgmfZg_lW}L z$Z_1RMaRZ-nEXg_=%m^pVpbaoCV`?si-_XqT0|_8qWS?QLV|&tqQ&7+4s-NG2t~tT z&>LgK0Wmy`*G2}DNJ*i^7R8D~Ag>>-)M0{&1Pl&znP~XR;y7{8lfmG|lA=jW7BH&# zr1+R9k<{^HS}-XDgLN&5pGXvl2760sf({I=CXXfs>c~YKDJe^wNECDjtST)}ikUzZ z9Ht^!tftVGToe=y!BnQoM4{Fe7X?KF<5pCqa&2jgLTHO_qybZ%rlqYTOrnyu07Lz= zCY{$$kG3ER)DJMV85426b%Mv1yO0kXhgwa7I-Qq5(Oo`z{AT)14H_g>SxVFLD4Mm^m3j^6dcCec_LAu zet_|DLBv9$V?{yHczXM|P~y7Ul0?B_7P_#+wMAhii30Tl%pzA##k?scr4|K6L~9C_odsncf6oNWZ(z{ZxA);4gd TgQLPpfqy157Z3eg9E1M@_c>;! literal 0 HcmV?d00001 diff --git a/docs/buttons/gelcap_green.xcf b/docs/buttons/gelcap_green.xcf new file mode 100644 index 0000000000000000000000000000000000000000..e7fb60538914d5dff612366b57e60830198efd0a GIT binary patch literal 5170 zcmeI0XK+;47030qX{A*`jUpr=39WiBt6lYm`br2yHy{ZK6(ov)Py$E@0vH5#98V06 zv2lqV+aVreI}T$qwr6a|gkGPH%WVD2V9LVxd!@lc2{zFMu9C z459M&9h#UJI(Q8J4F)<18mse&l%$(0SAA&pm z?!~tc6s{yw$j;EXtux!kUlE}2Pru{?%Mf%%NcnD~^eqKd}O%{%t&8y*=ua9})TT!soyrF158l@ig{AG~Z{pTP4{?_#ir;i;R8y?y>5Im67PsTB@ zy6h%QF8uM^FYe!a|LxabedXm_)LY3nBXJi*HRv#HrZyCJ`Q0X!WMPgn=i%`MLJ>)n zEQUwRZBYn#bEG*JZ(&iTGn&)QG~DAd$#`?*Irsd6OryoJFbeMR+Ew#}#N$g8s4_pXv9K_C>0L}IZd zSdt`l<9<6Pg5(GfnKy$;B#|yI$>ef{0!>39zCpe)hs+sx^Yc)#cu}TMs?-{-7DKQ! z9qRMwr2IJ^52A`BOLC=JtJ52dCX?B0Nwa9YZjER@Fj2fHS88;6lf`PYJ3<|aPOZnK z74u=5K)k3>V+OO;?r^%?h&#ihaXGOi0e=CKDbzZn#qMyqJzlRb)2DOT^{9|95J}}K z%wVxQLHC9ElKhCxVAMziLdg=U)thYro#e~%BUXbElS{=?nG*aRE)V$U`am^cYPsaG zN<<-4BdDlcE>l8`Ky0!%%SVLPX_T-V%0MwhExBIAj+vIVDpa9RsxGprX0Zulf~%k}o53vffm|9Z6~$4S{s=w0-;@Nj()1g@w|{cBp1oCWoKn(FjEs(1XC#p z1tGg=vAy5B{0T?`Z7nI@xMtPL*yt4zVWIS3DwPrln=}1|vxr`#D=f&*&CX<|CasB! zieQ8gb|}yjTXD_UMejnno$aj~>Z{6&a+pc0V7tD?d~gK03Iy!o4p$VKV}#mxEXsWT^!P7LqqZLclOPK}R=2&EGqouAwYzM;52 zd+qAwi&LkLj`eTts4L4(SrZcub_%)m?sd|2>MVNg>Xl0urcNIlAKcZ`Tv?R44pM{! z(;1!b&(LO&^XT-{xihDJab$e|-fi8@)ulP9@v%^1Wa_rtlfjdUBZm(i93LAV?Ax_< zV|znoNzVGjRZ(Fft11Rx=%e?cd-v>lX6N>;o4Y$&8mh~SveOb*MMp%Ybsd`Rq4yvg zRoz{k9c?We8fq)cOY*Z|ZgdQ@qG$X{Q)rW_v7w>9wx+6r%_=F#Nl#fDm%uFBuw~-e zN=hZYLd#*7m$OQX3vx126O)+*?CO>slh3gjEK(U(T2fq8kei*6mQ}*8YGx2tE%_8mJmbu`tmS)~l_9s7dFgn!jZLQ5s^);0QF_o6rwLf#{%ANb) zFL4+ggsm-Sm6a9)XqB;RTel6L{mpxy|0FXMuP9zF0eGuz?%Fka=DD}-|3j!YIcrEY zNHwhnsnyoi1B-WW-8**T(o64t`t1U$x4C@%lz!TPdfy<>?cw8RFa7$J_dfaR-(sb~ z=JNXSo0OZhTiDCLyM5=4ckX`l;LGpkBubsx;RX|eM`~TzvdQN5<6(HPm?ZKD1$=^{ zoIL)L)&|c4JU3>S$%vs+0mvSnSYyR$cogPU$%F((iBO9lC*v_nuS~)R!7I@?;9-fD zAxqvx0YO@>1+~?S3}k4q_1y2L6L359}%1wNn03k22L{AdVD zR+#0or9~-N1^jt1kpSDII?hJ#+MSdxec8*ff#^Mrd4w+@bNn+4E7DVK@_3lLLg^@aOL z-euxMw*hXb2m?Tv-0G+J!+d%;>K&kKl`^Riz)WfJM*;yDfF&GO)3REzC=!TdTC*>T za0OZbUkwUrrK)Aqe~Hp1g$BfMAH|D!OpoTv03Jd0MtSufH^7FO04^Xam1f!O4fm2g z`aod@SSrC!fQ1%!xEpaHPQAlMAPa#{;I4&B>|i*^#M*&ZmazaD0g3@FI?N0+$%Mg% z0pJi}0GR+ijaG*nV_=9D(I9F)>@-jjuoQ$MEM7DcMHCddg{TD!5Tw^9XUNGik{nT( z0R1#NKvV!oug_2TD)j^e1H)NtK&K%3aV!!u=$3(g%@!Nbqt{1>2p(Y}Tb%&CPGTv z;ZxwF-nZB99q8Zh1IN$*`m+vvlK=Yb_O*6=48AVjYQXSGFtECJKAuqj&WEn*+y{Qc z2mVJN_~$?HFMyBF^}f}DgRgx#>zNTM|AOI0to$?dNExa85_+^;sbK#I4gmuH03e}^Rz8Kkx?EfN1;ne%pH>KG z-+xgdV%3$p^3N)@(0^L4hfh2UE!R{U%jdAauY8QvREUsIDqp~g4vXQf($$!xJ$8?7~1DIy~`19H;b{(!bD zkzbWpW7z}E(5wY>gI7mgPwX}0#N7O-Y4HaefsSA3*<%3OVX<&tQ=50!9k=Y)7o~cqw|Z~J$LTifB5L@uX``` zhAStleO>rk*V}G&c71v0LGL%uUiOjuUk^}-6w+Y0n4j)w#nGD`T|M`EpY~CPSYwmZ zoLTN1agM|b??)K;mTt6v@#X!;F9sOnvkO9rd{w!wQWMoAP1xred<%c|=-B{siZ5E# z=nQ77&F*ksaz^&-l;-O1SbL#klTx+zueZepeBJsk6qzxV*F^xFR3`wtreWIVxoLZ?X>M!EoRdd6VRn{dYFoZ zu7-dv<>R1UI6>_v6UmqRfh;+{Y-Es(lHUx_ri3auR{S|%^Z{4)O$+@1ob=PimUTwc zRZ}%q%Gp<_5IgRtu(+}{<@!(8QLI=>8OQp`2pQ==p)h6zOH0eh@>L-M%VrcT3IJ&T zA%)JKoSvEGa_4vm@A7;RD<{p2XJ_h#$b(e<`#rvpn(cMm`fYs{DBD1rO+57pM943PGGR^e#p`<8UMQYQ16Cju zE*~a*o(;j+@Yw8lgSdY#N5Sv%DrpStcn&EmRGl|FkNCloyq+I!et^sg|`sK3F`N+TEvRELC>E9DAO z`D*~m2nfz!0<&=8`Y{Y3l&dS>$LgRbfiw{zwemwyF=7S9J_hxwu2f?`hR+&|2)czQ zBhc4je^IH&@G0=<1?+;exEDA$E@S7hx)wrnb<{vOEZYojaMsi2-eVR zX($yLJf^(7_xbgf<|d@+q-WlFgki7HS2Zuu7xCxMo<9BdN$>sc_Ex}~o33}zgGH>j zz8CpA_vqpMdv|(ncYWS*tF0Ae>=-6~z_XVI(ZL!@WZ-o_x$oukZy!Ir`^T=%TWx3Q z?GKiYcqp%CF2bFinVuYD4N<;(_V~e9-R}mpjHEQErbZo6t;3;7Ru;LF%)wXRJnZ?R z{RY0jfgNYPGvct@b}UA{Rw-HJum)fB-tF$Z+1k?Fw-H9ewV^0}a2~hatW!z&lSAKq zbMH0|_h}MnqAnhbMI)i0Z_i=gR4j3Zzk718yZuJ%YeS+wfyUzihTnp#f~lcbkH7k& zvuns0tBnz(NF)^w`aQcggGRy|9r)Az+h0AK+6p&>387Rl;PdR-O`8hAB<;ncp2w^u zZLmH_45a)%@1D!{4tVl(U`nX**ZPS*)VuH5+jUsCHB$Zb)-Sa6>Wk8#DD?(^=%t_#9uy+$FNpPm>UW{gbo6$U$MueZhV+uNYiDCH6%pTh>} zVsk|ro4MYMn&MF2+qw<)nnb{z1mR$?I7{nh?)oV=b4ES77LfWg%yRyVE0D$b4SI~il9M&EG3qK_Hw0G zZ*h9ViF6(ZDwwIkgqZg&R-0qj69~srnZnUY2?r4DLZ}!`=8HHhKI*R~AN5n%i(1d& zDb5KW;yv=XtedhqCazV*0lLt!k8{FwVl>F-82w}dxiq7WRWJhf@j9X`Dwd`|;!tvl zGOthLJQ1SH=u(l#rbGRLrm-}k6AYVgn9uU&xKOm5sj*=iUfT%yRpI4=CJQrO!|#=nUFs-!D7(PP(c97k`RqS!3KP8hXpSU zK4)y0J_xz4W`LA{v5QP_L3M&W6BTsCu%iif-oqedo} z9Uq2y7xoV84~d0TKAYZ8M7$1zTEd?mWzZQSZ{Y%jbJ=t%7Tnv>t-+fLbCj!e7l?)0 zJeotYX*|Q{FsQ`yQ>9x+#|G~-3;Y$i z3ZiKCqf83+oQ#FMPLoz45{o6P8lx*+oj!Mv+E2zKL9fH4Q!5oxiF9q#>Pa*tkT?=c zMZ*E_uH99|&kS!(9Q|A(pB1HecM`fWPKB9d@f}dsB^z zibyO6#2ZWNQP3P*cj8-{8(LUNCJ}++NLRH6yDxT7kT=K?SwboS8e_1b%&DK zH$~x}3DYZ}n@a8W&Tb%fkUuV!rRSxHEG1X0t!uUn7KbMU<^ATQRIcb6bf`YLZ7^AE z&OKi!zMm}|6(L^1d_*77i}?28T{|3!CH6D9L%i^D2*K`F{}cYl?^7`RPg~Xh0hziZ A!TI-gg3+(UV%U$$-Q}y5R$MVgb;{;5CKsFK|nx3R74=4h=2ml z&W_!7+`6@`tKF^E2U=U5-K|^4jvYH)ySqB=c2?0SK31w!!Xx+gTvlf6|LuQ#Grx1b ze82B}=bX&_^2^=a*s@K~Sz9ltZ)|q?0jmSxQx33I01yNQE&$Vb*w2pwFdhH`Km!N` zNC)6-2Bp$!x3;vnT06jJKWbrEPP?n7!&N8P)!5M>C~a^F%odxSV#5Ha5>(c*9a(n3 zynGId=h$nuQ$-4DcDvfC9BN<6=m1m^5`g)}rxvi@_+av5zvcVC`K z6$ulN4v57SBndXxbD2WiLPeL%jEc3Czm;pwd2qZHIE-5BB z4IpiA(whhmwa7a{kfT1}*{;=h-pJ3Rk_jo<>g3drm6YAQ3^( z;B>ty7s@5fd5k=P1tRB(hr>o5$cK;_lo=czyCyC^Au&lr6U8NaN#CXeU(?7Pw zQajTbY|g5%n79FFbptTo}+y{~%s;Tq>?J+a1-l4NWbrTeod% z6SPgnv2Q4&_Dg z<5SY*N{!BtV>0Ji@~s60HlghySnskMlqu0sF~THqx(rvUHQFp)wq9?DH%y&6G1R>7 z9gR|vwniA2B$i0!xI&>+F;oKe)Wo^>c2!$-Dy2rRmWz|9?_Ua@91%A4#pk~qX)QNt z6-u=}x4>owyhM^FVM+MukN)=MOBbd~pBP z$Lj!%i-FwhI zf-Z!7M)(%zXJ36kHTjRP{_>|UKD~1J(!~jM0=mFIztU$beYVnP|NlO7Gx|t3G)n?W zTtf}3Ng5#l-~;800YVD-Xham4VK7I6I5md?4)!5H6WIjfgTX2yY{{XKT!Ib)2pI`z zgbel32|5`?Fv(CLoWaB*wL>5og(uOL{hkNEBDb0*4I{RvYq>&-@bG2nzVN0pA z?DVEviv&qpPzx)MFa!0R*T(YzM}z114WB$G$z(<{EP|3=Cnm%T1^jRh1A!1g(m88y zyd?NEK0S6iCORrIB8(Rj#PMe_=;%_yg1F<77e{aedoGh^NW`K9K}F70l`u-6VvoJZW-;kCxJ0xjDl|BN#Xu1RMwxZ@+t4;>8?@Ea+T2uMQ?<_ajz%UD zL~sNBsTv4edhG!105bSs|G>U}_nw{G8aI{OjLNjQXkHN51ti$cjickx7&PiRGy;B1 zyE?Ww9X5j^H7<%5$Yy{`=6`Y!IY=9UhCM@r1N}Xn?OSRq>}IV@v^pXLWUvB@PP%Ds zq!;S(ba!>`Xm4$--B4C&(qdv^G&m_UB(dTrEsPeZ+0)dx*;Tt~gQLV|He||E<72}^ zIP4gG!{I7M6;$b|Snnt+Ew&d}Oa`qYBZZ=axGDD55gW_qDX`{S@^Vc%`m9WaOd=A- zgoT8QvrC$X3~a+AeRj4kOPi@y;xb7}f*>j)PNK>!YaLOeYNqNbP!>#i%PO5s9eraT{QAnxyAPhv z%qXM#Z$J^`dH6hWVS+yK?BZ{KclGn@H~)I) kpAVl*&v+Lo5?X1gm6lp*ssC+Dxe*oh0xScdUS9qF0~#4#G5`Po literal 0 HcmV?d00001 diff --git a/docs/buttons/gelcap_teal.xcf b/docs/buttons/gelcap_teal.xcf new file mode 100644 index 0000000000000000000000000000000000000000..10e87c629f8a8218e4f503693e38a9e08e498ae2 GIT binary patch literal 5147 zcmeHLiC2?X7WXAz5_a6F3P=$l>`MX!kX4XPDNx4+p<*q9j*6|c+E$jjV6C<7Olzk- zof)TdX3orObwl#3Q1T7lhz_kt<0Ptl4w1Bb?)~vw|u8q(TXe4Nxpru0# zZHH8;$2-rQX*=5mKd-?PH}8I>?O0daOEDKtc6G$;?`Vsutln3Tqnn}O6nNB=_3@Jp ze1Fmhj)&GCJCBp>J@$IrD|ie6e}Rh(4JW~%1w7v434xFI@NG@dQ~Thj_90L0L!a7* z!#&RRWKrM-uYs>8=YCQjxzDg_ zsl5T1!{?azLvva%LL?AZDPh|Z(=xMY^z4{yGKQ{dZ|{kOeg{HHt~>vmzumnTe-FV> zoAiC^dgw;ULG-rQZzSI!U@njOUu6*p5fEJnC8nzBM0-j*0dq^Q6otb;Cld5bO4**u zDneCaHHx`~cj(YdKrE!dwcEDG#_fzxpi&c)b|#@->qiyOKo%UM1O$bItzEw09huH1B1iXZQ2s`?9RlLv<%oXpvBTXKm4m2ChHIqIUqP}eMD4T za%OH}S!K<>=jt08cQh(KzEwa(a5QA?=E%5|?Bc41LoXa}KXvBp*-oT0`kdl=Z#EGj zQ36BOZH`XJ+*R4w+;-;t#qPe#SFT<|u0{7NuDnSnBL4j7gbawcw4b}seYyX}&3A9T zx8psz~=4kdaqf z)7W&Z{q)PPUVP(HcTew*Ud8px_0$b8eQQiYdTvq0-i8B5j=tE|aq9G$vzd-v7F z)v0?gy|}NG78e;2wS$_PLCay}?1f!U&&Z_i*d9ksNzbBX=j1XN zdDJ}phaa48sw&LQ+f~3wO`s;Fq~q5kiLU+2=T}cYU!I?vQ&3u6TUnYArFrxmMp1c9!@=g()}zgMhoFVj9NnUx82|UDJ?)JZc{wzCZb3;o9LfC$ z4jn$+6yKzlO4#50vH$Fmnvz^PtdqkiC@e1BU0z-hUtuz>$Yz=U{HW*T;o7qN99kyG zbi)vOHpnLC#Ad5qPK#E=`Tp-8z14Yae{FdYY%QBkr_ty{dMpii_2{ZeE#k87-TC0H zu9K~YpReCnTU|w}ime2g*5^T2%{rNY!@U2GJGXCL>$~*Eh1Xu~iti#~dY{+rw43xw zF@JJo;K%Roe|_)n-LFVr#e5lxIlZV=uaYfE5+#A~gH6L{53-m9CdwKd9vf!^b}R=@ zkr!1?KV%Y_F4oxeqC%@r(8C$>Iu&CN{GkJEfk+CZi82C)`aFioAsFgrJ)GhRfiQU< z4v|yJ9fUr|z|i>A^z_WkY|<=>`Bv3zCc*?P*Wl0yti=HwWFn4>Vjktx5ab0c%fR5! z@WYW&h;b$+xPTisiF#au0TvT5jVuU092w(qr)Fm7cznJXHVn!f_$cn|b>To(;RF_t(o*Wn)9^p(2#0ss^Y+H4@Tqx?M zx{U_i?9kA|@k!pIT)S+xJ6)(d#ckAS=DA~|oEf1+Wia8t*`atEQYe)pn~H_H=Bl=>Ab&Yg;)T8&&hF8~6oP$X3wOjg(; zq)9^c2EB4=LBJQxiNLvJx^WTJUKkH;6zFG{3xg;J%~5Hvom2GK-o0cu#aE^8G_3osx4 zI0E7P!lFnF#0e7MHNnehHfZFMMWKMlo15bSUI;&00DMNT+qG&l88iy1cyV4Jfb4UG zIWjM14q(7%f~do0Ue;@ra_N#-v)hloHc3(Vy`laT^%3YZW z(GlzXA;gqx|I@xleouDm-J5UsU+%teuD#`Pz$1?2zHgS^y-B($f9J;a{;Pd&zSh}s z^uXTI99U&zcrffFt^b?3UUILzr~A?y7hiq(bo;TU#+p(_dcyXI^`SvQn+vaeIo3() zl))B%eX8Tc@zx^;8fq(wbJMBMZiNitDGj}UX10)9K(q2l)8T{r8|rE+cNgW+(h_hy zd`od__hctaulLo{_wB`<9JspQTl|zWK?wWr1a?(vsq$!h$?T z4lN^v8XFZ68JAU3_ae;A3(O-jbhzHgN>8E2ZI4aL%q=Ku?6~@8COwp{qh)5KrzRy( zQy9An@^T6*o6djm#b|nPI!M!{rlr&KORH+COAB&y8Rd;9uYUghEEGzFW(1nH5nz4*m*inCkM9g4}FcPJTsWd(Wr;9v2xZ0xLkd zW_M{xQ2`@|o|Q#sl++wKd;QKgY_Z;+jX<$P$Od#TEei^$6YJszDfaZ{5E0kNYe(U#2tr5r7fDqPTqJyuu4vr0HHWGqBR zkfLHC7fKqaxgM}(s29#w*gQe#=FN<g@4r&TMZ z;syQ;cYFjtFJQXaDx1e1Xa_c6)xig{UZapK@TNJBnj4pyJ+5FEaOxa(n`K3>mWu^5 z6Jx^<23X^AGwKd@161dN4{P|8*DAz`(cGg{wcrS zvZCRr0gtw>=#>%yuB${c7>VUC?SefQC0{U~$XlMn)!3p$ zt}#Hh3H?5(o+v!u9FM>Q{AB@D!cwIM*M%;4Z++N8-~w?Gh*qFJma8=SWwXuUa>FbP zUUn#;5G7HyqSk0}Q3wU26Nm8I9%2R-V71zC4e3HX9xu!w{W1f;%)rln26_<&{y$n4 JH2;5B{|BQ>>6QQh literal 0 HcmV?d00001 diff --git a/docs/buttons/gelcap_violet.xcf b/docs/buttons/gelcap_violet.xcf new file mode 100644 index 0000000000000000000000000000000000000000..9537ae01abc212691960c290f446dc253e595e13 GIT binary patch literal 3862 zcmYjU2UHX37G}}`5m5xO#DGXs=_Pce2qK6|(Wkp2AS}CY)wj|`iim)8MCq{fj&!7V z1d$@W*FX|N5F08bnfDL7p5uSco&V1L?)~OwGIze@x8LvlkK}IWKyvu~PkRoqZUZAC z4p@A^AP5`|03+x|a&RC97C$fyFch$Zz+`~&{06Ab*xkEx$NsJ}IOjkL1@!LQ+c?|b zCb|9Y>`1b3v?m#!H@$?Q0>BUoB5M;{2zbIHaDAu+M>u)mMwAlF3}4j4iL z10($FBL$rQ`e5VW`pM`1$=~yn&-0Vd3w(s@$HD^#xdyU+{@njWI3UA+ogWQ@T*#V( zgBQ6jvi^-jPJkA~IXL#i5L=4H4R5eM&b1fDJ@s;Tc9L)+z?*I8>mpeeV+b>{E<6=UEMvs{Q^Uu#U`a@<>nW@EG{W6EfXoDd|b^!s@)!V`vrwPPs+$E zuB>fnZf);)-PzeC(zQ&PN&N@*4~b67EUIj1d($^CJUTW$F)2DpotsQ?a&hfv`ocOiL~X#nRL*zPe6EFdQo+2&(Or|;xd)K!dP8piZbcbAsfA!mP}!{1Wg)biC;u909jvYHC_+dU=U5_O`J+KPx>mr>MNP z`E_^iyTPI1k&)5SG0`y^b9G^?yRp0=Df%^W z%d3~U>1k;hS-Ax-ODn2gRoB$kovfp6e*e6-JU!UiP*IqZk(QbY9;2-6oZQ?zOrCH) zwDW%R>jws9a-gf}RY^fkCLl;fr{dC}RAL&$UftRHz5(Fr;hv7Bnu?O5g1p?EY>8|L zJol@t?ai;B*652fV*@>19j#4`^>uZ%Vzp?1t+9~8Pw!XhOAE786XRo}qa*kc;xHe) z!)EPlOKx++U$-f(k@jcB_j92o(FB?@VNJ&S6S(&9^6lpr5Il59 z2rqQ>@D^($G@rT|KlOQGaJ{_y!f8{dVWR zo2R$0-(&wL=qJPgO2P|UB|!qX{LvGq73Qo(>FM0C~8QH3cr8NNRuorOgttcaau-R zQCS6iN9yVtVj7IZI8Pf>ZB??m(i!m+;!@JG@(PMd%96?}`8mP&uAS2$t7x3n(^FSC zEp=L2Mpjl%LXJ^ilkDecuCJz~OxDuBaK*~%irEDt14#qgyS~b#M~)T-YRU>qWKCTo z(<@fje?h(nFQDc7p_JKCpU7Z=>>3IF3ftISWqJsP>d5Fc>+<3n<-d&p)8{qbb zwdF-416>_$ElqJv2wq|DY;CO5W(PZ7aaWHS^W_wds zxR*1KqAh2aChU&AsPtBe&y1jpWWHI!v1L$5p?iU60h(vd z%}!4Y_jiGh`!YW}E4#3=rGJ`x8k%BEPK=KZ^}p?GZLBUY%*o8kE3NAq9pfBBjjoIg z4-XCW^>np0RF&ibZObjL=@^*pNA+{|t@QSE1KDV(sdx#H^o(2}qyy8mI_|nJwKdgM zm1V_+`PrFiP}clVO+`5F!LgH3T=uHKF5ZlDyOrnO_FdF7_ z+jPBiQHB=-qT9Tep3j0&*k^^Z+_X3+c@U2X*>{YncgrUj*5uSgYkXE$Q&UwX%Zl*h zFbKGb=du%5Bey5j2@)BdR9kELsd!cv>54#!2Z45fMYj@W%b4mZwJ{@Z(0BP zAInR|dK!wSMUM&a?cv1lX6Pk(;k}@T)CV4JPInz`uU|IQRFD)F+P{|zk2Il!(v)9t1}#KMco*Lt)g=;2G(~#2;I!8Cq*V6^JMvbf_FD-F`cu3%gw3dmjrv|qM zq|Q)NC99|?Daf9Y5@`?5GB&+rX=Q03Z>oSu#rC;)1tu5W(ZGrFj4Tn(=VsY7azDub+| z47!k)Q&3jdHM{v&U`l286hnTWJfyG=)J@me(#9zu;brU4B6CBNN0R~cSl`g(%60p{ zd?V7z+J@#CpT6zf!ra2!tk~XmaJ=L6z%Mi|v$Uyae3AM2`!t;Q!LrKDvS zl-9I#4^B}SA2z^Lff4aR9f84!2qTB%Fi;SnEku~bX0ajmQ6OIsP?f`AN7P9W;E2lb z!31!Q1{Lf>K!mV}!_UTn2$%|>Qy4Y|76jUafpGvt7|C^FbKVi?f|3N$Boq1?^@9leU zS3CQDqdof$9L_s6usd(}zWve!I0m8Q5)(Mmp#T8?WI~}gzMhak2psdEkfD&E%!g72 zg}DcYDjhg<;DGetG5CK1u`sJ?NV@ZwbTIGazGHjydiF~5*0gm<2x}G;A_U>}WZZf( zfuB$6AnZ)Z&Z9(-_MNAtLxc~Jml#wiL=YSb{qdYwkob5GKN1*E&6A#*CqFf3J~dB; zb0XH0L4y+_2Qi-B_namHta&_nQZV!d&m|;eO#HVV9EGK9By{O`I1=>xyew}L9*p|! zdga8pj4h+%Sj2BqPRI~ha9p7_Se!05aOZodIEHz2(1j$!#wXQgtF6dJh9Ue$!WF7! z^adkhTxlZVSS;d%0m!n*!4Bgp48!PfROkR3uf=EWjgS&y0*J0~25} zD4&{|o>nN7g-Q&MxeZe=4HyR#Uis9t0xpKhd8X zFk?Yoe9@Frtut91ZjUbz423WjW(oTB^2tg0v{J1%Tb&+%AcTb@#SyFDXHrecr>~3EW z7DLns{5F@3SfMkRP@BW$B{qc>V<2etI<0U4JUDnjkIx|h0xN?6vjm{c3~hwb6hA$e z+e7o@c|jzA#f?V27HIwO(2XWDYOz>JRf_FY!D+WyEhs>X%oM10MI(_g z77V}}>+!hVE|%-r1%7sc|F17_DjterM%mBbKVUsz;DMO^$G7^cQt1dAfse5H$0Oxw z2nlghQp(ovf8~SUef`ayyZ7!dy$>H^)tx>j4cf5eMV)7_-6*<2hW_6lOr{XJ#7x2N z{YThG;5&?=AD1U12ok0&sufFsgxv)nV)Z3qD)a+nFEzcOq@uE_x`xZ;0bT(=ghvfu z)shhajez2%(h?cTDXHn1^X6xPEb4-sg;>=0xilZztz-&?N>5Bq$(X+|J9k+@A&XU1 zOfJr4V?pc1Rq1gLDvgnxHgD0=g5t6&zOcTrxutb^tH!C_okBy%aCK5@=At}SIj^Cu zv!`$Sj$H$TgVJSEt#-VR9JeQ@Wo55e#cOQueQx)Gp%bTHJp0l)^0}Pz+D8w2s1yn< zF)3|+PGOm#MY2_T@c5YvmtVa)a_u^DJ$F>|;9g%AgUB#HyP%ZY*s*En^Fyc3y*zw% zeFFzj}+9Iyw)zsEE)^p2>ic43Ol~-_B9MgkuZ(n(SV{>hF4Nuep zYwcp2@{1mBK@OZ?!R|wUv~??rm}`FYF^vfvw2%Tv6De5kRpS*QlnP=_dk9x zd|-=MR8v)1#TAGen#F6|J31wW5~I_he)R1pubm#~ZWVGXIk1`7hp zNXTQ;%K!G~uRgl@%GskYNOx@C(zkh2?}}aoM`IDp=QOJ)fBE50-+X%e-CJ+IHhTTq z2x$ad10%7kBiSS8X&3MmFXn?iIEJU-84zZsHK-f@L&p<6z#VkiQT^=HL>y=28fOTn z;%T<9)i5I`z(s}naWbB4q8cL_#U!Co+d?=APt%e#VKuRiEDOm|e-y`OnX`xrn^7v{ zapm}=HWg(sDkD9S)d zW*5;3b(+~3#k71P4qK6N9p*}M0jI+O`ypyFXw@p^l$=-yWKoSbKngJYz-RS(Tn;M= zv0-LWrpFNid&_aJ8HD8a3n*s3k{}Bla*x_(B?ilmaQv>UvyS2m*l926wB67=qf}SSs9# z9pWma0*fimG!VzU!K5G(fGp;9yByFPa)(Y&@SERD^-|%tY;`#uHftO@v;+k~Itp3I zR;mqHfhCB}aYvkH40GrdHj<3V2B44Ww20Ol2PX)9p>R|?PwOHoM6CqZVUcJ|m#PDL zyTNEQp^%{;z?1uiY z-_Qr4?;rkS){EgxJRR{81j*Uw9=dRx zpU6jeK5k8Q6{noNm`No=7C}O^1)F~f#TJ5vv;`o`Ie%VedTL5CBau#{P{?GMIb8hG zcR@CZO)0h(u~;itEYHhXl$DvrWF!(EFnl1_HW&^p}o1Ts-z%0D=j&Z2JHy4?%sLQdGa~kOJ~o#c=FhxeFIy% z)(APQyoDLeIgiE-uXWuMS^&>D17^9UIrKt}0#z9bgJFBDyt39Rs6!*ri^% zeBsRTgVL>Ct#uWwr3=zw1PZzSonbIcz5*`mU%qtl{Mpkm$F411Vo`O;@+I@rlIV<7 z@jEBzC-ldU4IMuC!rp=YzV7yBVRdOi&H|Vrv$%IOUjD$Y9sS$-dN-_J+p?NpS+XK` zVP;Cwl1Axp52MG}-PO6ieXY2qQ6#7?D=vVx^d+m-?YStXi}h<-TU%P18|y`N0$z1R zDJwsFLDrJ82Fad_LaLBl2Wn9PpU2}?SC*F)6)erkF0K|dcfT;qC36`yR^q!_Rl+JL zSXnOMafRY7M_=bKIiSK?URKI3F5%QQGzqy}eq-03OCN}UC`pKl>YLWAlk{{;#0>&& z6>oLNj?*{4mXaWAkfdM`44`lyTY9_NTN@xURMphC?>Ow9qZa!n^xEI zsw*q2YnwIl`QrYAzy4dPw|RmX@w%TU P^N8PrI8cb+auWUnz&$Ec literal 0 HcmV?d00001 diff --git a/docs/design-goals.html b/docs/design-goals.html new file mode 100644 index 0000000..047f4af --- /dev/null +++ b/docs/design-goals.html @@ -0,0 +1,103 @@ + + + + Design Goals of Venice/Dynamo + + +

Design Goals of Venice/Dynamo

+ Eric J. Bowersox, <erbo@silcom.com> - May 2003 +

Introduction - The Original Venice Goals

+

As is well-known, the Venice Web Communities System was originally founded for the purpose of providing + code on which the new Electric Minds server could be run. To this + end, it was designed along the lines of the CommunityWare platform, by Durand Communications, on which + Electric Minds was run for several years. (CommunityWare formed the nucleus of the WebbMe portal system + as well.) To that end, the original design goals of Venice looked like this:

+
    +
  1. A replacement for the CommunityWare/WebbMe conferencing system
  2. +
  3. Java/JSP/servlets implementation running under Apache Tomcat, MySQL backend
  4. +
  5. Multiple communities hosted per server, each with multiple conferences + (and other features); users logged into one server can join multiple communities
  6. +
  7. Conferencing functionality similar to CW/WebbMe: +
      +
    • Linear topics composed of HTML messages
    • +
    • View topics by new messages/unread/all messages/hidden topics/archived topics
    • +
    • Topics can be deleted/archived/made read-only by the conference host
    • +
    • Topics can be hidden from a user's personal view
    • +
    • Individual posts can be "hidden" or "scribbled" by owner or conference host
    • +
    • Posts can be previewed, with spellchecking and HTML formatting
    • +
    • Files can be "attached" to posts (up to 1 Mb in size)
    • +
    +
  8. +
  9. Enhancements to existing conference features: +
      +
    • Full text search of posts within a conference
    • +
    • Conference-level "bozo filters"
    • +
    • Individual posts can be "nuked" without a trace by the conference host
    • +
    +
  10. +
  11. Later, replace other CW/WebbMe functions: +
      +
    • Activity logs
    • +
    • Instant messaging and chat (use Jabber)
    • +
    • Calendaring
    • +
    • Newsletters via e-mail
    • +
    +
  12. +
  13. Features from CW/WebbMe we won't do: +
      +
    • Web hosting
    • +
    • Web-based email
    • +
    +
  14. +
  15. Blue sky features: +
      +
    • Output uses XML and gets formatted into [X]HTML via XSLT; "themeable"/"skinnable" interface
    • +
    • Conferencing/other functionality available via XML-RPC or SOAP calls
    • +
    • News page creation (see Slash, Squishdot, Scoop)
    • +
    • Member trust metrics (see Slashdot "karma," Scoop "mojo," Advogato distributed trust metric) + (Feature indefinitely shelved at the request of the EMinds community)
    • +
    • User diary pages (see Advogato, Kuro5hin)
    • +
    • Moderated discussions (see Slash, Scoop)
    • +
    • Collaborative database facility (see Wiki, Everything2)
    • +
    • Content management/distributed publishing
    • +
    +
  16. +
+

Evolution of The Original Venice Code

+

As time went on and the Venice code was put to use on Electric Minds and elsewhere, gradually, the enhanced + feature set described in "Enhancements," above, was implemented, as well as some additional enhancements (user + photos in posts, some limited customization capabilities). This was in response to the needs of Electric Minds + and other communities

+

Perhaps the biggest change, however, was a changeover from the original UI front end, which used a great many + "magic servlets," to a generalized system which employed a scripting engine built into Venice (actually, the + Bean Scripting Framework, which supports many different scripting languages), so that UI-level operations could + be written as scripts and executed directly by means of a single servlet. The JSP-based display front ends, too, + were updated, making heavy use of JSP tag libraries to minimize the amount of embedded code on a page.

+

A partial XML-RPC API was also implemented, and the "mailgate" program was written to take advantage of this, + providing a gateway from a mailing list to a Venice conferencing topic, with some success.

+

Dynamo - The Next Leap Forward

+

Currently, the Venice code is being rewritten to be even more modular than before, carrying the advantages + of the modularized, scriptable UI into other aspects of the code. As part of this effort, the lower-level + support elements of the application are being factored out into a code framework referred to as "Dynamo" (for + "DYNAMic Objects"). The goals of the new Dynamo-based Venice are as follows:

+
    +
  1. Even greater modularity than the original Venice, including dynamically-loadable modules. One should + be able to add a new service to Venice simply by dropping a JAR file into a directory on the server and + performing an installation process from within Venice's administrative UI.
  2. +
  3. Replacement of the JSP front-ends, which involve a high degree of overhead as well as the need to employ + external access protection to prevent them from being invoked directly by an end-user. Instead, a solution + based on the Velocity template system will be employed.
  4. +
  5. Refactoring of database access, to eventually allow the use of databases other than MySQL, especially + ones which employ stored procedures.
  6. +
  7. Improved search capabilities for posts, possibly employing the Lucene full-text search engine.
  8. +
  9. Shifting of configuration information from XML configuration files to the database, where it can be + modified without bringing down the server. A new "property" storage system will be employed for much of + this information.
  10. +
  11. Replacement of the original Venice security model, which employed a somewhat-confusing system of "security + levels." Instead, a more modern ACL-based system will be employed, for greater granularity.
  12. +
  13. Replacement of the front-page publishing model to allow people other than administrators to "publish" + posts there. Instead, a system of "channels" will be created, with each channel having its own ACL + to permit other people to access it.
  14. +
+ + diff --git a/docs/identifiers.html b/docs/identifiers.html new file mode 100644 index 0000000..b3b7892 --- /dev/null +++ b/docs/identifiers.html @@ -0,0 +1,46 @@ + + + + Doc: About Venice Identifiers + + + +

About Venice Identifiers

+ Eric J. Bowersox <erbo@silcom.com> - + January 26, 2001

+ + Venice identifiers are used for user IDs, community aliases, and conference aliases (and maybe other unique + identifiers in the future). A valid Venice ID consists of characters from the following character set + only: +

    +
  • Alphanumerics [A-Z, a-z, and 0-9]
  • +
  • Dash [-]
  • +
  • Underscore [_]
  • +
  • Tilde [~]
  • +
  • Asterisk [*]
  • +
  • Apostrophe [']
  • +
  • Dollar sign [$]
  • +

+ All characters are represented in the ISO 8859-1 character set. Also note that all Venice identifiers + are case-insensitive.

+ Rationale

+ The character set was defined starting with the list of characters allowable in URL path components + ("pchar" as defined in RFC 2396, section 3.3, page 14), so that Venice IDs would be usable as "path + information" in a URL.

+ The ampersand [&] was eliminated because of its possible confusion with a URL parameter separator, and + because it requires HTML escaping.

+ The at sign [@] was eliminated because of possible confusion with email addresses and Jabber IDs.

+ The plus sign [+] was eliminated because of possible confusion with a URL-encoded space character.

+ The comma [,] was eliminated because of its possible interpretation as a separator character.

+ The equals sign [=] was eliminated because of its possible confusion with a URL parameter/value + separator.

+ The colon [:] was withheld to provide for a possible future "namespace" expansion (as in XML + namespaces).

+ The parentheses [(, )] were eliminated because of possible confusion with user link syntax in + conferencing.

+ The period [.] was eliminated because of possible confusion with post link syntax in conferencing.

+ The exclamation point [!] was eliminated because of possible confusion with extended post link syntax in + conferencing. + + + diff --git a/docs/user-acl-truth-table.sxc b/docs/user-acl-truth-table.sxc new file mode 100644 index 0000000000000000000000000000000000000000..46e2d4cff1e8027eb4919c213d4d71900b852b19 GIT binary patch literal 6612 zcma)B2|SeD_gD5ITZ2(yj3u(njGgSuF!nWMU&ay!W316wA|Y#$wPY##P9b}ih>%3t zw-B;rjlZe4-sSVY|IhC}pShp8_kPd0=X}q7?sJ~|=%^DC0SU-Xua_FB`~-g~6sP}f z-OyMR8Y|%I>av<)>NciE(>dAy^y@~OZsF^P^IEAn6`FxOZ1=_x%eup)q#8E#unJ9q z$>SmiN~9XtWCnFX%R;rx!2x%*a-wMjW^>ZETjEE~C+mFd0w(YAXSojteoZK@?s{1GzI*v!#8(VD9G7;YktKX-biQWHn3&dYkT2i8B zWLRdm>TP;*yrWv1?fV64T%s~PH==e^{Hj<+Z-;|?LuR}7_nRI_fqqs@%$Wu=@GkVo zH}I%=MiesK!cLn{wa^hz#>h+ZVesY=N5ggux{Wb*M6#cfVRof+8Y?Z4`fO`-l64=6 zdCWB={*|;_ndVbwoevMcy>QJ4XrVOAB=patY05P&(&=kxI%5mCOg+Z7@=KL zRvH|o>_4@`Vkc`8bqgc&d}jZNNb0@I%MJ6w3+JzBwSl`kJUbkEp{smTTd{{-{%KcR z?8gknyYl>B7!-?{Fc=Xu5|+n2gCsv2D2k*roTnSU;HCQ{)!>PLnuzkIPMKvK|+WnG;eHGXRW#? zaW9DH)8Jf{_@!djXvCO#+P?VC<-;P?uO=CX?cX)fsg547b4S8c7b%!tzUSC0QvW&{ zH&uzG+ejjMQW4gGTSnhi*LDJ4NNpXqc7;T}DAx(0v>crlb zjXbKoscI-w=y^9uGMRu?b;JO!m^5GrH`zIfnnQ+)obI|+Fc!N}or zp9sseG|Qq`{x1}F>$X)Y<<#BsJ`KAAQPkk|^eHj#Wg9RmYhw{zaR*Zwk9*9r9lh>$ z>wfQR?Nyb0{r&yMqol|zLP{>4&@+?_JfXytBs`(#C|P(y2`L5WLw$}&{BgV4+joUv zf+Wdm8K^e;U}#-S%3o_&S6q3SQset;v#1t0ZEiF z6$1>ELn#XL&7q`%JvZ1o^BeUU00#z|Uy>K_$1Jpc+s>-sJ&==a5))?DA~fF7*SpXNezmNH&5xoABVh?lfRJzI7?~H7T!uvgc(RojAAy3TRh+J zTw0YGn4?tyZnipA-$;7qmkAza!7c3f@Gco%(ve?&4EE9^J`-L-qc{yX`{HwV3UwH7 z*9z6FHtTf4v9KKO!hL58Qjo@}dLLM`RlJ~avsIknhvupHK2lPUS%LWDA0Q=X*=1@N zHVgzfiN;$Y#A>m#_~68Ed6;PDM#5TVPzwhN7SsYkl?AncQFseb?m;cNHgY>RLi|OL zKHAN1@r@9(?YX&`SNV+JheQs(4=03F$;n^OIb_8X2{59uDpO_Rvx2F5S`&t|%Yug+{WvY-qpk}KC!PDx8`DAcl3H7N1 z9W7@_k|R&UaPHtO*J-fuVJM-Fi^@zlb1`Sl8J}G5^|_zC9sEEZyvM2*CI?7NYLx@1 zM?d)-ZLDhjwxbmRh)rsh2P8+Itq$>dbXOT6zvl$d!@lAM;2>d4OUOEew+j4NWm3ZQ zJup1A)lnoYE00VUc>EHUQ|8FSmjiPYvSANXQJ)5fsUzZ@0g9T|RjI8y`nS0wM@|JG zix>PnQa1;8LEEX%i&Tx(`W>B@;#+faVR5Zba?9dcALo|Ew`S+M$F*{1chQsgEHk;9 zOY32~xiQMEgZ@Y+Kf|0>dVC-&Al4f)*~Jqo0R8AEd(w0aUxzwc6#$`0zg=*#n2Wp} zb`)Kcz{*o+0}R7yg`PT)%80Y#U+9?(b2)i&F=5Dl>$D7VWPcwfY>ocyEVVy=fsGTN?JS<~%H{_=5>%v4Hs^hm6g z;VNND6F5iKGktiR>FKR?#;I+3*@VD7RvmRxvWgG@iv}41LC;MB0-gU%LI9^ph$q(1 z1?7p)L57V@+-5~-ZmpNcQ;F#dFEg^#xq&3lO>#BUB%tcDE8C)fwH_;yXu3IuP;dA(!XZy{{8536iI^D<74j zCuNSjcKfV*IAh)l+v~tgEY@vme+(d4)`_A|oQ5(gWSdMDO zNOf#Y1fHdWEg;GxklK8G=AlSfeo>0pCB+#jJw7NC z2E7(sX-86bn}_S8gzp)lq^7l*XrTDHk4y~l9QNlp4Gh!70yaCT`_APJL`sZ^n~*QY z2CA$RG@X1Avpcioz1yre@xj>u9l|{$o*Ehux^?t+)Iyt~s0$lE_!7i#E$`ySbMLyt zc7_+b5*hb2Q!;T2agyt^Pps2GIx%*b!u};9{(kQe&Nwb&jhr~a$SQ6dV)_76HOYGO zhqkIW6H#%wujoEh*=X+OFB3wN?1`jz3~d%~14exirFw$gDX5f-vu1Jy2i3BYh8~|e zc5=Y!DS37`^?9M;Z?t7T&mniX35haRW6X0O);$E=SB-*emBpo8aAx$^Ds)jIUfkUH z_)P--O?xf;QhBNfyN=b4D4B)ur$SA)A!7F2M_ztlfSR=-ICd9&l#6*`Yok3Uy(7_u z%-0m>75x6$x$~kywaI?1-MIyqMf8%h{KJ6Mm?ZU4OyGQwwCca4M%wG396vH9*zgiS_ zgGbS2Sq7 z$thaqj3e1=r7i51$2I1O_)S%WYWSFqN{Vv|cRmg+mMrt|_GHNdxSlQ^kPlz!I-k$! zn2$Aw*WRq#BtAcAiRyi1mX4j6mBA%N-#z)DA|d+4qii+0wr$&bGt>dmI4A&$9litS zk&%(mx4G;<)Y%tb+9b>!TE5RMpnJUke1b9?y6l?eF}fQAu?#c{7NyyoSJTmSU|#ct z1}`FprWLloeIqS|HEWHODWIG_zeK0ctvT~fYwT<|+2a;@Z})y;wXm@0YbbfER-wgN z<@~t9@9Cu~iuoue*;WsyT(*yJv(!y*1)26%hx>3DRfS#uWZoFM;R!?fTb$57_0aRi zaa`?1ma9r5lKGs2)e{oteT0tdj$qOlz}#}YPE1-O>+{*>bA58+R1H%a-)$jf7Ti{Q zh5C|wFLy(iHukr-pJ3{sL#`*c+z*&b$=_xBh^Gh#Bfc4;W_BjoN>5J0r)BXwXYtPU z<+H>D1fPJvc24|T8~*iel!a`%o{)e5|2y4U30zTFYy7?`C3{+dy-^rXCpWY-1TFxB zfKg~$H#;Y^gEYj@0KqQ~k(B{Ru_>UKKEAENj<1Ys~3^k*9a{wd(=;)HhojrZ~K5%3ZEVGmqFLIV0@ z^cU35_BYPm3*+(wWoHXTxuEd=c|zd=aOf{A-r3*if3pG)fc)a;|I4-b)%!q<`x zC^QOVjdjDw{GByCLjrIxw}uni%a=zA`VX)a8$Z9ko}#EQ+|pD`R8+{^QUj@FXl#kp zGEmmAwDfee_CZ@(V=ZCgP&gb46SRa2Ns5R`3JdY`|1q&G24#&s4LHA@H5Mgv%AX)V zT##Q-)Bq+Z2@{qSl=x%LzvHCrY$g9iKuAndL{tj;Yw)LQC_5+Y=@R0%^|L*FLdyvL zq3|Ewf5+N+osw~Cm5h#okdUUJxc)zcevkhY^YTPt`0Y^kPH2=J_y1F=;-k9c)R29u%RC6Rr$@#wWXA$%;2=rp|~V2 z4kRJNIAC5M$sON?vY^?oRcLyeX+~jLh#NmL#}(~_uOjYBOA`z1&%nhfknP%ftrDN} za=k5Ij5u>nD*;(;>7@I1v`l8AY+f2c`NwupwR9l5R|s`(a*C<^PU$TF%0wy)#8PtD z-ZhX13yxNq#QOvF)d~*e%oBdTs~S!;_bhj|q-5XpFVxMeHu+5I0`dJ`%U%{krFP@p?&m4{N6waw@i_?v|II*Uq&gWW;PDc(d!i zZ(5#eV_?EUpj8W3Wv#ddX8hw0xr={v;| z)j0kAio%^wPh<~qL^2pZ7@KEZFgs4gckcTXFOE9B=9;msk=8zVw`}RAvLR@ZFM!my zCsy`yrTL8Cd%uz~E4P<>MSZK;Dw9cCc^PSXD0=Da4VzR~Jw_9) zF&|p1M?m7a+U*|c>2cZ~3PJ#I%;PHCt8P^2It)P`b9?!G9?$4xv?iVCuIxA}=<+D( z9)Cw{*!u*l$|}|%GacvX3Ohnglk%|FoAW7rmS0RRjx6ku={n5-&H7urto#zKsHxtl zzy-BA;+$gSMus}0+suQp4q0uEW1MNk(_lm$ZOqNyW}eGw=K~`$stHz>Hk$*4DM*mk zjXs%FJvSX@G>^Wq&ya46_iltB>)Z3A4X(`grqwWah&V~zb3430n;023K*I%(NOsLjG%^*5l9Ch;< zYPd=e`G=4*Pj{rM@~Xz213dY>?0bYOMRw}N9FbZBO#&Nt(8sewcONnPNqQ(o_zYRC zW(ovDp)vNaYaSS}yrq7@IOtG+d0wOd8;x+*>!o!9v1>aAtT^AWODleO`+HBOy;@j5 z8BYqYk)8{^B<#yKV<#+_E7G+NGwCzW(E9=~TNm#54jMlocR``8ZPVtxq*2EvY zw)|H5@xAcyaFP<(0^IblC-C-FLQbDlTbxW@$>3J1aP`$7P)^v1VotPyX?8-%750lA z8#l58ExO=(GmRGu`rk4x^xuYqfHpgVmW2C*+Wsocg^!N2v#-mGP*ZgL}RwN&1ft$*PSGOc?WTAR z1*f2FZ-y6AZKjzJ);U_*Od8LPwN-e5Zqk~k?*~79TAW|(wVMqjmbzty@#sK%O6|g@C$Rqn+$go<9!RiwDbZw83adre11iO`snQzLT42!h#HVHYxS1yOWy`Bc;rnuI|v!SA}6bOJv_!D zByO-i!0RHWz2s@}rQi_;dfmxOF>_={{{EfX{@9ElvhvSe44T>WuS#Sg3x)!Xd39Fo zYfbXa+rSYs#b&oRG_MaVo3bV|e5v@S;9v7){CUEkCG0dw{_}Lh($ literal 0 HcmV?d00001 diff --git a/drivers/.gitignore b/drivers/.gitignore new file mode 100644 index 0000000..b3b3865 --- /dev/null +++ b/drivers/.gitignore @@ -0,0 +1 @@ +mysql-connector-java-3.0.7-stable-bin.jar diff --git a/drivers/README.drivers b/drivers/README.drivers new file mode 100644 index 0000000..eb651f5 --- /dev/null +++ b/drivers/README.drivers @@ -0,0 +1,6 @@ +This is the directory where JDBC drivers get placed. + +MySQL +----- +Store the file "mysql-connector-java-3.0.7-stable-bin.jar" in this directory. + diff --git a/resources/dynamo-test-module/res1.txt b/resources/dynamo-test-module/res1.txt new file mode 100644 index 0000000..f7513f6 --- /dev/null +++ b/resources/dynamo-test-module/res1.txt @@ -0,0 +1 @@ +If you're reading this, we loaded the resource successfully! diff --git a/src/baseutil/com/silverwrist/util/AnyCharMatcher.java b/src/baseutil/com/silverwrist/util/AnyCharMatcher.java new file mode 100644 index 0000000..a454c0f --- /dev/null +++ b/src/baseutil/com/silverwrist/util/AnyCharMatcher.java @@ -0,0 +1,160 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +/** + * A class which performs the equivalent of String.indexOf(char), but using + * multiple characters. It locates the first instance within a string of any of + * the specified characters. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public final class AnyCharMatcher +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private char[] charset; // the set of characters to look for + private int[] locs; // a temporary array used for locations + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + /** + * Creates a new character matcher that matches the specified characters. + * + * @param charset The set of characters to be matched by this object, expressed as a character array. + */ + public AnyCharMatcher(char[] charset) + { + this.charset = charset; + this.locs = new int[charset.length]; + + } // end constructor + + /** + * Creates a new character matcher that matches the specified characters. + * + * @param charset The set of characters to be matched by this object, expressed as a string. + */ + public AnyCharMatcher(String charset) + { + this.charset = charset.toCharArray(); + this.locs = new int[charset.length()]; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the offset within the string of the first instance of any character in this + * character set. + * + * @param str The string to look through. If this parameter is null, + * the method returns -1. + * @return The 0-based index of the first instance of any character from this character + * matcher within str. If str contains no instances of + * any character from this character matcher, -1 is returned. + */ + public final int get(String str) + { + if (str==null) + return -1; + int numindexes = 0; + int i; + for (i=0; i=0) + locs[numindexes++] = tmp; + + } // end for + + if (numindexes==0) + return -1; // no characters found + else if (numindexes==1) + return locs[0]; // only one found + + int rc = locs[0]; + for (i=1; inull, + * the method returns -1. + * @return The 0-based index of the last instance of any character from this character + * matcher within str. If str contains no instances of + * any character from this character matcher, -1 is returned. + */ + public final int getLast(String str) + { + if (str==null) + return -1; + + int numindexes = 0; + int i; + for (i=0; i=0) + locs[numindexes++] = tmp; + + } // end for + + if (numindexes==0) + return -1; // no characters found + else if (numindexes==1) + return locs[0]; // only one found + + int rc = locs[0]; + int limit = str.length() - 1; + for (i=1; irc) + rc = locs[i]; // this is now the highest + + } // end for + + return rc; + + } // end getLast + +} // end class AnyCharMatcher diff --git a/src/baseutil/com/silverwrist/util/BooleanValues.properties b/src/baseutil/com/silverwrist/util/BooleanValues.properties new file mode 100644 index 0000000..cf97455 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/BooleanValues.properties @@ -0,0 +1,19 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# --------------------------------------------------------------------------------- +# This file has been localized for the en_US locale +values.true=1|true|yes|on +values.false=0|false|no|off diff --git a/src/baseutil/com/silverwrist/util/Country.java b/src/baseutil/com/silverwrist/util/Country.java new file mode 100644 index 0000000..72e4016 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/Country.java @@ -0,0 +1,159 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2001-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +/** + * A utility class used by International that stores a country code and name pair. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + * @see International + */ +public final class Country implements Comparable +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_code; // the country code + private String m_name; // the country name + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new Country object. + * + * @param code The country code. + * @param name The country name. + */ + Country(String code, String name) + { + m_code = code.trim().toUpperCase(); + m_name = name.trim(); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class Object + *-------------------------------------------------------------------------------- + */ + + /** + * Indicates whether some other object is "equal to" this one. + * + * @param o The reference object with which to compare. + * @return true if this object is the same as the o argument; false otherwise. + */ + public boolean equals(Object o) + { + if ((o==null) || !(o instanceof Country)) + return false; + if (this==(Country)o) + return true; + Country other = (Country)o; + return m_code.equals(other.m_code); + + } // end equals + + /** + * Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those + * provided by java.util.Hashtable. + * + * @return A hash code value for this object. + */ + public int hashCode() + { + return m_code.hashCode(); + + } // end hashCode + + /** + * Returns a string representation of the object. In general, the toString method returns a string + * that "textually represents" this object. + * + * @return A string representation of the object. + */ + public String toString() + { + return m_name + " [" + m_code + "]"; + + } // end toString + + /*-------------------------------------------------------------------------------- + * Implementations from interface Comparable + *-------------------------------------------------------------------------------- + */ + + /** + * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive + * integer as this object is less than, equal to, or greater than the specified object. Country + * objects are compared on their country name. + * + * @param o The Object to be compared. + * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than + * the specified object. + * @exception java.lang.ClassCastException If the specified object's type prevents it from being compared to + * this Object. + */ + public int compareTo(Object o) + { + if (o==null) + return 1; + if (o instanceof Country) + { // compare country names + Country c = (Country)o; + return m_name.compareTo(c.m_name); + + } // end if + + return m_name.compareTo(o.toString()); + + } // end compareTo + + /*-------------------------------------------------------------------------------- + * External getters + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the 2-letter country code for this country. + * + * @return The 2-letter country code for this country. + */ + public final String getCode() + { + return m_code; + + } // end code + + /** + * Returns the name of this country. + * + * @return The name of this country. + */ + public final String getName() + { + return m_name; + + } // end name + +} // end class Country diff --git a/src/baseutil/com/silverwrist/util/HardSoftCache.java b/src/baseutil/com/silverwrist/util/HardSoftCache.java new file mode 100644 index 0000000..41a7a9b --- /dev/null +++ b/src/baseutil/com/silverwrist/util/HardSoftCache.java @@ -0,0 +1,329 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +import java.lang.ref.*; +import java.util.*; + +/** + * A class implementing a memory-sensitive cache. The cache is an LRU cache which uses two size limits, + * the soft limit and the hard limit. The soft limit dictates the maximum size of the + * cache; all elements in the cache have SoftReferences to them, which allows the JVM to expel + * them from memory if necessary. However, the most recent elements in the cache, up to the hard limit, + * have ordinary references on them, which prevents them from being expelled. Therefore, under low memory + * conditions, all elements in the cache may be discarded except for the most recent ones. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class HardSoftCache +{ + /*-------------------------------------------------------------------------------- + * Internal class to hold the hard hash entries + *-------------------------------------------------------------------------------- + */ + + private static class HardHashMap extends LinkedHashMap + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private int m_maxsize; // maximum size of the cache + + /*==================================================================== + * Constructor + *==================================================================== + */ + + private HardHashMap(int capacity) + { + super(capacity+2,0.95F,true); + m_maxsize = capacity; + + } // end constructor + + /*==================================================================== + * Overrides from class LinkedHashMap + *==================================================================== + */ + + protected boolean removeEldestEntry(Map.Entry eldest) + { + return (this.size()>m_maxsize); + + } // end removeEldestEntry + + } // end class HardHashMap + + /*-------------------------------------------------------------------------------- + * Internal class to hold the soft hash entries + *-------------------------------------------------------------------------------- + */ + + private static class SoftHashMap extends LinkedHashMap + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private int m_maxsize; // maximum size of the cache + + /*==================================================================== + * Constructor + *==================================================================== + */ + + private SoftHashMap(int capacity) + { + super(capacity+2,0.95F,true); + m_maxsize = capacity; + + } // end constructor + + /*==================================================================== + * Overrides from class HashMap + *==================================================================== + */ + + public Object put(Object key, Object value) + { + SoftReference newref = new SoftReference(value); + Reference r = (Reference)(super.put(key,newref)); + Object rc = null; + if (r!=null) + { // get the old object + rc = r.get(); + r.clear(); + + } // end if + + return rc; + + } // end put + + public void putAll(Map t) + { + Iterator it = t.entrySet().iterator(); + while (it.hasNext()) + { // run each item through our modified put() + Map.Entry ntry = (Map.Entry)(it.next()); + this.put(ntry.getKey(),ntry.getValue()); + + } // end while + + } // end putAll + + public Object remove(Object key) + { + Reference r = (Reference)(super.remove(key)); + Object rc = null; + if (r!=null) + { // get the old object + rc = r.get(); + r.clear(); + + } // end if + + return rc; + + } // end remove + + /*==================================================================== + * Overrides from class LinkedHashMap + *==================================================================== + */ + + public void clear() + { + Iterator it = this.values().iterator(); + while (it.hasNext()) + { // dump all the references we contain + Reference r = (Reference)(it.next()); + r.clear(); + + } // end while + + super.clear(); + + } // end clear + + public Object get(Object key) + { + Reference r = (Reference)(super.get(key)); + if (r==null) + return null; + Object rc = r.get(); + if (rc==null) + { // reference has been dumped - remove it from the map + super.remove(key); + r.clear(); + + } // end if + + return rc; + + } // end get + + protected boolean removeEldestEntry(Map.Entry eldest) + { + if (this.size()<=m_maxsize) + return false; + Reference r = (Reference)(eldest.getValue()); + r.clear(); + return true; + + } // end removeEldestEntry + + } // end class SoftHashMap + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private HardHashMap m_hard_map; // the "hard map" + private SoftHashMap m_soft_map; // the "soft map" + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new cache object. + * + * @param hard_limit The "hard limit" for this cache. Has a minimum value of 1. + * @param soft_limit The "soft limit" for this cache. Has a minimum value of 2 times the value of the + * "hard limit." + */ + public HardSoftCache(int hard_limit, int soft_limit) + { + // Pre-condition the input parameters. + if (hard_limit<1) + hard_limit = 1; + if (soft_limit<(hard_limit * 2)) + soft_limit = hard_limit * 2; + m_hard_map = new HardHashMap(hard_limit); + m_soft_map = new SoftHashMap(soft_limit); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the value to which this cache maps the specified key. Returns null if the cache + * contains no mapping for this key. + * + * @param key The key whose associated value is to be returned. + * @return The value to which this cache maps the specified key. + */ + public synchronized Object get(Object key) + { + if (key==null) + throw new NullPointerException("HardSoftCache.get"); + Object hard_rc = m_hard_map.get(key); + Object soft_rc = m_soft_map.get(key); + return ((hard_rc!=null) ? hard_rc : soft_rc); + + } // end get + + /** + * Associates the specified value with the specified key in this cache. If the cache previously contained a + * mapping for this key, the old value is replaced. + * + * @param key The key with which the specified value is to be associated. + * @param value The value to be associated with the specified key. + */ + public synchronized void put(Object key, Object value) + { + if (key==null) + throw new NullPointerException("HardSoftCache.put(key)"); + if (value==null) + throw new NullPointerException("HardSoftCache.put(value)"); + m_hard_map.put(key,value); + m_soft_map.put(key,value); + + } // end put + + /** + * Removes the mapping for this key from this cache if present. + * + * @param key The key whose mapping is to be removed from the map. + */ + public synchronized void remove(Object key) + { + if (key==null) + throw new NullPointerException("HardSoftCache.remove"); + m_hard_map.remove(key); + m_soft_map.remove(key); + + } // end remove + + /** + * Returns the number of key-value mappings in this cache. + * + * @return The number of key-value mappings in this cache. + */ + public synchronized int size() + { + return m_soft_map.size(); + + } // end size + + /** + * Returns true if this cache contains no key-value mappings. + * + * @return true if this cache contains no key-value mappings. + */ + public synchronized boolean isEmpty() + { + return m_hard_map.isEmpty(); + + } // end isEmpty + + /** + * Removes all mappings from this cache. + */ + public synchronized void clear() + { + m_hard_map.clear(); + m_soft_map.clear(); + + } // end clear + + /** + * Returns true if this cache contains a mapping for the specified key. + * + * @param key The key whose presence in this cache is to be tested. + * @return true if this cache contains a mapping for the specified key. + */ + public synchronized boolean containsKey(Object key) + { + if (key==null) + throw new NullPointerException("HardSoftCache.containsKey"); + return (m_soft_map.get(key)!=null); + + } // end containsKey + +} // end class HardSoftCache diff --git a/src/baseutil/com/silverwrist/util/IOUtils.java b/src/baseutil/com/silverwrist/util/IOUtils.java new file mode 100644 index 0000000..d8edcf1 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/IOUtils.java @@ -0,0 +1,378 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +import java.io.*; + +/** + * A collection of IO-related static methods which are useful in various contexts.

+ * Some of the concepts in this class have been borrowed from Apache Jakarta Avalon Excalibur 4.0. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class IOUtils +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + /** + * The default buffer size to use for copying, if none is specified. + */ + public static int DEFAULT_BUFSIZE = 4096; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * IOUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as IOUtils.shutdown(stm);. + * This constructor is public to permit tools that require a JavaBean instance + * to operate. + */ + public IOUtils() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + /** + * Closes an input stream cleanly, without throwing an exception. + * + * @param stm The stream to be closed. + * @see java.io.InputStream#close() + */ + public static void shutdown(InputStream stm) + { + try + { // close the stream + stm.close(); + + } // end try + catch (IOException e) + { // throw away the exception + } // end catch + + } // end shutdown + + /** + * Closes an output stream cleanly, without throwing an exception. + * + * @param stm The stream to be closed. + * @see java.io.OutputStream#close() + */ + public static void shutdown(OutputStream stm) + { + try + { // close the stream + stm.close(); + + } // end try + catch (IOException e) + { // throw away the exception + } // end catch + + } // end shutdown + + /** + * Closes an input reader cleanly, without throwing an exception. + * + * @param stm The stream to be closed. + * @see java.io.Reader#close() + */ + public static void shutdown(Reader rdr) + { + try + { // close the stream + rdr.close(); + + } // end try + catch (IOException e) + { // throw away the exception + } // end catch + + } // end shutdown + + /** + * Closes an output reader cleanly, without throwing an exception. + * + * @param stm The stream to be closed. + * @see java.io.Writer#close() + */ + public static void shutdown(Writer wr) + { + try + { // close the stream + wr.close(); + + } // end try + catch (IOException e) + { // throw away the exception + } // end catch + + } // end shutdown + + /** + * Copies the contents of the given input stream to the given output stream. + * + * @param input The stream to copy binary data from. + * @param output The stream to copy binary data to. + * @param bufsize The size of the buffer to allocate for copying. + * @exception java.io.IOException If an exception occurred while reading or writing data. + */ + public static void copy(InputStream input, OutputStream output, int bufsize) throws IOException + { + byte[] buffer = new byte[bufsize]; + int rd = input.read(buffer); + while (rd>=0) + { // simple read-write loop to shove data out the door + if (rd>0) + output.write(buffer,0,rd); + rd = input.read(buffer); + + } // end while + + } // end copy + + /** + * Copies the contents of the given input stream to the given output stream. Uses a default + * buffer size. + * + * @param input The stream to copy binary data from. + * @param output The stream to copy binary data to. + * @exception java.io.IOException If an exception occurred while reading or writing data. + * @see #DEFAULT_BUFSIZE + * @see #copy(java.io.InputStream,java.io.OutputStream,int) + */ + public static void copy(InputStream input, OutputStream output) throws IOException + { + copy(input,output,DEFAULT_BUFSIZE); + + } // end copy + + /** + * Takes the contents of an input stream and returns it as an array of bytes. + * + * @param input The stream to load binary data from. + * @param bufsize The size of the buffer to allocate for copying. + * @return A new byte array containing the contents of the specified input stream. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #copy(java.io.InputStream,java.io.OutputStream,int) + */ + public static byte[] load(InputStream input, int bufsize) throws IOException + { + ByteArrayOutputStream stm = new ByteArrayOutputStream(); + try + { // copy the data to the input stream + copy(input,stm,bufsize); + return stm.toByteArray(); + + } // end try + finally + { // close our byte array stream before we go + shutdown(stm); + + } // end finally + + } // end load + + /** + * Takes the contents of an input stream and returns it as an array of bytes. Uses a default + * buffer size. + * + * @param input The stream to load binary data from. + * @return A new byte array containing the contents of the specified input stream. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #DEFAULT_BUFSIZE + * @see #load(java.io.InputStream,int) + */ + public static byte[] load(InputStream input) throws IOException + { + return load(input,DEFAULT_BUFSIZE); + + } // end load + + /** + * Takes the contents of a binary file and returns it as an array of bytes. + * + * @param file The file to load binary data from. + * @param bufsize The size of the buffer to allocate for copying. + * @return A new byte array containing the contents of the specified file. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #load(java.io.InputStream,int) + */ + public static byte[] loadBinary(File file, int bufsize) throws IOException + { + FileInputStream stm = new FileInputStream(file); + try + { // now just load from the stream + return load(stm,bufsize); + + } // end try + finally + { // close the file before we leave + shutdown(stm); + + } // end finally + + } // end loadBinary + + /** + * Takes the contents of a binary file and returns it as an array of bytes. Uses a default + * buffer size. + * + * @param file The file to load binary data from. + * @return A new byte array containing the contents of the specified file. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #DEFAULT_BUFSIZE + * @see #loadBinary(java.io.File,int) + */ + public static byte[] loadBinary(File file) throws IOException + { + return loadBinary(file,DEFAULT_BUFSIZE); + + } // end loadBinary + + /** + * Copies the contents of the given input reader to the given output writer. + * + * @param input The reader to copy character data from. + * @param output The writer to copy character data to. + * @param bufsize The size of the buffer to allocate for copying. + * @exception java.io.IOException If an exception occurred while reading or writing data. + */ + public static void copy(Reader input, Writer output, int bufsize) throws IOException + { + char[] buffer = new char[bufsize]; + int rd = input.read(buffer); + while (rd>=0) + { // simple read-write loop to shove data out the door + if (rd>0) + output.write(buffer,0,rd); + rd = input.read(buffer); + + } // end while + + } // end copy + + /** + * Copies the contents of the given input reader to the given output writer. Uses a default + * buffer size. + * + * @param input The reader to copy character data from. + * @param output The writer to copy character data to. + * @exception java.io.IOException If an exception occurred while reading or writing data. + * @see #DEFAULT_BUFSIZE + * @see #copy(java.io.Reader,java.io.Writer,int) + */ + public static void copy(Reader input, Writer output) throws IOException + { + copy(input,output,DEFAULT_BUFSIZE); + + } // end copy + + /** + * Takes the contents of an input reader and returns it as a StringBuffer. + * + * @param input The reader to copy character data from. + * @param bufsize The size of the buffer to allocate for copying. + * @return A new StringBuffer containing the contents of the specified reader. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #copy(java.io.Reader,java.io.Writer,int) + */ + public static StringBuffer load(Reader input, int bufsize) throws IOException + { + StringWriter wr = new StringWriter(); + try + { // copy from reader to StringWriter + copy(input,wr,bufsize); + return wr.getBuffer(); + + } // end try + finally + { // make sure and close the StringWriter before we go + shutdown(wr); + + } // end finally + + } // end load + + /** + * Takes the contents of an input reader and returns it as a StringBuffer. Uses a + * default buffer size. + * + * @param input The reader to copy character data from. + * @return A new StringBuffer containing the contents of the specified reader. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #DEFAULT_BUFSIZE + * @see #load(java.io.Reader,int) + */ + public static StringBuffer load(Reader input) throws IOException + { + return load(input,DEFAULT_BUFSIZE); + + } // end load + + /** + * Takes the contents of a text file and returns it as a StringBuffer. + * + * @param file The file to copy text from. + * @param bufsize The size of the buffer to allocate for copying. + * @return A new StringBuffer containing the contents of the specified text file. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #load(java.io.Reader,int) + */ + public static StringBuffer loadText(File file, int bufsize) throws IOException + { + FileReader rdr = new FileReader(file); + try + { // load from the string reader + return load(rdr,bufsize); + + } // end try + finally + { // make sure and close the reader before we go + shutdown(rdr); + + } // end finally + + } // end load + + /** + * Takes the contents of a text file and returns it as a StringBuffer. + * + * @param file The file to copy text from. + * @return A new StringBuffer containing the contents of the specified text file. + * @exception java.io.IOException If an exception occurred while reading data. + * @see #DEFAULT_BUFSIZE + * @see #loadText(java.io.File,int) + */ + public static StringBuffer loadText(File file) throws IOException + { + return loadText(file,DEFAULT_BUFSIZE); + + } // end load + +} // end class IOUtils diff --git a/src/baseutil/com/silverwrist/util/International.java b/src/baseutil/com/silverwrist/util/International.java new file mode 100644 index 0000000..14f2a81 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/International.java @@ -0,0 +1,267 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +import java.io.*; +import java.util.*; + +/** + * A class which centralizes a number of "international" resources, such as locales, + * country lists, and language lists. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class International +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static International self = new International(); // me + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private List country_list = null; // list of Country objects + private Map country_map = null; // mapping from codes to Country objects + private List language_list = null; // list of Language objects + private Map language_map = null; // mapping from codes to Language objects + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new instance of the International object. Only one instance + * of this object is ever created. + */ + private International() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + /** + * Loads the internal list of countries from a resource file. + * + * @exception RuntimeException If an I/O error occurred while loading the country list. + */ + private synchronized void loadCountryList() + { + if ((country_list!=null) || (country_map!=null)) + return; // already loaded + + // Create temporary list and map to hold read data. + ArrayList tmp_list = new ArrayList(); + HashMap tmp_map = new HashMap(); + + try + { // Load the country properties file. + BufferedReader data = + new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("countries.properties"))); + String l; // temporary line + while ((l = data.readLine())!=null) + { // read lines from the properties file + l = l.trim(); + if ((l.length()==0) || (l.startsWith("#"))) + continue; // blank line or comment line + int pos = l.indexOf('='); + if (pos<0) + continue; // no properties - just forget this line + Country c = new Country(l.substring(0,pos),l.substring(pos+1)); + tmp_list.add(c); + tmp_map.put(c.getCode(),c); + + } // end while + + } // end try + catch (IOException e) + { // IO error loading country properties... + throw new RuntimeException("Error loading country.properties: " + e.getMessage()); + + } // end catch + + // Set up the lists, which are considered "unmodifiable." + tmp_list.trimToSize(); + country_list = Collections.unmodifiableList(tmp_list); + country_map = Collections.unmodifiableMap(tmp_map); + + } // end loadCountryList + + /** + * Loads the internal list of languages from a resource file. + * + * @exception RuntimeException If an I/O error occurred while loading the language list. + */ + private synchronized void loadLanguageList() + { + if ((language_list!=null) || (language_map!=null)) + return; // already loaded + + // Create temporary list and map to hold read data. + ArrayList tmp_list = new ArrayList(); + HashMap tmp_map = new HashMap(); + + try + { // Load the language properties file. + BufferedReader data = + new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("languages.properties"))); + String l; // temporary line + while ((l = data.readLine())!=null) + { // read lines from the properties file + l = l.trim(); + if ((l.length()==0) || (l.startsWith("#"))) + continue; // blank line or comment line + int pos = l.indexOf('='); + if (pos<0) + continue; // no properties - just forget this line + Language lng = new Language(l.substring(0,pos),l.substring(pos+1)); + tmp_list.add(lng); + tmp_map.put(lng.getCode(),lng); + + } // end while + + } // end try + catch (IOException e) + { // IO error loading language properties... + throw new RuntimeException("Error loading language.properties: " + e.getMessage()); + + } // end catch + + // Set up the lists, which are considered "unmodifiable." + tmp_list.trimToSize(); + language_list = Collections.unmodifiableList(tmp_list); + language_map = Collections.unmodifiableMap(tmp_map); + + } // end loadLanguageList + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the list of defined countries. + * + * @return The list of Country objects that are currently defined. + */ + public List getCountryList() + { + loadCountryList(); + return country_list; + + } // end getCountryList + + /** + * Returns the Country object with the specified code. + * + * @param code The country code to match. + * @return The matching Country object, or null if no country matched. + */ + public Country getCountryForCode(String code) + { + if (code==null) + return null; + loadCountryList(); + return (Country)(country_map.get(code.trim().toUpperCase())); + + } // end getCountryForCode + + /** + * Returns the list of defined languages. + * + * @return The list of Language objects that are currently defined. + */ + public List getLanguageList() + { + loadLanguageList(); + return language_list; + + } // end getLanguageList + + /** + * Returns the Language object with the specified code. + * + * @param code The language code to match. + * @return The matching Language object, or null if no language matched. + */ + public Language getLanguageForCode(String code) + { + if (code==null) + return null; + loadLanguageList(); + return (Language)(language_map.get(code.trim())); + + } // end getLanguageForCode + + /** + * Creates a Locale from a standard descriptor string. + * + * @param streq The string equivalent of the Locale to be created. + * @return The corresponding Locale, or the default Locale if the parameter is + * null or the empty string. + */ + public Locale createLocale(String streq) + { + if ((streq==null) || (streq.length()==0)) + return Locale.getDefault(); // no locale + int p1 = streq.indexOf('_'); + if (p1<0) + return new Locale(streq,""); // language but no country specified + String x_lang = streq.substring(0,p1); + int p2 = streq.indexOf('_',p1+1); + if (p2<0) + { // there's only one underscore - figure out what part the last part is + String lastpart = streq.substring(p1+1); + if (lastpart.length()==2) + return new Locale(x_lang,lastpart); // language + country + else + return new Locale(x_lang,"",lastpart); // language + country(null) + variant + + } // end if + + // do all three variants + return new Locale(x_lang,streq.substring(p1+1,p2),streq.substring(p2+1)); + + } // end createLocale + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the singleton instance of the International object. + * + * @return The singleton instance of the International object. + */ + public static International get() + { + return self; + + } // end get() + +} // end class International diff --git a/src/baseutil/com/silverwrist/util/Language.java b/src/baseutil/com/silverwrist/util/Language.java new file mode 100644 index 0000000..fa9fb53 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/Language.java @@ -0,0 +1,159 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2001-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +/** + * A utility class used by International that stores a language code and name pair. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + * @see International + */ +public final class Language implements Comparable +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_code; // the language code + private String m_name; // the language name + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new Language object. + * + * @param code The language code. + * @param name The language name. + */ + Language(String code, String name) + { + m_code = code.trim(); + m_name = name.trim(); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class Object + *-------------------------------------------------------------------------------- + */ + + /** + * Indicates whether some other object is "equal to" this one. + * + * @param o The reference object with which to compare. + * @return true if this object is the same as the o argument; false otherwise. + */ + public boolean equals(Object o) + { + if ((o==null) || !(o instanceof Language)) + return false; + if (this==(Language)o) + return true; + Language other = (Language)o; + return m_code.equals(other.m_code); + + } // end equals + + /** + * Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those + * provided by java.util.Hashtable. + * + * @return A hash code value for this object. + */ + public int hashCode() + { + return m_code.hashCode(); + + } // end hashCode + + /** + * Returns a string representation of the object. In general, the toString method returns a string + * that "textually represents" this object. + * + * @return A string representation of the object. + */ + public String toString() + { + return m_name + " [" + m_code + "]"; + + } // end toString + + /*-------------------------------------------------------------------------------- + * Implementations from interface Comparable + *-------------------------------------------------------------------------------- + */ + + /** + * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive + * integer as this object is less than, equal to, or greater than the specified object. Language + * objects are compared on their language name. + * + * @param o The Object to be compared. + * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than + * the specified object. + * @exception java.lang.ClassCastException If the specified object's type prevents it from being compared to + * this Object. + */ + public int compareTo(Object o) + { + if (o==null) + return 1; + if (o instanceof Language) + { // compare country names + Language c = (Language)o; + return m_name.compareTo(c.m_name); + + } // end if + + return m_name.compareTo(o.toString()); + + } // end compareTo + + /*-------------------------------------------------------------------------------- + * External getters + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the RFC 1766 language code for this language. + * + * @return The RFC 1766 language code for this language. + */ + public final String getCode() + { + return m_code; + + } // end code + + /** + * Returns the name of this language. + * + * @return The name of this language. + */ + public final String getName() + { + return m_name; + + } // end name + +} // end class Language diff --git a/src/baseutil/com/silverwrist/util/MySQLUtils.java b/src/baseutil/com/silverwrist/util/MySQLUtils.java new file mode 100644 index 0000000..3838530 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/MySQLUtils.java @@ -0,0 +1,120 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +import java.sql.*; +import org.apache.log4j.Logger; + +/** + * A class containing miscellaneous public methods useful when working with MySQL databases. All + * public methods of {@link com.silverwrist.util.SQLUtils SQLUtils} are also accessible through this class. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class MySQLUtils extends SQLUtils +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(MySQLUtils.class); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * MySQLUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as MySQLUtils.shutdown(statement);. + * This constructor is public to permit tools that require a JavaBean instance + * to operate. + */ + public MySQLUtils() + { + super(); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Unlocks all database tables that were previously locked. Executes the MySQL statement "UNLOCK TABLES;". + * + * @param conn The connection on which one or more tables were previously locked. + */ + public static final void unlockTables(Connection conn) + { + Statement stmt = null; + try + { // do the update + stmt = conn.createStatement(); + stmt.executeUpdate("UNLOCK TABLES;"); + + } // end try + catch (SQLException e) + { // warn if there was an error here + logger.warn("DB error in unlockTables()",e); + + } // end catch + finally + { // shutdown the statement before we go + shutdown(stmt); + + } // end finally + + } // end unlockTables + + /** + * Gets the ID of the most recent insert made to a table with an AUTO_INCREMENT column. This assumes that the + * column is of integer type. Executes the MySQL statement "SELECT LAST_INSERT_ID();" and returns the value + * that that statement returns. + * + * @param conn Database connection on which to perform the operation. + * @return The value of the last inserted ID on this connection. + * @exception java.sql.SQLException If an error occurred in the execution, or if the SELECT statement returned + * no rows (which it should not do). + */ + public static final int getLastInsertInt(Connection conn) throws SQLException + { + Statement stmt = null; + ResultSet rs = null; + try + { // perform the operation + stmt = conn.createStatement(); + rs = stmt.executeQuery("SELECT LAST_INSERT_ID();"); + if (!(rs.next())) + throw new SQLException("internal error - getLastInsertInt SELECT should have returned OK"); + return rs.getInt(1); + + } // end try + finally + { // shut down the objects before we go + shutdown(rs); + shutdown(stmt); + + } // end finally + + } // end getLastInsertInt + +} // end class MySQLUtils diff --git a/src/baseutil/com/silverwrist/util/OptionSet.java b/src/baseutil/com/silverwrist/util/OptionSet.java new file mode 100644 index 0000000..2ff9564 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/OptionSet.java @@ -0,0 +1,424 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2001-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +import java.util.BitSet; + +/** + * A variant of the BitSet that can express itself as a character string. Each + * character in the resulting string represents a flag that is "set." Up to 91 flags can be + * specified per OptionSet. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + * @see java.util.BitSet + */ +public class OptionSet extends BitSet +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + // The alphabet to use to store individual flags. + private static final String ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + + "!#$%&()*+,-./:;<=>?@[]^_`{|}~"; + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + /** + * Creates a new OptionSet. All bits are initially false. + */ + public OptionSet() + { + super(); + + } // end constructor + + /** + * Creates an OptionSet whose initial size is large enough to explicitly represent bits with + * indices in the range 0 through nbits-1. All bits are initially false. The maximum + * size of the OptionSet is 91. + * + * @param nbits The initial size of the bit set. + * @exception java.lang.NegativeArraySizeException If the specified initial size is negative. + */ + public OptionSet(int nbits) + { + super(Math.min(nbits,ALPHA.length())); + + } // end constructor + + /** + * Creates an OptionSet from an array of characters representing "set" options. + * + * @param options The options to be set in the new OptionSet. + */ + public OptionSet(char[] options) + { + super(); // initialize all bits to 0 + for (int i=0; i=0) + super.set(ndx); + + } // end for + + } // end constructor + + /** + * Creates an OptionSet from a string of characters representing "set" options. + * + * @param options The options to be set in the new OptionSet. + */ + public OptionSet(String options) + { + this(options.toCharArray()); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal functions + *-------------------------------------------------------------------------------- + */ + + /** + * Returns a StringBuffer representing the current state of this OptionSet, + * with one character in it for each bit that is set. + * + * @return A StringBuffer containing the current state of the OptionSet. + */ + private StringBuffer asStringBuffer() + { + StringBuffer b = new StringBuffer(); + for (int i=0; ifalse. + * + * @param bitIndex The index of the bit to be cleared. + * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the + * maximum option for an OptionSet. + */ + public void clear(int bitIndex) + { + if (bitIndex>=ALPHA.length()) + throw new IndexOutOfBoundsException(); + super.clear(bitIndex); + + } // end clear + + /** + * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex + * (exclusive) to false. + * + * @param fromIndex Index of the first bit to be cleared. + * @param toIndex Index after the last bit to be cleared. + * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex + * is greater than the maximum option for an OptionSet, or toIndex is negative, + * or toIndex is greater than the maximum option for an OptionSet, or + * fromIndex is larger than toIndex. + */ + public void clear(int fromIndex, int toIndex) + { + if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length())) + throw new IndexOutOfBoundsException(); + super.clear(fromIndex,toIndex); + + } // end clear + + /** + * Cloning this OptionSet produces a new OptionSet that is equal to it. The clone of the + * option set is another option set that has exactly the same bits set to true as this option set and the same + * current size. + * + * @return A clone of this option set. + */ + public Object clone() + { + OptionSet rc = new OptionSet(this.size()); + for (int i=this.nextSetBit(0); i>=0; i=this.nextSetBit(i+1)) + rc.set(i); + return rc; + + } // end clone + + /** + * Sets the bit at the specified index to to the complement of its current value. + * + * @param bitIndex The index of the bit to flip. + * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the + * maximum option for an OptionSet. + */ + public void flip(int bitIndex) + { + if (bitIndex>=ALPHA.length()) + throw new IndexOutOfBoundsException(); + super.flip(bitIndex); + + } // end flip + + /** + * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex + * (exclusive) to the complement of their current values. + * + * @param fromIndex Index of the first bit to be flipped. + * @param toIndex Index after the last bit to be flipped. + * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex + * is greater than the maximum option for an OptionSet, or toIndex is negative, + * or toIndex is greater than the maximum option for an OptionSet, or + * fromIndex is larger than toIndex. + */ + public void flip(int fromIndex, int toIndex) + { + if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length())) + throw new IndexOutOfBoundsException(); + super.flip(fromIndex,toIndex); + + } // end flip + + /** + * Returns the value of the bit with the specified index. The value is true if the bit with + * the index bitIndex is currently set in this OptionSet; otherwise, the result + * is false. + * + * @param bitIndex The bit index. + * @return The value of the bit with the specified index. + * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the + * maximum option for an OptionSet. + */ + public boolean get(int bitIndex) + { + if (bitIndex>=ALPHA.length()) + throw new IndexOutOfBoundsException(); + return super.get(bitIndex); + + } // end get + + /** + * Returns a new OptionSet composed of bits from this OptionSet from + * fromIndex (inclusive) to toIndex (exclusive). + * + * @param fromIndex Index of the first bit to be included. + * @param toIndex Index after the last bit to be included. + * @return A new OptionSet from a range of this OptionSet. + * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex + * is greater than the maximum option for an OptionSet, or toIndex is negative, + * or toIndex is greater than the maximum option for an OptionSet, or + * fromIndex is larger than toIndex. + */ + public BitSet get(int fromIndex, int toIndex) + { + if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length())) + throw new IndexOutOfBoundsException(); + BitSet tmp = super.get(fromIndex,toIndex); + OptionSet rc = new OptionSet(tmp.size()); + for (int i=tmp.nextSetBit(0); i>=0; i=tmp.nextSetBit(i+1)) + rc.set(i); + return rc; + + } // end get + + /** + * Sets the bit specified by the index to true. + * + * @param bitIndex The index of the bit to be set. + * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the + * maximum option for an OptionSet. + */ + public void set(int bitIndex) + { + if (bitIndex>=ALPHA.length()) + throw new IndexOutOfBoundsException(); + super.set(bitIndex); + + } // end set + + /** + * Sets the bit specified by the index to the specified value. + * + * @param bitIndex The index of the bit to be set. + * @param value A boolean value to set. + * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the + * maximum option for an OptionSet. + */ + public void set(int bitIndex, boolean value) + { + if (bitIndex>=ALPHA.length()) + throw new IndexOutOfBoundsException(); + super.set(bitIndex,value); + + } // end set + + /** + * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex + * (exclusive) to true. + * + * @param fromIndex Index of the first bit to be set. + * @param toIndex Index after the last bit to be set. + * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex + * is greater than the maximum option for an OptionSet, or toIndex is negative, + * or toIndex is greater than the maximum option for an OptionSet, or + * fromIndex is larger than toIndex. + */ + public void set(int fromIndex, int toIndex) + { + if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length())) + throw new IndexOutOfBoundsException(); + super.set(fromIndex,toIndex); + + } // end set + + /** + * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex + * (exclusive) to the specified value. + * + * @param fromIndex Index of the first bit to be set. + * @param toIndex Index after the last bit to be set. + * @param value A boolean value to set. + * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex + * is greater than the maximum option for an OptionSet, or toIndex is negative, + * or toIndex is greater than the maximum option for an OptionSet, or + * fromIndex is larger than toIndex. + */ + public void set(int fromIndex, int toIndex, boolean value) + { + if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length())) + throw new IndexOutOfBoundsException(); + super.set(fromIndex,toIndex,value); + + } // end set + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Sets the value of the specified bit in the OptionSet to a specified Boolean + * value, and returns an indication of whether that value was changed. + * + * @param ndx The index of the bit to be assigned. + * @param val true to set the corresponding bit, false to clear it. + * @return true if the value of the bit in the OptionSet was changed by this + * operation, false if not. + * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the + * maximum option for an OptionSet. + */ + public boolean assign(int ndx, boolean val) + { + if (ndx>=ALPHA.length()) + throw new IndexOutOfBoundsException(); + boolean old = super.get(ndx); + super.set(ndx,val); + return (old!=val); + + } // end assign + + /** + * Resets the state of this OptionSet from an array of characters representing "set" options. + * + * @param options The options to be set in the new OptionSet. All options not specified will + * be cleared. + */ + public void assign(char[] options) + { + super.clear(); + + for (int i=0; i=0) + super.set(ndx); + + } // end for + + } // end assign + + /** + * Resets the state of this OptionSet from a string of characters representing "set" options. + * + * @param options The options to be set in the new OptionSet. All options not specified will + * be cleared. + */ + public void assign(String options) + { + if (options!=null) + assign(options.toCharArray()); + + } // end assign + + /** + * Returns a character array representing the current state of this OptionSet, + * with one character in it for each bit that is set. + * + * @return A character array containing the current state of the OptionSet. + */ + public char[] asCharArray() + { + return asStringBuffer().toString().toCharArray(); + + } // end asCharArray + + /** + * Returns a string representing the current state of this OptionSet, + * with one character in it for each bit that is set. + * + * @return A string containing the current state of the OptionSet. + */ + public String asString() + { + return asStringBuffer().toString(); + + } // end asString + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the character associated with a specific "option index" by all OptionSet instances. + * + * @param index The index of the character to retrieve. + * @return The character associated with that index. + * @exception java.lang.IndexOutOfBoundsException If the specified index is out of range. + */ + public static final char getOptionChar(int index) + { + if ((index<0) || (index>=ALPHA.length())) + throw new IndexOutOfBoundsException(); + return ALPHA.charAt(index); + + } // end getOptionChar + +} // end class OptionSet diff --git a/src/baseutil/com/silverwrist/util/SQLUtils.java b/src/baseutil/com/silverwrist/util/SQLUtils.java new file mode 100644 index 0000000..95f949f --- /dev/null +++ b/src/baseutil/com/silverwrist/util/SQLUtils.java @@ -0,0 +1,127 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +import java.sql.*; + +/** + * A class containing miscellaneous public methods useful when working with SQL databases. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class SQLUtils +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * SQLUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as SQLUtils.shutdown(statement);. + * This constructor is public to permit tools that require a JavaBean instance + * to operate. + */ + public SQLUtils() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Closes a ResultSet cleanly, without throwing an exception. + * + * @param rs The ResultSet to be closed. + * @see java.sql.ResultSet#close() + */ + public static final void shutdown(ResultSet rs) + { + try + { // close the ResultSet + if (rs!=null) + rs.close(); + + } // end try + catch (SQLException e) + { // ignore any SQL errors + } // end catch + + } // end shutdown + + /** + * Closes a Statement cleanly, without throwing an exception. + * + * @param rs The Statement to be closed. + * @see java.sql.Statement#close() + */ + public static final void shutdown(Statement stmt) + { + try + { // close the Statement + if (stmt!=null) + stmt.close(); + + } // end try + catch (SQLException e) + { // ignore any SQL errors + } // end catch + + } // end shutdown + + /** + * Closes a Connection cleanly, without throwing an exception. + * + * @param rs The Connection to be closed. + * @see java.sql.Connection#close() + */ + public static final void shutdown(Connection conn) + { + try + { // close the Connection + if (conn!=null) + conn.close(); + + } // end try + catch (SQLException e) + { // ignore any SQL errors + } // end catch + + } // end shutdown + + /** + * Fetches the return count from a query such as "SELECT COUNT(*) FROM ...". All such queries will always + * return at least one row, with the count. + * + * @param rs The ResultSet returned from the query execution. + * @param column The column index in which the return value may be found. + * @return The value of that column (usually, the count you were querying for). + * @exception java.sql.SQLException If there was no returned row, or there was a data type mismatch on the column. + */ + public static final int getReturnCountInt(ResultSet rs, int column) throws SQLException + { + if (!(rs.next())) + throw new SQLException("expected return count row, not present"); + return rs.getInt(column); + + } // end getReturnCountInt + +} // end class SQLUtils diff --git a/src/baseutil/com/silverwrist/util/StringUtils.java b/src/baseutil/com/silverwrist/util/StringUtils.java new file mode 100644 index 0000000..a5da575 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/StringUtils.java @@ -0,0 +1,349 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.*; +import org.apache.log4j.Logger; + +/** + * Common string utilities. Inherits from the org.apache.commons.lang.StringUtils + * class, so it contains everything that contains. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class StringUtils extends org.apache.commons.lang.StringUtils +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(StringUtils.class); + + private static final char[] HTML_ENCODE_CHARS = { '"', '&', '<', '>' }; + + private static final String VAR_START = "${"; + private static final String VAR_END = "}"; + + private static final Set TRUE_STRINGS; + private static final Set FALSE_STRINGS; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * StringUtils instances should NOT be constructed in standard programming. + * Instead, the class should be used as StringUtils.trim(" foo ");. + * This constructor is public to permit tools that require a JavaBean instance + * to operate. + */ + public StringUtils() + { + super(); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Performs HTML encoding of an arbitrary string. When a string is HTML encoded, the double-quote ("), + * ampersand (&), less-than (<), and greater-than (>) characters are transformed to their HTML + * entity equivalents; all other characters are left untouched. + * + * @param str The string to be HTML-encoded. May be null. + * @return The HTML-encoded equivalent of str. If str is + * null, returns null. + */ + public static final String encodeHTML(String str) + { + if (str==null) + return null; // safety feature + AnyCharMatcher nhc = new AnyCharMatcher(HTML_ENCODE_CHARS); + int ndx = nhc.get(str); + if (ndx<0) + return str; // trivial short-circuit case + StringBuffer buf = new StringBuffer(); + while (ndx>=0) + { // append the matched "head" and then the encoded character + if (ndx>0) + buf.append(str.substring(0,ndx)); + switch (str.charAt(ndx++)) + { + case '"': + buf.append("""); + break; + + case '&': + buf.append("&"); + break; + + case '<': + buf.append("<"); + break; + + case '>': + buf.append(">"); + break; + + } // end switch + + if (ndx==str.length()) + return buf.toString(); // munched the entire string - all done! + str = str.substring(ndx); + ndx = nhc.get(str); + + } // end while + + buf.append(str); // append the unmatched tail + return buf.toString(); + + } // end encodeHTML + + /** + * Translates a string into application/x-www-form-urlencoded format, using a UTF-8 encoding. + * + * @param s The string to be encoded. May be null. + * @return The translated string value, or null if null was passed in. + */ + public static final String encodeURL(String s) + { + try + { // the old URLEncoder.encode(str) method is deprecated as of JDK1.4, use the new one + return ((s==null) ? null : URLEncoder.encode(s,"UTF-8")); + + } // end try + catch (UnsupportedEncodingException e) + { // this should never happen, but we gotta catch it anyway + logger.fatal("WTF? encodeURL doesn't support UTF-8? You're crazy!"); + return null; + + } // end catch + + } // end encodeURL + + /** + * Returns true if the given string is a representation of a Boolean true value. + * Values that represent a valid Boolean true value include "true", "yes", "on", and "1". + * + * @param test The string to be tested. + * @return true if the string represents a Boolean true value, false if not. + */ + public static final boolean isBooleanTrue(String test) + { + if (test==null) + return false; + return TRUE_STRINGS.contains(test.trim().toLowerCase()); + + } // end isBooleanTrue + + /** + * Returns true if the given string is a representation of a Boolean false value. + * Values that represent a valid Boolean false value include "false", "no", "off", and "0". + * + * @param test The string to be tested. + * @return true if the string represents a Boolean false value, false if not. + */ + public static final boolean isBooleanFalse(String test) + { + if (test==null) + return false; + return FALSE_STRINGS.contains(test.trim().toLowerCase()); + + } // end isBooleanTrue + + /** + * Replaces variable substitutions in a string. Variable substitutions are strings of the form + * ${varname}. The varname names are looked up in the supplied + * Map, and the values of variables in that map are substituted.

+ * Only variable names that exist in the Map are replaced; other variable strings + * in the supplied string are left untouched. Variable substitution values may themselves contain + * variables; those variables are recursively replaced. (Caution: The code cannot + * detect variable substitutions that contain themselves, or two variables that contain each other. + * Avoid these situations.) + * + * @param base The string to be operated on. If this parameter is null, the + * method will return null. + * @param vars The mapping of variable name to value substitutions. If this parameter is + * null or an empty map, no substitutions will be performed on + * base. + * @return The base string with all variable substitutions made as detailed above. + */ + public static final String replaceAllVariables(String base, Map vars) + { + if ((base==null) || (vars==null) || vars.isEmpty()) + return base; // safety feature + + String work = base; + boolean did_replace = false; + boolean retest = true; + do + { // main loop for replacing all variables + did_replace = false; + Iterator it = vars.keySet().iterator(); + while (it.hasNext()) + { // variable start is there... + if (retest) + { // only perform this test on the first iteration and after we know we've replaced a variable + if (work.indexOf(VAR_START)<0) + return work; // no more variables in text - all done! + retest = false; + + } // end if + + // get variable name and see if it's present + String vname = it.next().toString(); + String var_full = VAR_START + vname + VAR_END; + if (work.indexOf(var_full)>=0) + { // OK, this variable is in place + work = replace(work,var_full,vars.get(vname).toString()); + did_replace = true; + retest = true; + + } // end if + + } // end while + + } while (did_replace); // end do + + return work; // all done! + + } // end replaceAllVariables + + /** + * Splits the provided text into a list, based on a given separator. The separator is not included in the + * returned String list. The maximum number of splits to perfom can be controlled. + * + * @param text The string to parse. + * @param separator Character used as the delimiter. + * @param limit The maximum number of elements to include in the list. A zero or negative value implies no limit. + * @return A list of parsed Strings. + */ + public static final List split1List(String text, char separator, int limit) + { + if (text==null) + return Collections.EMPTY_LIST; + if (limit<=0) + limit = Integer.MAX_VALUE; + ArrayList rc = new ArrayList(); + String work = text; + int p = work.indexOf(separator); + while ((work.length()>0) && (p>=0) && (--limit>0)) + { // add elements to the ArrayList + if (p==0) + rc.add(""); + else + rc.add(work.substring(0,p)); + work = work.substring(p+1); + p = work.indexOf(separator); + + } // end while + + rc.add(work); + rc.trimToSize(); + return rc; + + } // end split1list + + /** + * Splits the provided text into a list, based on a given separator. The separator is not included in the + * returned String list. + * + * @param text The string to parse. + * @param separator Character used as the delimiter. + * @return A list of parsed Strings. + */ + public static final List split1List(String text, char separator) + { + return split1List(text,separator,0); + + } // end split1list + + /** + * Splits the provided text into a list, based on a given separator. The separator is not included in the + * returned String array. The maximum number of splits to perfom can be controlled. + * + * @param text The string to parse. + * @param separator Character used as the delimiter. + * @param limit The maximum number of elements to include in the list. A zero or negative value implies no limit. + * @return An array of parsed Strings. + */ + public static final String[] split1(String text, char separator, int limit) + { + List tmp = split1List(text,separator,limit); + String[] rc = new String[tmp.size()]; + tmp.toArray(rc); + return rc; + + } // end split1 + + /** + * Splits the provided text into a list, based on a given separator. The separator is not included in the + * returned String array. + * + * @param text The string to parse. + * @param separator Character used as the delimiter. + * @return An array of parsed Strings. + */ + public static final String[] split1(String text, char separator) + { + return split1(text,separator,0); + + } // end split1 + + /*-------------------------------------------------------------------------------- + * Static initializer + *-------------------------------------------------------------------------------- + */ + + static + { // get the boolean values resource + ResourceBundle bv = ResourceBundle.getBundle("com.silverwrist.util.BooleanValues"); + + // Load the Boolean "true" values. + String[] values = split(bv.getString("values.true"),"|"); + HashSet tmp = new HashSet(); + for (int i=0; i. +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# ------------------------------------------------------------------------------------- +# This list of countries is taken from the ISO 3166 standard list of country names and +# 2-letter codes . When adding new +# entries to this file, make sure and add it in sorted order by country NAME! You can +# re-sort the country entries with "sort -t = -k 2 input > output", but then make sure +# the "XX=(unknown)" entry appears first! +XX=(unknown) +AF=Afghanistan +AL=Albania +DZ=Algeria +AS=American Samoa +AD=Andorra +AO=Angola +AI=Anguilla +AQ=Antarctica +AG=Antigua and Barbuda +AR=Argentina +AM=Armenia +AW=Aruba +AU=Australia +AT=Austria +AZ=Azerbaijan +BS=Bahamas +BH=Bahrain +BD=Bangladesh +BB=Barbados +BY=Belarus +BE=Belgium +BZ=Belize +BJ=Benin +BM=Bermuda +BT=Bhutan +BO=Bolivia +BA=Bosnia and Herzegovina +BW=Botswana +BV=Bouvet Island +BR=Brazil +IO=British Indian Ocean Territory +BN=Brunei Darussalam +BG=Bulgaria +BF=Burkina Faso +BI=Burundi +KH=Cambodia +CM=Cameroon +CA=Canada +CV=Cape Verde +KY=Cayman Islands +CF=Central African Republic +TD=Chad +CL=Chile +CN=China +CX=Chrismas Island +CC=Cocos (Keeling) Islands +CO=Colombia +KM=Comoros +CG=Congo +CD=Congo (Democratic Republic of) +CK=Cook Islands +CR=Costa Rica +CI=Cote D''Ivoire +HR=Croatia +CU=Cuba +CY=Cyprus +CZ=Czech Republic +DK=Denmark +DJ=Djibouti +DM=Dominica +DO=Dominican Republic +TP=East Timor +EC=Ecuador +EG=Egypt +SV=El Salvador +GQ=Equatorial Guinea +ER=Eritrea +EE=Estonia +ET=Ethiopia +FK=Falkland Islands (Malvinas) +FO=Faroe Islands +FJ=Fiji +FI=Finland +FR=France +GF=French Guiana +PF=French Polynesia +TF=French Southern Territories +GA=Gabon +GM=Gambia +GE=Georgia +DE=Germany +GH=Ghana +GI=Gibraltar +GR=Greece +GL=Greenland +GD=Grenada +GP=Guadeloupe +GU=Guam +GT=Guatemala +GN=Guinea +GW=Guinea-Bissau +GY=Guyana +HT=Haiti +HM=Heard Island and McDonald Islands +VA=Holy See (Vatican City State) +HN=Honduras +HK=Hong Kong +HU=Hungary +IS=Iceland +IN=India +ID=Indonesia +IR=Iran (Islamic Republic of) +IQ=Iraq +IE=Ireland +IL=Israel +IT=Italy +JM=Jamaica +JP=Japan +JO=Jordan +KZ=Kazakhstan +KE=Kenya +KI=Kiribati +KP=Korea (Democratic People's Republic of) +KR=Korea (Republic of) +KW=Kuwait +KG=Kyrgyzstan +LA=Lao People's Democratic Republic +LV=Latvia +LB=Lebanon +LS=Lesotho +LR=Liberia +LY=Libyan Arab Jamahirya +LI=Liechtenstein +LT=Lithuania +LU=Luxembourg +MO=Macau +MK=Macedonia (Former Yugoslav Republic of) +MG=Madagascar +MW=Malawi +MY=Malaysia +MV=Maldives +ML=Mali +MT=Malta +MH=Marshall Islands +MQ=Martinique +MR=Mauritania +MU=Mauritius +YT=Mayotte +MX=Mexico +FM=Micronesia (Federated States of) +MD=Moldova, Republic of +MC=Monaco +MN=Mongolia +MS=Montserrat +MA=Morocco +MZ=Mozambique +MM=Myanmar +NA=Namibia +NR=Nauru +NP=Nepal +NL=Netherlands +AN=Netherlands Antillies +NC=New Caledonia +NZ=New Zealand +NI=Nicaragua +NE=Niger +NG=Nigeria +NU=Niue +NF=Norfolk Island +MP=Northern Mariana Islands'), +NO=Norway +OM=Oman +PK=Pakistan +PW=Palau +PS=Palestinian Territory, Occupied +PA=Panama +PG=Papua New Guinea +PY=Paraguay +PE=Peru +PH=Phillipines +PN=Pitcairn +PL=Poland +PT=Portugal +PR=Puerto Rico +QA=Qatar +RE=Reunion +RO=Romania +RU=Russian Federation +RW=Rwanda +SH=Saint Helena +KN=Saint Kitts and Nevis +LC=Saint Lucia +PM=Saint Pierre and Miquelon +VC=Saint Vincent and The Grenadines +WS=Samoa +SM=San Marino +ST=Sao Tome and Principe +SA=Saudi Arabia +SN=Senegal +SC=Seychelles +SL=Sierra Leone +SG=Singapore +SK=Slovakia +SI=Slovenia +SB=Solomon Islands +SO=Somalia +ZA=South Africa +GS=South Georgia and the South Sandwich Islands +ES=Spain +LK=Sri Lanka +SD=Sudan +SR=Suriname +SJ=Svalbard and Jan Mayen +SZ=Swaziland +SE=Sweden +CH=Switzerland +SY=Syrian Arab Republic +TW=Taiwan (Province of China) +TJ=Tajikistan +TZ=Tanzania, United Republic of +TH=Thailand +TG=Togo +TK=Tokelau +TO=Tonga +TT=Trinidad and Tobago +TN=Tunisia +TR=Turkey +TM=Turkmenistan +TC=Turks and Caicos Islands +TV=Tuvalu +UG=Uganda +UA=Ukraine +AE=United Arab Emirates +GB=United Kingdom +US=United States +UM=United States Minor Outlying Islands +UY=Uruguay +UZ=Uzbekistan +VU=Vanatu +VE=Venezuela +VN=Viet Nam +VG=Virgin Islands (British) +VI=Virgin Islands (U.S.) +WF=Wallis and Futuna +EH=Western Sahara +YE=Yemen +YU=Yugoslavia +ZM=Zambia +ZW=Zimbabwe diff --git a/src/baseutil/com/silverwrist/util/image/ImageNormalizer.java b/src/baseutil/com/silverwrist/util/image/ImageNormalizer.java new file mode 100644 index 0000000..bc72afd --- /dev/null +++ b/src/baseutil/com/silverwrist/util/image/ImageNormalizer.java @@ -0,0 +1,272 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util.image; + +import java.awt.RenderingHints; +import java.awt.image.*; +import java.awt.image.renderable.ParameterBlock; +import java.io.*; +import java.util.*; +import javax.imageio.*; +import javax.imageio.stream.*; +import javax.media.jai.*; + +/** + * A class that performs "normalization" on an image to fit within a bounding box of a specified pixel + * size. "Normalized" images are scaled down proportionally to fit the bounding box, then centered over + * a black backdrop (so the image will be "letterboxed" if it has a larger H:V aspect ratio than the bounding + * box, or "pillarboxed" if it has a smaller H:V aspect ratio than the bounding box). + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class ImageNormalizer +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * ImageNormalizer instances should NOT be constructed in standard programming. + * Instead, the class should be used as ImageNormalizer.normalizeImage(...);. + * This constructor is public to permit tools that require a JavaBean instance + * to operate. + */ + public ImageNormalizer() + { + super(); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * "Normalizes" an image to fit within a bounding box of a specified pixel size. "Normalized" images are + * scaled down proportionally to fit the bounding box, then centered over a black backdrop (so the image + * will be "letterboxed" if it has a larger H:V aspect ratio than the bounding box, or "pillarboxed" if it + * has a smaller H:V aspect ratio than the bounding box). + * + * @param image_data Raw image data from the input, in any ImageIO-recognized format. + * @param width The width of the bounding box to use to normalize the image. + * @param height The height of the bounding box to use to normalize the image. + * @param output_type The desired MIME type for output (such as "image/jpeg"). + * @return The normalized image data as a byte array. + * @exception com.silverwrist.util.image.ImageNormalizerException An error occurred in the image data or + * the image transformation process. + * @see ImageNormalizerException + */ + public static byte[] normalizeImage(InputStream image_data, int width, int height, String output_type) + throws ImageNormalizerException + { + PlanarImage img1; // initial image + try + { // get an image input stream for the image + ImageInputStream iistm = ImageIO.createImageInputStream(image_data); + + // create the "ImageRead" operation to load the image; it will autodetect the + // image format and create an appropriate ImageReader + ParameterBlock pb = new ParameterBlock(); + pb.add(iistm); + pb.add(new Integer(0)); + pb.add(Boolean.FALSE); + pb.add(Boolean.FALSE); + RenderedOp rop = JAI.create("ImageRead",pb); + img1 = rop.getRendering(); + + } // end try + catch (IOException e) + { // try to create the ImageInputStream + throw new ImageNormalizerException("Unable to load image",e); + + } // end catch + catch (RuntimeException re) + { // unable to get the rendering here! + throw new ImageNormalizerException("Image data not a valid image format",re); + + } // end catch + + try + { // Compute the scaling factors required to get the image down to the appropriate size, then choose + // the smaller of the two to use as the final scaling factor. Note that we always scale DOWN, + // not UP. + Float scale_width = null, scale_height = null; + if (img1.getWidth()>width) + scale_width = new Float((float)width / (float)(img1.getWidth())); + if (img1.getHeight()>height) + scale_height = new Float((float)height / (float)(img1.getHeight())); + Float scale = null; + if (scale_width!=null) + { // we can scale by width, how about height? + if (scale_height!=null) + { // yes, height too...pick the smaller of the two + if (scale_width.floatValue()ImageNormalizer, which reads an image from one file, + * normalizes it, and writes it to a second file. + * + * @param args Command-line arguments. The first of these should be the name of the input file, and the + * second should be the name of the output file. + * @return (Exit code) 0 on success, 1 on error. + */ + public static void main(String[] args) + { + if (args.length<2) + { // make sure we have 2 arguments + System.out.println("Usage: ImageNormalizer input-file output-file"); + System.exit(1); + + } // end if + + try + { // very simple, very easy + FileInputStream instm = new FileInputStream(args[0]); + byte[] outdata = normalizeImage(instm,100,100,"image/jpeg"); + instm.close(); + FileOutputStream outstm = new FileOutputStream(args[1]); + outstm.write(outdata); + outstm.close(); + System.out.println(args[0] + " => " + args[1]); + + } // end try + catch (Exception e) + { // dump exception on error + e.printStackTrace(); + System.exit(1); + + } // end catch + + System.exit(0); + + } // end main + +} // end class ImageNormalizer diff --git a/src/baseutil/com/silverwrist/util/image/ImageNormalizerException.java b/src/baseutil/com/silverwrist/util/image/ImageNormalizerException.java new file mode 100644 index 0000000..3737256 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/image/ImageNormalizerException.java @@ -0,0 +1,77 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util.image; + +/** + * Indicates an error in the image normalization process. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + * @see com.silverwrist.util.image.ImageNormalizer#normalizeImage(java.io.InputStream,int,int,java.lang.String) + */ +public class ImageNormalizerException extends Exception +{ + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new ImageNormalizerException. + */ + public ImageNormalizerException() + { + super(); + + } // end constructor + + /** + * Constructs a new ImageNormalizerException. + * + * @param message Message for the exception. + */ + public ImageNormalizerException(String message) + { + super(message); + + } // end constructor + + /** + * Constructs a new ImageNormalizerException. + * + * @param t The exception to be wrapped by this one. + */ + public ImageNormalizerException(Throwable t) + { + super(t); + + } // end constructor + + /** + * Constructs a new ImageNormalizerException. + * + * @param message Message for the exception. + * @param t The exception to be wrapped by this one. + */ + public ImageNormalizerException(String message, Throwable t) + { + super(message,t); + + } // end constructor + +} // end class ImageNormalizerException diff --git a/src/baseutil/com/silverwrist/util/languages.properties b/src/baseutil/com/silverwrist/util/languages.properties new file mode 100644 index 0000000..f9d0e97 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/languages.properties @@ -0,0 +1,254 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# ------------------------------------------------------------------------------------- +# This list of languages is styled on RFC 1766, based on ISO 639 language code listings, +# from , and ISO 3166 country code listings, +# from . Language variants by country taken +# from WINNT.H header file, Microsoft Windows Platform SDK. Additional language codes +# (i- names and expanded zh- names) from IANA, . +# Changes to Indonesian, Hebrew, and Yiddish noted from Java 2 SDK documentation. +# When adding new entries to this file, make sure and add it in sorted order by language NAME! +# You can re-sort the language entries with "sort -t = -k 2 input > output", but then make sure +# the "i-default=(unknown)" entry appears first! +i-default=(unknown) +ab=Abkhazian +aa=Afar +af=Afrikaans +sq=Albanian +am=Amharic +i-ami=Amis +ar=Arabic +ar-DZ=Arabic (Algeria) +ar-BH=Arabic (Bahrain) +ar-EG=Arabic (Egypt) +ar-IQ=Arabic (Iraq) +ar-JO=Arabic (Jordan) +ar-KW=Arabic (Kuwait) +ar-LB=Arabic (Lebanon) +ar-LY=Arabic (Libya) +ar-MA=Arabic (Morocco) +ar-OM=Arabic (Oman) +ar-QA=Arabic (Qatar) +ar-SA=Arabic (Saudi Arabia) +ar-SY=Arabic (Syria) +ar-TN=Arabic (Tunisia) +ar-AE=Arabic (U.A.E.) +ar-YE=Arabic (Yemen) +hy=Armenian +as=Assamese +ay=Aymara +az=Azerbaijani +ba=Bashkir +eu=Basque +bn=Bengali +bh=Bihari +bi=Bislama +br=Breton +bg=Bulgarian +i-bnn=Bunun +my=Burmese +be=Byelorussian +km=Cambodian +ca=Catalan +zh=Chinese +zh-yue=Chinese (Cantonese) +zh-gan=Chinese (Gan) +zh-hakka=Chinese (Hakka) +zh-HK=Chinese (Hong Kong) +zh-xiang=Chinese (Hunan) +zh-guoyu=Chinese (Mandarin) +zh-wuu=Chinese (Shanghai) +zh-CN=Chinese (Simplified) +zh-SG=Chinese (Singapore) +zh-min=Chinese (Taiwanese) +zh-TW=Chinese (Traditional) +co=Corsican +hr=Croatian +cs=Czech +da=Danish +nl=Dutch +nl-BE=Dutch (Belgian) +dz=Dzongkha +en=English +en-AU=English (Australian) +en-BZ=English (Belize) +en-CA=English (Canadian) +en-caribbean=English (Caribbean) +en-IE=English (Irish) +en-JM=English (Jamaica) +en-NZ=English (New Zealand) +en-scouse=English (Scouse) +en-ZA=English (South Africa) +en-TT=English (Trinidad) +en-GB=English (United Kingdom) +en-US=English (United States) +eo=Esperanto +et=Estonian +fo=Faeroese +fj=Fiji +fi=Finnish +fr=French +fr-BE=French (Belgian) +fr-CA=French (Canadian) +fr-LU=French (Luxembourg) +fr-CH=French (Swiss) +fy=Frisian +gl=Gallegan +ka=Georgian +de=German +de-AT=German (Austria) +de-LI=German (Liechtenstein) +de-LU=German (Luxembourg) +de-CH=German (Swiss) +el=Greek +kl=Greenlandic +gn=Guarani +gu=Gujarati +i-hak=Hakka +ha=Hausa +he=Hebrew +hi=Hindi +hu=Hungarian +is=Icelandic +id=Indonesian +ia=Interlingua +ie=Interlingue +iu=Inuktitut +ik=Inupiak +ga=Irish +it=Italian +it-CH=Italian (Swiss) +ja=Japanese +jw=Javanese +kn=Kannada +ks=Kashmiri +km=Khmer +kk=Kazakh +rw=Kinyarwanda +ky=Kirghiz +rn=Kirundi +i-klingon=Klingon +ko=Korean +ko-johab=Korean (Johab) +ku=Kurdish +oc=Langue d'Oc +lo=Lao +la=Latin +lv=Latvian +ln=Lingala +lt=Lithuanian +i-lux=Luxembourgish +mk=Macedonian +mg=Malagasy +ms=Malay +ml=Maltese +mi=Maori +mr=Marathi +i-mingo=Mingo +mo=Moldavian +mn=Mongolian +na=Nauru +i-navajo=Navajo +ne=Nepali +no=Norwegian +no-bok=Norwegian (Bokmal) +no-nyn=Norwegian (Nynorsk) +oc=Occitan +or=Oriya +om=Oromo +i-pwn=Paiwan +pa=Panjabi +ps=Pashto +fa=Persian +pl=Polish +pt=Portuguese +pt-BR=Portuguese (Brazilian) +ps=Pushto +qu=Quechua +rm=Rhaeto-Romance +ro=Romanian +rn=Rundi +ru=Russian +sm=Samoan +sg=Sango +sa=Sanskrit +gd=Scots Gaelic +sr-cyrillic=Serbian (Cyrillic) +sr=Serbian (Latin) +sh=Serbo-Croatian +st=Sesotho +sn=Shona +sd=Sindhi +si=Singhalese +ss=Siswant +sk=Slovak +sl=Slovenian +so=Somali +st=Sotho +es-AR=Spanish (Argentina) +es-BO=Spanish (Bolivia) +es-ES=Spanish (Castilian) +es-CL=Spanish (Chile) +es-CO=Spanish (Colombia) +es-CR=Spanish (Costa Rica) +es-DO=Spanish (Dominican Republic) +es-EC=Spanish (Ecuador) +es-SV=Spanish (El Salvador) +es-GT=Spanish (Guatemala) +es-HN=Spanish (Honduras) +es-MX=Spanish (Mexican) +es=Spanish (Modern) +es-NI=Spanish (Nicaragua) +es-PA=Spanish (Panama) +es-PY=Spanish (Paraguay) +es-PE=Spanish (Peru) +es-PR=Spanish (Puerto Rico) +es-UY=Spanish (Uruguay) +es-VE=Spanish (Venezuela) +su=Sudanese +sw=Swahili +sv=Swedish +sv-FI=Swedish (Finland) +tl=Tagalog +tg=Tajik +ta=Tamil +i-tao=Tao +tt=Tatar +i-tay=Tayal +te=Tegulu +th=Thai +bo=Tibetan +ti=Tigrinya +to=Tonga +ts=Tsonga +i-tsu=Tsou +tn=Tswana +tr=Turkish +tk=Turkmen +tw=Twi +ug=Uighur +uk=Ukrainian +ur=Urdu +uz=Uzbek +vi=Vietnamese +vo=Volapuk +cy=Welsh +wo=Wolof +xh=Xhosa +yi=Yiddish +yo=Yoruba +za=Zhuang +zu=Zulu diff --git a/src/baseutil/com/silverwrist/util/xml/DOMElementHelper.java b/src/baseutil/com/silverwrist/util/xml/DOMElementHelper.java new file mode 100644 index 0000000..0a17517 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/xml/DOMElementHelper.java @@ -0,0 +1,489 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util.xml; + +import org.w3c.dom.*; +import com.silverwrist.util.StringUtils; + +/** + * A class which wraps around the DOM Element class, providing some + * additional functionality. Written to DOM Level 2. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + * @see org.w3c.dom.Element + */ +public final class DOMElementHelper +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private Element m_elt; // element housed by this helper class + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new DOMElementHelper to wrap a specific Element. + * + * @param elt The Element to be wrapped. + */ + public DOMElementHelper(Element elt) + { + m_elt = elt; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal static operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the content of all text nodes underneath a specified Element, concatenated + * together into a single string. + * + * @param e The Element to extract text from. + * @return The text content under this Element node. If the specified Element + * has no text nodes underneath it, returns null. + */ + private static final String getTextOfElement(Element e) + { + NodeList kids = e.getChildNodes(); + if (kids==null) + return null; // no text? + + StringBuffer b = null; + for (int i=0; iElement, expressed as an integer. + * + * @param e The Element to extract text from. + * @return An Integer object containing the value of the specified element. If + * the Element has no text, or if the text cannot be expressed as an integer, + * returns null. + */ + private static final Integer getIntegerFromElement(Element e) + { + try + { // extract the text and create an Integer around it + String s = getTextOfElement(e); + return ((s==null) ? null : new Integer(s.trim())); + + } // end try + catch (NumberFormatException nfe) + { // value cannot be parsed as an integer + return null; + + } // end catch + + } // end getIntegerFromElement + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the Element wrapped by this object. + * + * @return See above. + */ + public final Element getElement() + { + return m_elt; + + } // end getElement + + /** + * Searches for the first sub-element of the wrapped Element with the given name. + * + * @param name Name of the sub-element to search for. + * @return The first sub-element of the wrapped Element with the specified name. + * If the Element has no child Elements with the given name, + * the method returns null. + */ + public final Element getSubElement(String name) + { + NodeList kids = m_elt.getChildNodes(); + if (kids==null) + return null; // no children? + for (int i=0; iElement with the given name. + * + * @param namespaceURI Namespace URI for the sub-element to search for. + * @param name Name of the sub-element to search for. + * @return The first sub-element of the wrapped Element with the specified URI/name. + * If the Element has no child Elements with the given URI/name, + * the method returns null. + */ + public final Element getSubElementNS(String namespaceURI, String name) + { + NodeList kids = m_elt.getChildNodes(); + if (kids==null) + return null; // no children? + for (int i=0; iElement, concatenated + * together into a single string. + * + * @return The text content under the wrapped Element node. If the wrapped Element + * has not text nodes underneath it, returns null. + */ + public final String getElementText() + { + return getTextOfElement(m_elt); + + } // end getElementText + + /** + * Returns the value of the text of the wrapped Element, expressed as an integer. + * + * @return An Integer object containing the value of the wrapped element. If + * the Element has no text, or if the text cannot be expressed as an integer, + * returns null. + */ + public final Integer getElementInt() + { + return getIntegerFromElement(m_elt); + + } // end getElementInt + + /** + * Returns the content of all text nodes underneath the first sub-element of the wrapped + * Element, with the given name, concatenated together into a single string. + * + * @param name The name of the sub-element to search for. + * @return The text content under the specified sub-element of the wrapped Element node. + * If the wrapped Element does not have a sub-element with the given name, or + * that sub-element has no text nodes underneath it, returns null. + */ + public final String getSubElementText(String name) + { + Element se = getSubElement(name); + return ((se==null) ? null : getTextOfElement(se)); + + } // end getSubElementText + + /** + * Returns the content of all text nodes underneath the first sub-element of the wrapped + * Element, with the given name, concatenated together into a single string. + * + * @param namespaceURI Namespace URI for the sub-element to search for. + * @param name The name of the sub-element to search for. + * @return The text content under the specified sub-element of the wrapped Element node. + * If the wrapped Element does not have a sub-element with the given URI/name, or + * that sub-element has no text nodes underneath it, returns null. + */ + public final String getSubElementTextNS(String namespaceURI, String name) + { + Element se = getSubElementNS(namespaceURI,name); + return ((se==null) ? null : getTextOfElement(se)); + + } // end getSubElementTextNS + + /** + * Returns the value of the text underneath the first sub-element of the wrapped + * Element, with the given name, expressed as an integer. + * + * @param name The name of the sub-element to search for. + * @return An Integer object containing the value of the specified element. If + * the wrapped Element does not have a sub-element with the given name, or that + * sub-element has no text, or if the text cannot be expressed as an integer, returns + * null. + */ + public final Integer getSubElementInt(String name) + { + Element se = getSubElement(name); + return ((se==null) ? null : getIntegerFromElement(se)); + + } // end getSubElementInt + + /** + * Returns the value of the text underneath the first sub-element of the wrapped + * Element, with the given name, expressed as an integer. + * + * @param namespaceURI Namespace URI for the sub-element to search for. + * @param name The name of the sub-element to search for. + * @return An Integer object containing the value of the specified element. If + * the wrapped Element does not have a sub-element with the given URI/name, or that + * sub-element has no text, or if the text cannot be expressed as an integer, returns + * null. + */ + public final Integer getSubElementIntNS(String namespaceURI, String name) + { + Element se = getSubElementNS(namespaceURI,name); + return ((se==null) ? null : getIntegerFromElement(se)); + + } // end getSubElementIntNS + + /** + * Determines whether the wrapped Element has a sub-element with the given name. + * + * @param name Name of the sub-element to search for. + * @return true if the wrapped Element has a sub-element with the + * specified name, false if not. + */ + public final boolean hasChildElement(String name) + { + return (getSubElement(name)!=null); + + } // end hasChildElement + + /** + * Determines whether the wrapped Element has a sub-element with the given name. + * + * @param namespaceURI Namespace URI for the sub-element to search for. + * @param name Name of the sub-element to search for. + * @return true if the wrapped Element has a sub-element with the + * specified name, false if not. + */ + public final boolean hasChildElementNS(String namespaceURI, String name) + { + return (getSubElementNS(namespaceURI,name)!=null); + + } // end hasChildElementNS + + /** + * Determines whether the wrapped Element has an attribute with the given name. + * + * @param name Name of the attribute to search for. + * @return true if the wrapped Element has an attribute with the + * specified name, false if not. + */ + public final boolean hasAttribute(String name) + { + return m_elt.hasAttribute(name); + + } // end hasAttribute + + /** + * Determines whether the wrapped Element has an attribute with the given name. + * + * @param namespaceURI Namespace URI for the attribute to search for. + * @param name Name of the attribute to search for. + * @return true if the wrapped Element has an attribute with the + * specified URI/name, false if not. + */ + public final boolean hasAttributeNS(String namespaceURI, String name) + { + return m_elt.hasAttributeNS(namespaceURI,name); + + } // end hasAttributeNS + + /** + * Returns the value of a specified attribute of the wrapped Element, expressed as + * an integer. + * + * @param name Name of the attribute to search for. + * @return An Integer object containing the value of the specified attribute. If + * the wrapped Element has no such attribute, or if the attribute's value + * cannot be expressed as an integer, returns null. + */ + public final Integer getAttributeInt(String name) + { + String tmp = m_elt.getAttribute(name); + if (StringUtils.isEmpty(tmp)) + return null; + try + { // convert to an Integer + return new Integer(tmp.trim()); + + } // end try + catch (NumberFormatException nfe) + { // return a null value on error + return null; + + } // end catch + + } // end getAttributeInt + + /** + * Returns the value of a specified attribute of the wrapped Element, expressed as + * an integer. + * + * @param namespaceURI Namespace URI for the attribute to search for. + * @param name Name of the attribute to search for. + * @return An Integer object containing the value of the specified attribute. If + * the wrapped Element has no such attribute, or if the attribute's value + * cannot be expressed as an integer, returns null. + */ + public final Integer getAttributeIntNS(String namespaceURI, String name) + { + String tmp = m_elt.getAttributeNS(namespaceURI,name); + if (StringUtils.isEmpty(tmp)) + return null; + try + { // convert to an Integer + return new Integer(tmp.trim()); + + } // end try + catch (NumberFormatException nfe) + { // return a null value on error + return null; + + } // end catch + + } // end getAttributeInt + + /** + * Returns the value of a specified attribute of the wrapped Element, expressed as + * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to + * determine the state of the attribute value. + * + * @param name Name of the attribute to search for. + * @return Boolean.TRUE if the attribute value represents a "true" Boolean value; + * Boolean.FALSE if the attribute value represents a "false" Boolean value; null + * otherwise. + * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String) + * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String) + */ + public final Boolean getAttributeBoolean(String name) + { + String tmp = m_elt.getAttribute(name); + if (StringUtils.isBooleanTrue(tmp)) + return Boolean.TRUE; + else if (StringUtils.isBooleanFalse(tmp)) + return Boolean.FALSE; + else + return null; + + } // end getAttributeBoolean + + /** + * Returns the value of a specified attribute of the wrapped Element, expressed as + * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to + * determine the state of the attribute value. + * + * @param namespaceURI Namespace URI for the attribute to search for. + * @param name Name of the attribute to search for. + * @return Boolean.TRUE if the attribute value represents a "true" Boolean value; + * Boolean.FALSE if the attribute value represents a "false" Boolean value; null + * otherwise. + * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String) + * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String) + */ + public final Boolean getAttributeBooleanNS(String namespaceURI, String name) + { + String tmp = m_elt.getAttributeNS(namespaceURI,name); + if (StringUtils.isBooleanTrue(tmp)) + return Boolean.TRUE; + else if (StringUtils.isBooleanFalse(tmp)) + return Boolean.FALSE; + else + return null; + + } // end getAttributeBooleanNS + + /** + * Returns the value of a specified attribute of the wrapped Element, expressed as + * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to + * determine the state of the attribute value. + * + * @param name Name of the attribute to search for. + * @param default_val Default value for the attribute. + * @return Boolean.TRUE if the attribute value represents a "true" Boolean value; + * Boolean.FALSE if the attribute value represents a "false" Boolean value; the + * Boolean object corresponding to default_val if the attribute is missing; + * null otherwise. + * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String) + * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String) + */ + public final Boolean getAttributeBoolean(String name, boolean default_val) + { + if (this.hasAttribute(name)) + return this.getAttributeBoolean(name); + else + return (default_val ? Boolean.TRUE : Boolean.FALSE); + + } // end getAttributeBoolean + + /** + * Returns the value of a specified attribute of the wrapped Element, expressed as + * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to + * determine the state of the attribute value. + * + * @param namespaceURI Namespace URI for the attribute to search for. + * @param name Name of the attribute to search for. + * @param default_val Default value for the attribute. + * @return Boolean.TRUE if the attribute value represents a "true" Boolean value; + * Boolean.FALSE if the attribute value represents a "false" Boolean value; the + * Boolean object corresponding to default_val if the attribute is missing; + * null otherwise. + * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String) + * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String) + */ + public final Boolean getAttributeBooleanNS(String namespaceURI, String name, boolean default_val) + { + if (this.hasAttributeNS(namespaceURI,name)) + return this.getAttributeBooleanNS(namespaceURI,name); + else + return (default_val ? Boolean.TRUE : Boolean.FALSE); + + } // end getAttributeBooleanNS + +} // end class DOMElementHelper diff --git a/src/baseutil/com/silverwrist/util/xml/XMLLoadException.java b/src/baseutil/com/silverwrist/util/xml/XMLLoadException.java new file mode 100644 index 0000000..9dd7c32 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/xml/XMLLoadException.java @@ -0,0 +1,155 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util.xml; + +import org.w3c.dom.*; + +/** + * An exception type thrown by the {@link com.silverwrist.util.xml.XMLLoader XMLLoader} when it encounters + * a parse error, value error, or other erroneous condition. It contains a reference to the node in the DOM + * tree where the error occured, if such is possible to determine. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class XMLLoadException extends Exception +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private Node m_locus = null; // locus of the error + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new XMLLoadException. + */ + public XMLLoadException() + { + super(); + + } // end constructor + + /** + * Constructs a new XMLLoadException. + * + * @param msg The error message to be thrown. + */ + public XMLLoadException(String msg) + { + super(msg); + + } // end constructor + + /** + * Constructs a new XMLLoadException. + * + * @param inner The exception wrapped by this XMLLoadException. + */ + public XMLLoadException(Throwable inner) + { + super(inner); + + } // end constructor + + /** + * Constructs a new XMLLoadException. + * + * @param msg The error message to be thrown. + * @param inner The exception wrapped by this XMLLoadException. + */ + public XMLLoadException(String msg, Throwable inner) + { + super(msg,inner); + + } // end constructor + + /** + * Constructs a new XMLLoadException. + * + * @param locus The Node in the DOM tree where the error occurred. + */ + public XMLLoadException(Node locus) + { + super("Error in <" + locus.getNodeName() + "/> section of input"); + m_locus = locus; + + } // end constructor + + /** + * Constructs a new XMLLoadException. + * + * @param msg The error message to be thrown. + * @param locus The Node in the DOM tree where the error occurred. + */ + public XMLLoadException(String msg, Node locus) + { + super("Error in <" + locus.getNodeName() + "/> section of input - " + msg); + m_locus = locus; + + } // end constructor + + /** + * Constructs a new XMLLoadException. + * + * @param inner The exception wrapped by this XMLLoadException. + * @param locus The Node in the DOM tree where the error occurred. + */ + public XMLLoadException(Throwable inner, Node locus) + { + super("Error in <" + locus.getNodeName() + "/> section of input - " + inner.getMessage(),inner); + m_locus = locus; + + } // end constructor + + /** + * Constructs a new XMLLoadException. + * + * @param msg The error message to be thrown. + * @param inner The exception wrapped by this XMLLoadException. + * @param locus The Node in the DOM tree where the error occurred. + */ + public XMLLoadException(String msg, Throwable inner, Node locus) + { + super("Error in <" + locus.getNodeName() + "/> section of input - " + msg,inner); + m_locus = locus; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Returns the locus of the error contained in this exception. + * + * @return The Node that indicates wherre in the DOM tree the error occurred. + */ + public Node getLocus() + { + return m_locus; + + } // end getLocus + +} // end class XMLLoadException diff --git a/src/baseutil/com/silverwrist/util/xml/XMLLoader.java b/src/baseutil/com/silverwrist/util/xml/XMLLoader.java new file mode 100644 index 0000000..9886ba6 --- /dev/null +++ b/src/baseutil/com/silverwrist/util/xml/XMLLoader.java @@ -0,0 +1,824 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.util.xml; + +import java.io.*; +import java.util.*; +import javax.xml.parsers.*; +import org.apache.log4j.Logger; +import org.w3c.dom.*; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import com.silverwrist.util.StringUtils; + +/** + * A simple class which is commonly used for the loading of XML documents as configuration files. Various + * methods on this object load XML documents as DOM trees and extract portions of the information therein. + * It is implemented as a Singleton. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class XMLLoader +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(XMLLoader.class); + + private static XMLLoader self = null; // our singleton instance + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Internal constructor for XMLLoader. Only one instance is ever constructed. + */ + private XMLLoader() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Parses an XML document into a DOM tree. + * + * @param stm The XML document to be parsed, expressed as an InputStream. + * @param namespacing true if we want this XML document parsed in a namespace-aware fashion, + * false if not. + * @return The Document that results from parsing the XML document. + * @exception java.io.IOException If there was an I/O error reading from the XML document. + * @exception com.silverwrist.util.xml.XMLLoaderException If there was a parse error in the XML, or other error + * accessing the XML parser. + */ + public final Document load(InputStream stm, boolean namespacing) throws IOException, XMLLoadException + { + try + { // create a simple DOM parser by using the Java XML parsing API + DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); + fac.setNamespaceAware(namespacing); + fac.setValidating(false); + DocumentBuilder parser = fac.newDocumentBuilder(); + if (parser.isNamespaceAware()!=namespacing) + throw new XMLLoadException("XML parser namespacing parameter is not consistent"); + + // access the config file and parse it into our config data tree + return parser.parse(stm); + + } // end try + catch (FactoryConfigurationError fce) + { // if the document builder factory could not be created + throw new XMLLoadException("XML parser factory could not be created - " + fce.getMessage()); + + } // end catch + catch (ParserConfigurationException pce) + { // if the XML parser itself could not be created + throw new XMLLoadException("XML parser could not be created - " + pce.getMessage(),pce); + + } // end catch + catch (SAXException se) + { // if the XML parser choked on our document + if (se instanceof SAXParseException) + { // we have a detailed message - make a proper exception + SAXParseException spe = (SAXParseException)se; + throw new XMLLoadException("Error in XML data: " + spe.getMessage() + " at line " + + spe.getLineNumber() + ", column " + spe.getColumnNumber(),spe); + + } // end if + else + { // generic exception - just send up a simple error message + throw new XMLLoadException("Error in XML data - " + se.getMessage(),se); + + } // end else + + } // end catch + + } // end load + + /** + * Parses an XML document into a DOM tree. + * + * @param stm The XML document to be parsed, expressed as a File object. + * @param namespacing true if we want this XML document parsed in a namespace-aware fashion, + * false if not. + * @return The Document that results from parsing the XML document. + * @exception java.io.IOException If there was an I/O error reading from the XML document. + * @exception com.silverwrist.util.xml.XMLLoaderException If there was a parse error in the XML, or other error + * accessing the XML parser. + */ + public final Document load(File file, boolean namespacing) throws IOException, XMLLoadException + { + return this.load(new FileInputStream(file),namespacing); + + } // end load + + /** + * Gets the root element of a parsed XML DOM tree, and verifies that it matches a specific name. + * + * @param doc The document to get the root element of. + * @param expected_name The expected name of the root element. + * @return The root Element of the document, + * @exception com.silverwrist.util.XMLLoadException If the root element of the document does not match the + * expected_name. + */ + public final Element getRootElement(Document doc, String expected_name) throws XMLLoadException + { + Element rc = doc.getDocumentElement(); + if (rc.getTagName().equals(expected_name)) + return rc; // we're OK + throw new XMLLoadException("expected <" + expected_name + "/> root element",rc); + + } // end getRootElement + + /** + * Gets the root element of a parsed XML DOM tree, and verifies that it matches a specific name. + * + * @param doc The document to get the root element of. + * @param expected_namespace The expected namespace for the root element of the document. + * @param expected_name The expected name of the root element. + * @return The root Element of the document, + * @exception com.silverwrist.util.XMLLoadException If the root element of the document does not match the + * expected_namespace and expected_name. + */ + public final Element getRootElementNS(Document doc, String expected_namespace, + String expected_name) throws XMLLoadException + { + Element rc = doc.getDocumentElement(); + if (rc.getNamespaceURI().equals(expected_namespace) && rc.getTagName().equals(expected_name)) + return rc; // we're OK + throw new XMLLoadException("expected <" + expected_namespace + ":" + expected_name + "/> root element",rc); + + } // end getRootElementNS + + /** + * Gets the text contained in an Element wrapped in a + * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}. + * + * @param h The DOMElementHelper to extract the text from. + * @return The text contained in the element. + * @exception com.silverwrist.util.XMLLoadException If there is no text contained in the element. + */ + public final String getText(DOMElementHelper h) throws XMLLoadException + { + String rc = h.getElementText(); + if (rc!=null) + return rc; // we're OK + throw new XMLLoadException("no text found under element",h.getElement()); + + } // end getText + + /** + * Gets the text contained in an Element. + * + * @param elt The Element to extract the text from. + * @return The text contained in the element. + * @exception com.silverwrist.util.XMLLoadException If there is no text contained in the element. + */ + public final String getText(Element elt) throws XMLLoadException + { + return getText(new DOMElementHelper(elt)); + + } // end getText + + /** + * Gets the text contained in a named sub-element of an Element wrapped in a + * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}. + * + * @param h The DOMElementHelper to extract the text from. + * @param elt_name The name of the sub-element to look for text in. + * @return The text contained in the sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text + * contained in the sub-element. + */ + public final String getSubElementText(DOMElementHelper h, String elt_name) throws XMLLoadException + { + String rc = h.getSubElementText(elt_name); + if (rc!=null) + return rc; // we're OK + throw new XMLLoadException("sublement <" + elt_name + "/> not found",h.getElement()); + + } // end getSubElementText + + /** + * Gets the text contained in a named sub-element of an Element. + * + * @param elt The Element to extract the text from. + * @param subelt_name The name of the sub-element to look for text in. + * @return The text contained in the sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text + * contained in the sub-element. + */ + public final String getSubElementText(Element elt, String subelt_name) throws XMLLoadException + { + return getSubElementText(new DOMElementHelper(elt),subelt_name); + + } // end getSubElementText + + /** + * Gets the text contained in a named sub-element of an Element wrapped in a + * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}. + * + * @param h The DOMElementHelper to extract the text from. + * @param namespace The namespace URI of the sub-element to look for text in. + * @param elt_name The name of the sub-element to look for text in. + * @return The text contained in the sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text + * contained in the sub-element. + */ + public final String getSubElementTextNS(DOMElementHelper h, String namespace, String elt_name) + throws XMLLoadException + { + String rc = h.getSubElementTextNS(namespace,elt_name); + if (rc!=null) + return rc; // we're OK + throw new XMLLoadException("sublement <" + namespace + ":" + elt_name + "/> not found",h.getElement()); + + } // end getSubElementTextNS + + /** + * Gets the text contained in a named sub-element of an Element. + * + * @param elt The Element to extract the text from. + * @param namespace The namespace URI of the sub-element to look for text in. + * @param subelt_name The name of the sub-element to look for text in. + * @return The text contained in the sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text + * contained in the sub-element. + */ + public final String getSubElementTextNS(Element elt, String namespace, String subelt_name) + throws XMLLoadException + { + return getSubElementTextNS(new DOMElementHelper(elt),namespace,subelt_name); + + } // end getSubElementTextNS + + /** + * Gets a named sub-element of an Element wrapped in a + * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}. + * + * @param h The DOMElementHelper to extract the sub-element from. + * @param name The name of the sub-element to look for. + * @return The sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found. + */ + public final Element getSubElement(DOMElementHelper h, String name) throws XMLLoadException + { + Element rc = h.getSubElement(name); + if (rc!=null) + return rc; // we're OK + throw new XMLLoadException("sublement <" + name + "/> not found",h.getElement()); + + } // end getSubElement + + /** + * Gets a named sub-element of an Element. + * + * @param sect The Element to extract the sub-element from. + * @param name The name of the sub-element to look for. + * @return The sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found. + */ + public final Element getSubElement(Element sect, String name) throws XMLLoadException + { + return getSubElement(new DOMElementHelper(sect),name); + + } // end getSubElement + + /** + * Gets a named sub-element of an Element wrapped in a + * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}. + * + * @param h The DOMElementHelper to extract the sub-element from. + * @param namespace The namespace URI of the sub-element to look for. + * @param name The name of the sub-element to look for. + * @return The sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found. + */ + public final Element getSubElementNS(DOMElementHelper h, String namespace, String name) + throws XMLLoadException + { + Element rc = h.getSubElementNS(namespace,name); + if (rc!=null) + return rc; // we're OK + throw new XMLLoadException("sublement <" + namespace + ":" + name + "/> not found",h.getElement()); + + } // end getSubElementNS + + /** + * Gets a named sub-element of an Element. + * + * @param sect The Element to extract the sub-element from. + * @param namespace The namespace URI of the sub-element to look for. + * @param name The name of the sub-element to look for. + * @return The sub-element. + * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found. + */ + public final Element getSubElementNS(Element sect, String namespace, String name) throws XMLLoadException + { + return getSubElementNS(new DOMElementHelper(sect),namespace,name); + + } // end getSubElementNS + + /** + * Returns all sub-elements of an Element element that have a specific name. + * + * @param sect The Element to extract the sub-elements from. + * @param name The name of the sub-elements to look for. + * @return A java.util.List containing all the sub-elements of the given Element with + * the specified name. If there are no matching sub-elements, an empty list is returned. + */ + public final List getMatchingSubElements(Element sect, String name) + { + ArrayList rc = new ArrayList(); + NodeList nl = sect.getChildNodes(); + for (int i=0; iElement element that have a specific name. + * + * @param sect The Element to extract the sub-elements from. + * @param namespace The namespace URI of the sub-elements to look for. + * @param name The name of the sub-elements to look for. + * @return A java.util.List containing all the sub-elements of the given Element with + * the specified namespace and name. If there are no matching sub-elements, an empty list is returned. + */ + public final List getMatchingSubElementsNS(Element sect, String namespace, String name) + { + ArrayList rc = new ArrayList(); + NodeList nl = sect.getChildNodes(); + for (int i=0; iNode to test the name of. + * @param name The name to test the node against. + * @param enclosing_sect The Element that contains this node as a child, used in constructing + * the exception if the test fails. + * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match. + */ + public final void verifyNodeName(Node n, String name, Element enclosing_sect) throws XMLLoadException + { + if (n.getNodeName().equals(name)) + return; + throw new XMLLoadException("node <" + n.getNodeName() + "/> should be <" + name + "/>",enclosing_sect); + + } // end verifyNodeName + + /** + * Checks to make sure that the name of a given node is what we expect, and throws an + * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't. + * + * @param n The Node to test the name of. + * @param name The name to test the node against. + * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match. + */ + public final void verifyNodeName(Node n, String name) throws XMLLoadException + { + verifyNodeName(n,name,(Element)(n.getParentNode())); + + } // end verifyNodeName + + /** + * Checks to make sure that the name of a given node is what we expect, and throws an + * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't. + * + * @param n The Node to test the name of. + * @param namespace The namespace URI to test the node against. + * @param name The name to test the node against. + * @param enclosing_sect The Element that contains this node as a child, used in constructing + * the exception if the test fails. + * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match. + */ + public final void verifyNodeNameNS(Node n, String namespace, String name, Element enclosing_sect) + throws XMLLoadException + { + if (n.getNamespaceURI().equals(namespace) && n.getNodeName().equals(name)) + return; + throw new XMLLoadException("node <" + n.getNamespaceURI() + ":" + n.getNodeName() + "/> should be <" + + namespace + ":" + name + "/>",enclosing_sect); + + } // end verifyNodeNameNS + + /** + * Checks to make sure that the name of a given node is what we expect, and throws an + * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't. + * + * @param n The Node to test the name of. + * @param namespace The namespace URI to test the node against. + * @param name The name to test the node against. + * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match. + */ + public final void verifyNodeNameNS(Node n, String namespace, String name) throws XMLLoadException + { + verifyNodeNameNS(n,namespace,name,(Element)(n.getParentNode())); + + } // end verifyNodeNameNS + + /** + * Checks to make sure that the name of a given tag element is what we expect, and throws an + * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't. + * + * @param tag The Element to test the name of. + * @param name The name to test the element against. + * @exception com.silverwrist.util.xml.XMLLoadException If the name of the element does not match. + */ + public final void verifyTagName(Element tag, String name) throws XMLLoadException + { + if (tag.getTagName().equals(name)) + return; + throw new XMLLoadException("expected <" + name + "/> element",tag); + + } // end verifyTagName + + /** + * Checks to make sure that the name of a given tag element is what we expect, and throws an + * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't. + * + * @param tag The Element to test the name of. + * @param namespace The namespace URI to test the element against. + * @param name The name to test the element against. + * @exception com.silverwrist.util.xml.XMLLoadException If the name of the element does not match. + */ + public final void verifyTagNameNS(Element tag, String namespace, String name) throws XMLLoadException + { + if (tag.getNamespaceURI().equals(namespace) && tag.getTagName().equals(name)) + return; + throw new XMLLoadException("expected <" + namespace + ":" + name + "/> element",tag); + + } // end verifyTagNameNS + + /** + * Gets the value of an attribute on an Element. + * + * @param elt The Element to retrieve the attribute from. + * @param attr_name The name of the attribute to retrieve. + * @return The attribute value. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element. + */ + public final String getAttribute(Element elt, String attr_name) throws XMLLoadException + { + String rc = elt.getAttribute(attr_name); + if (!(StringUtils.isEmpty(rc))) + return rc; + throw new XMLLoadException("no " + attr_name + "= attribute found",elt); + + } // end getAttribute + + /** + * Gets the value of an attribute on an Element. + * + * @param elt The Element to retrieve the attribute from. + * @param attr_name The name of the attribute to retrieve. + * @param default_val The default value of the attribute. + * @return The attribute value, or the value of default_val if the attribute didn't exist. + */ + public final String getAttribute(Element elt, String attr_name, String default_val) + { + String rc = elt.getAttribute(attr_name); + return (StringUtils.isEmpty(rc) ? default_val : rc); + + } // end getAttribute + + /** + * Gets the value of an attribute on an Element. + * + * @param elt The Element to retrieve the attribute from. + * @param namespace The namespace URI of the attribute to retrieve. + * @param attr_name The name of the attribute to retrieve. + * @return The attribute value. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element. + */ + public final String getAttributeNS(Element elt, String namespace, String attr_name) throws XMLLoadException + { + String rc = elt.getAttributeNS(namespace,attr_name); + if (!(StringUtils.isEmpty(rc))) + return rc; + throw new XMLLoadException("no " + namespace + ":" + attr_name + "= attribute found",elt); + + } // end getAttributeNS + + /** + * Gets the value of an attribute on an Element. + * + * @param elt The Element to retrieve the attribute from. + * @param namespace The namespace URI of the attribute to retrieve. + * @param attr_name The name of the attribute to retrieve. + * @param default_val The default value of the attribute. + * @return The attribute value, or the value of default_val if the attribute didn't exist. + */ + public final String getAttributeNS(Element elt, String namespace, String attr_name, String default_val) + { + String rc = elt.getAttributeNS(namespace,attr_name); + return (StringUtils.isEmpty(rc) ? default_val : rc); + + } // end getAttributeNS + + /** + * Gets the value of an attribute on an Element, expressed as an integer. + * + * @param elt The Element to retrieve the attribute from. + * @param attr_name The name of the attribute to retrieve. + * @return The attribute value. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element, or + * it could not be parsed as an integer. + */ + public final int getAttributeInt(Element elt, String attr_name) throws XMLLoadException + { + String tmp = elt.getAttribute(attr_name); + if (StringUtils.isEmpty(tmp)) + { // the attribute is not present + throw new XMLLoadException("no " + attr_name + "= attribute found",elt); + + } // end if + + try + { // parse out the integer value + return Integer.parseInt(tmp.trim()); + + } // end try + catch (NumberFormatException nfe) + { // but it's not a valid integer - throw something else! + throw new XMLLoadException(attr_name + "= attribute value is not a valid integer",elt); + + } // end catch + + } // end getAttributeInt + + /** + * Gets the value of an attribute on an Element, expressed as an integer. + * + * @param elt The Element to retrieve the attribute from. + * @param attr_name The name of the attribute to retrieve. + * @param default_val The default value of the attribute. + * @return The attribute value, or the value of default_val if the attribute didn't exist. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as an integer. + */ + public final int getAttributeInt(Element elt, String attr_name, int default_val) throws XMLLoadException + { + String tmp = elt.getAttribute(attr_name); + if (StringUtils.isEmpty(tmp)) + return default_val; // the attribute is not present + + try + { // parse out the integer value + return Integer.parseInt(tmp.trim()); + + } // end try + catch (NumberFormatException nfe) + { // but it's not a valid integer - throw something else! + throw new XMLLoadException(attr_name + "= attribute value is not a valid integer",elt); + + } // end catch + + } // end getAttributeInt + + /** + * Gets the value of an attribute on an Element, expressed as an integer. + * + * @param elt The Element to retrieve the attribute from. + * @param namespace The namespace URI of the attribute to retrieve. + * @param attr_name The name of the attribute to retrieve. + * @return The attribute value. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element, or + * it could not be parsed as an integer. + */ + public final int getAttributeIntNS(Element elt, String namespace, String attr_name) throws XMLLoadException + { + String tmp = elt.getAttributeNS(namespace,attr_name); + if (StringUtils.isEmpty(tmp)) + { // the attribute is not present + throw new XMLLoadException("no " + namespace + ":" + attr_name + "= attribute found",elt); + + } // end if + + try + { // parse out the integer value + return Integer.parseInt(tmp.trim()); + + } // end try + catch (NumberFormatException nfe) + { // but it's not a valid integer - throw something else! + throw new XMLLoadException(namespace + ":" + attr_name + "= attribute value is not a valid integer",elt); + + } // end catch + + } // end getAttributeIntNS + + /** + * Gets the value of an attribute on an Element, expressed as an integer. + * + * @param elt The Element to retrieve the attribute from. + * @param namespace The namespace URI of the attribute to retrieve. + * @param attr_name The name of the attribute to retrieve. + * @param default_val The default value of the attribute. + * @return The attribute value, or the value of default_val if the attribute didn't exist. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as an integer. + */ + public final int getAttributeIntNS(Element elt, String namespace, String attr_name, int default_val) + throws XMLLoadException + { + String tmp = elt.getAttributeNS(namespace,attr_name); + if (StringUtils.isEmpty(tmp)) + return default_val; // the attribute is not present + + try + { // parse out the integer value + return Integer.parseInt(tmp.trim()); + + } // end try + catch (NumberFormatException nfe) + { // but it's not a valid integer - throw something else! + throw new XMLLoadException(namespace + ":" + attr_name + "= attribute value is not a valid integer",elt); + + } // end catch + + } // end getAttributeIntNS + + /** + * Gets the value of an attribute on an Element, expressed as a Boolean. Uses the Boolean string + * methods on {@link com.silverwrist.util.StringUtils StringUtils} to determine the state of the attribute value. + * + * @param elt The Element to retrieve the attribute from. + * @param attr_name The name of the attribute to retrieve. + * @return The attribute value. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element, or + * it could not be parsed as a Boolean. + * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String) + * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String) + */ + public final boolean getAttributeBoolean(Element elt, String attr_name) + throws XMLLoadException + { + String tmp = elt.getAttribute(attr_name); + if (StringUtils.isEmpty(tmp)) + throw new XMLLoadException("no " + attr_name + "= attribute found",elt); + if (StringUtils.isBooleanTrue(tmp)) + return true; + if (StringUtils.isBooleanFalse(tmp)) + return false; + throw new XMLLoadException(attr_name + "= attribute value is not a valid Boolean",elt); + + } // end getAttributeBoolean + + /** + * Gets the value of an attribute on an Element, expressed as a Boolean. Uses the Boolean string + * methods on {@link com.silverwrist.util.StringUtils StringUtils} to determine the state of the attribute value. + * + * @param elt The Element to retrieve the attribute from. + * @param attr_name The name of the attribute to retrieve. + * @param default_val The default value of the attribute. + * @return The attribute value, or the value of default_val if the attribute didn't exist. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as a Boolean. + * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String) + * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String) + */ + public final boolean getAttributeBoolean(Element elt, String attr_name, boolean default_val) + throws XMLLoadException + { + String tmp = elt.getAttribute(attr_name); + if (StringUtils.isEmpty(tmp)) + return default_val; + if (StringUtils.isBooleanTrue(tmp)) + return true; + if (StringUtils.isBooleanFalse(tmp)) + return false; + throw new XMLLoadException(attr_name + "= attribute value is not a valid Boolean",elt); + + } // end getAttributeBoolean + + /** + * Gets the value of an attribute on an Element, expressed as a Boolean. Uses the Boolean string + * methods on {@link com.silverwrist.util.StringUtils StringUtils} to determine the state of the attribute value. + * + * @param elt The Element to retrieve the attribute from. + * @param namespace The namespace URI of the attribute to retrieve. + * @param attr_name The name of the attribute to retrieve. + * @param default_val The default value of the attribute. + * @return The attribute value, or the value of default_val if the attribute didn't exist. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as a Boolean. + * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String) + * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String) + */ + public final boolean getAttributeBooleanNS(Element elt, String namespace, String attr_name, + boolean default_val) throws XMLLoadException + { + String tmp = elt.getAttributeNS(namespace,attr_name); + if (StringUtils.isEmpty(tmp)) + return default_val; + if (StringUtils.isBooleanTrue(tmp)) + return true; + if (StringUtils.isBooleanFalse(tmp)) + return false; + throw new XMLLoadException(namespace + ":" + attr_name + "= attribute value is not a valid Boolean",elt); + + } // end getAttributeBooleanNS + + /** + * Checks to make sure that the value of a given attribute is what we expect, and throws an + * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't. + * + * @param elt The Element to test the attribute of. + * @param attr_name The name of the attribute to test. + * @param attr_value The value to test the attribute against. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute does not exist, or its value does not match. + */ + public final void verifyAttributeValue(Element elt, String attr_name, String attr_value) + throws XMLLoadException + { + String tmp = this.getAttribute(elt,attr_name); + if (!(tmp.equals(attr_value))) + throw new XMLLoadException("attribute " + attr_name + "= should be '" + attr_value + "', but is '" + + tmp + "'",elt); + + } // end verifyAttributeValue + + /** + * Checks to make sure that the value of a given attribute is what we expect, and throws an + * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't. + * + * @param elt The Element to test the attribute of. + * @param namespace The namespace URI of the attribute to test. + * @param attr_name The name of the attribute to test. + * @param attr_value The value to test the attribute against. + * @exception com.silverwrist.util.xml.XMLLoadException If the attribute does not exist, or its value does not match. + */ + public final void verifyAttributeValueNS(Element elt, String namespace, String attr_name, String attr_value) + throws XMLLoadException + { + String tmp = this.getAttributeNS(elt,namespace,attr_name); + if (!(tmp.equals(attr_value))) + throw new XMLLoadException("attribute " + namespace + ":" + attr_name + "= should be '" + attr_value + + "', but is '" + tmp + "'",elt); + + } // end verifyAttributeValueNS + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + /** + * Gets the Singleton instance of the XMLLoader object. + * + * @return The Singleton instance of the XMLLoader object. + */ + public static final synchronized XMLLoader get() + { + if (self==null) + self = new XMLLoader(); + return self; + + } // end get + +} // end class XMLLoader diff --git a/src/dynamo-framework/com/silverwrist/dynamo/BrowserFlag.java b/src/dynamo-framework/com/silverwrist/dynamo/BrowserFlag.java new file mode 100644 index 0000000..691856f --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/BrowserFlag.java @@ -0,0 +1,189 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +import java.util.*; +import org.apache.commons.lang.enum.*; + +/** + * A type-safe enumerated type that indicates the capabilities of a browser. These objects are returned + * in a set by the {@link com.silverwrist.dynamo.iface.BrowserData#getBrowserFlags() BrowserData.getBrowserFlags()} + * method. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public final class BrowserFlag extends Enum +{ + /*-------------------------------------------------------------------------------- + * The actual enumeration values + *-------------------------------------------------------------------------------- + */ + + /** + * Indicates that the browser supports frames (the <FRAMESET> and <FRAME> tags). + */ + public static final BrowserFlag FRAMES = new BrowserFlag("FRAMES"); + + /** + * Indicates that the browser supports in-line frames (the <IFRAME> tag). + */ + public static final BrowserFlag IFRAMES = new BrowserFlag("IFRAMES"); + + /** + * Indicates that the browser supports tables. + */ + public static final BrowserFlag TABLES = new BrowserFlag("TABLES"); + + /** + * Indicates that the browser supports cookies. + */ + public static final BrowserFlag COOKIES = new BrowserFlag("COOKIES"); + + /** + * Indicates that the browser supports background sounds (the <BGSOUND> tag). + */ + public static final BrowserFlag BACKGROUND_SOUNDS = new BrowserFlag("BACKGROUND_SOUNDS"); + + /** + * Indicates that the browser supports client-side scripting using Visual Basic Script. + */ + public static final BrowserFlag VBSCRIPT = new BrowserFlag("VBSCRIPT"); + + /** + * Indicates that the browser supports client-side scripting using JavaScript (JScript). + */ + public static final BrowserFlag JAVASCRIPT = new BrowserFlag("JAVASCRIPT"); + + /** + * Indicates that the browser supports client-side Java applets. + */ + public static final BrowserFlag JAVA_APPLETS = new BrowserFlag("JAVA_APPLETS"); + + /** + * Indicates that the browser supports client-side ActiveX controls. + */ + public static final BrowserFlag ACTIVEX_CONTROLS = new BrowserFlag("ACTIVEX_CONTROLS"); + + /** + * Indicates that the browser supports CDF. + */ + public static final BrowserFlag CDF = new BrowserFlag("CDF"); + + /** + * Indicates that this browser is an America Online client. + */ + public static final BrowserFlag AOL = new BrowserFlag("AOL"); + + /** + * Indicates that this browser is a beta version. + */ + public static final BrowserFlag BETA = new BrowserFlag("BETA"); + + /** + * Indicates that the browser is running on a 16-bit Windows operating system. + */ + public static final BrowserFlag WIN16 = new BrowserFlag("WIN16"); + + /** + * Indicates that this browser is not a browser at all, but a "crawler," which may be used to index the + * site's content by a search engine, or for other (nefarious) purposes. + */ + public static final BrowserFlag CRAWLER = new BrowserFlag("CRAWLER"); + + /** + * Indicates that this browser is not a browser at all, but a "stripper," which is copying the HTML of the + * site to another location. This may or may not be benign. + */ + public static final BrowserFlag STRIPPER = new BrowserFlag("STRIPPER"); + + /** + * Indicates that the browser is a cellphone or other handheld device, possibly supporting + * Wireless Access Protocol (WAP). + */ + public static final BrowserFlag WAP = new BrowserFlag("WAP"); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Internal constructor which creates a new element of this enumerated type. + * + * @param name The name of the BrowserFlag to be created. + */ + private BrowserFlag(String name) + { + super(name); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Standard static method implementations + *-------------------------------------------------------------------------------- + */ + + /** + * Gets a BrowserFlag by name. + * + * @param name The name of the BrowserFlag to get; may be null. + * @return The BrowserFlag object, or null if the BrowserFlag does not exist. + */ + public static BrowserFlag getEnum(String name) + { + return (BrowserFlag)getEnum(BrowserFlag.class,name); + + } // end getEnum + + /** + * Gets the Map of BrowserFlag objects by name. + * + * @return The BrowserFlag object Map. + */ + public static Map getEnumMap() + { + return getEnumMap(BrowserFlag.class); + + } // end getEnumMap + + /** + * Gets the List of BrowserFlag objects, in the order in which the objects are listed + * in the code above. + * + * @return The BrowserFlag object List. + */ + public static List getEnumList() + { + return getEnumList(BrowserFlag.class); + + } // end getEnumList + + /** + * Gets an iterator over all BrowserFlag objects, in the order in which the objects are listed + * in the code above. + * + * @return The BrowserFlag object iterator. + */ + public static Iterator iterator() + { + return iterator(BrowserFlag.class); + + } // end iterator + +} // end class BrowserFlag diff --git a/src/dynamo-framework/com/silverwrist/dynamo/DynamoVersion.java b/src/dynamo-framework/com/silverwrist/dynamo/DynamoVersion.java new file mode 100644 index 0000000..b5a3744 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/DynamoVersion.java @@ -0,0 +1,33 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +/** + * Class that holds the Dynamo version number. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public final class DynamoVersion +{ + /** + * The current version number of the Dynamo framework. + */ + public static final String VERSION = "0.05"; + +} // end class DynamoVersion diff --git a/src/dynamo-framework/com/silverwrist/dynamo/HttpStatusCode.java b/src/dynamo-framework/com/silverwrist/dynamo/HttpStatusCode.java new file mode 100644 index 0000000..68d09cd --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/HttpStatusCode.java @@ -0,0 +1,482 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +import java.util.*; +import org.apache.commons.lang.enum.*; +import javax.servlet.http.HttpServletResponse; + +/** + * A type-safe enumerated type that encapsulates the HTTP status codes. We use an enumerated type here + * so that it can be extended to support additional status codes (the ones defined, say, by WebDAV) + * without affecting HttpServletResponse. + *

The descriptions of the status codes are taken from the HTTP 1.1 Specification, + * RFC 2616. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class HttpStatusCode extends ValuedEnum +{ + /*-------------------------------------------------------------------------------- + * The actual enumeration values + *-------------------------------------------------------------------------------- + */ + + // N.B.: We copy the status codes here to allow extending them independent of the codes + // listed in HttpServletResponse, but we point to the originals in HttpServletResponse + // to maintain compatibility. + + /** + * 100 Continue. The client SHOULD continue with its request. This interim response is used to + * inform the client that the initial part of the request has been received and has not yet been rejected + * by the server. The client SHOULD continue by sending the remainder of the request or, if the request + * has already been completed, ignore this response. The server MUST send a final response after the + * request has been completed. + */ + public static final HttpStatusCode I_CONTINUE = + new HttpStatusCode("I_CONTINUE",HttpServletResponse.SC_CONTINUE); + + /** + * 101 Switching Protocols. The server understands and is willing to comply with the client's request, + * via the Upgrade message header field, for a change in the application protocol being used on this connection. + * The server will switch protocols to those defined by the response's Upgrade header field immediately after + * the empty line which terminates the 101 response. + */ + public static final HttpStatusCode I_SWITCH = + new HttpStatusCode("I_SWITCH",HttpServletResponse.SC_SWITCHING_PROTOCOLS); + + /** + * 200 OK. The request has succeeded. The information returned with the response is dependent on + * the method used in the request. (Default status code) + */ + public static final HttpStatusCode S_OK = + new HttpStatusCode("S_OK",HttpServletResponse.SC_OK); + + /** + * 201 Created. The request has been fulfilled and resulted in a new resource being created. The + * newly created resource can be referenced by the URI(s) returned in the entity of the response, with + * the most specific URI for the resource given by a Location header field. The response SHOULD include + * an entity containing a list of resource characteristics and location(s) from which the user or user + * agent can choose the one most appropriate. The entity format is specified by the media type given in + * the Content-Type header field. The origin server MUST create the resource before returning the 201 + * status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 + * (Accepted) response instead. + */ + public static final HttpStatusCode S_CREATED = + new HttpStatusCode("S_CREATED",HttpServletResponse.SC_CREATED); + + /** + * 202 Accepted. The request has been accepted for processing, but the processing has not been + * completed. The request might or might not eventually be acted upon, as it might be disallowed when + * processing actually takes place. + */ + public static final HttpStatusCode S_ACCEPTED = + new HttpStatusCode("S_ACCEPTED",HttpServletResponse.SC_ACCEPTED); + + /** + * 203 Non-Authoritative Information. The returned metainformation in the entity-header is not the + * definitive set as available from the origin server, but is gathered from a local or a third-party copy. + * The set presented MAY be a subset or superset of the original version. For example, including local + * annotation information about the resource might result in a superset of the metainformation known by + * the origin server. Use of this response code is not required and is only appropriate when the response + * would otherwise be 200 (OK). + */ + public static final HttpStatusCode S_NONAUTHORITATIVE = + new HttpStatusCode("S_NONAUTHORITATIVE",HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION); + + /** + * 204 No Content. The server has fulfilled the request but does not need to return an entity-body, + * and might want to return updated metainformation. The response MAY include new or updated metainformation + * in the form of entity-headers, which if present SHOULD be associated with the requested variant. If the + * client is a user agent, it SHOULD NOT change its document view from that which caused the request to be + * sent. This response is primarily intended to allow input for actions to take place without causing a + * change to the user agent's active document view, although any new or updated metainformation SHOULD be + * applied to the document currently in the user agent's active view. + */ + public static final HttpStatusCode S_NODATA = + new HttpStatusCode("S_NODATA",HttpServletResponse.SC_NO_CONTENT); + + /** + * 205 Reset Content. The server has fulfilled the request and the user agent SHOULD reset the document + * view which caused the request to be sent. This response is primarily intended to allow input for actions + * to take place via user input, followed by a clearing of the form in which the input is given so that the + * user can easily initiate another input action. + */ + public static final HttpStatusCode S_RESET = + new HttpStatusCode("S_RESET",HttpServletResponse.SC_RESET_CONTENT); + + /** + * 206 Partial Content. The server has fulfilled the partial GET request for the resource. The + * request MUST have included a Range header field indicating the desired range, and MAY have included + * an If-Range header field to make the request conditional. + */ + public static final HttpStatusCode S_PARTIAL = + new HttpStatusCode("S_PARTIAL",HttpServletResponse.SC_PARTIAL_CONTENT); + + /** + * 300 Multiple Choices. The requested resource corresponds to any one of a set of representations, + * each with its own specific location, and agent-driven negotiation information is being provided so that + * the user (or user agent) can select a preferred representation and redirect its request to that location. + */ + public static final HttpStatusCode S_CHOICE = + new HttpStatusCode("S_CHOICE",HttpServletResponse.SC_MULTIPLE_CHOICES); + + /** + * 301 Moved Permanently. The requested resource has been assigned a new permanent URI and any future + * references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities + * ought to automatically re-link references to the Request-URI to one or more of the new references returned + * by the server, where possible. + */ + public static final HttpStatusCode S_MOVED = + new HttpStatusCode("S_MOVED",HttpServletResponse.SC_MOVED_PERMANENTLY); + + /** + * 302 Moved Temporarily (Redirect). The requested resource resides temporarily under a different URI. + * Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for + * future requests. + */ + public static final HttpStatusCode S_REDIRECT = + new HttpStatusCode("S_REDIRECT",HttpServletResponse.SC_MOVED_TEMPORARILY); + + /** + * 303 See Other. The response to the request can be found under a different URI and SHOULD be + * retrieved using a GET method on that resource. This method exists primarily to allow the output of a + * POST-activated script to redirect the user agent to a selected resource. The new URI is not a + * substitute reference for the originally requested resource. + */ + public static final HttpStatusCode S_SEE_OTHER = + new HttpStatusCode("S_SEE_OTHER",HttpServletResponse.SC_SEE_OTHER); + + /** + * 304 Not Modified. If the client has performed a conditional GET request and access is allowed, + * but the document has not been modified, the server SHOULD respond with this status code. + */ + public static final HttpStatusCode S_NOTMODIFIED = + new HttpStatusCode("S_NOTMODIFIED",HttpServletResponse.SC_NOT_MODIFIED); + + /** + * 305 Use Proxy. The requested resource MUST be accessed through the proxy given by the Location + * field. The Location field gives the URI of the proxy. The recipient is expected to repeat this single + * request via the proxy. + */ + public static final HttpStatusCode S_USE_PROXY = + new HttpStatusCode("S_USEPROXY",HttpServletResponse.SC_USE_PROXY); + + /** + * 307 Temporary Redirect. The requested resource resides temporarily under a different URI. + * Since the redirection MAY be altered on occasion, the client SHOULD continue to use the Request-URI + * for future requests. + */ + public static final HttpStatusCode S_REDIRECT_TEMP = + new HttpStatusCode("S_REDIRECT_TEMP",HttpServletResponse.SC_TEMPORARY_REDIRECT); + + /** + * 400 Bad Request. The request could not be understood by the server due to malformed syntax. The + * client SHOULD NOT repeat the request without modifications. + */ + public static final HttpStatusCode E_BAD_REQUEST = + new HttpStatusCode("E_BAD_REQUEST",HttpServletResponse.SC_BAD_REQUEST); + + /** + * 401 Unauthorized. The request requires user authentication. The response MUST include a + * WWW-Authenticate header field containing a challenge applicable to the requested resource. The client + * MAY repeat the request with a suitable Authorization header field. If the request already included + * Authorization credentials, then the 401 response indicates that authorization has been refused for those + * credentials. If the 401 response contains the same challenge as the prior response, and the user agent + * has already attempted authentication at least once, then the user SHOULD be presented the entity that + * was given in the response, since that entity might include relevant diagnostic information. + */ + public static final HttpStatusCode E_AUTH = + new HttpStatusCode("E_AUTH",HttpServletResponse.SC_UNAUTHORIZED); + + /** + * 402 Payment Required. This code is reserved for future use. + */ + public static final HttpStatusCode E_PAYMENT = + new HttpStatusCode("E_PAYMENT",HttpServletResponse.SC_PAYMENT_REQUIRED); + + /** + * 403 Forbidden. The server understood the request, but is refusing to fulfill it. Authorization + * will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server + * wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the + * refusal in the entity. If the server does not wish to make this information available to the client, + * the status code 404 (Not Found) can be used instead. + */ + public static final HttpStatusCode E_FORBIDDEN = + new HttpStatusCode("E_FORBIDDEN",HttpServletResponse.SC_FORBIDDEN); + + /** + * 404 Not Found. The server has not found anything matching the Request-URI. No indication is given + * of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the + * server knows, through some internally configurable mechanism, that an old resource is permanently + * unavailable and has no forwarding address. This status code is commonly used when the server does not + * wish to reveal exactly why the request has been refused, or when no other response is applicable. + */ + public static final HttpStatusCode E_NOTFOUND = + new HttpStatusCode("E_NOTFOUND",HttpServletResponse.SC_NOT_FOUND); + + /** + * 405 Method Not Allowed. The method specified in the Request-Line is not allowed for the resource + * identified by the Request-URI. The response MUST include an Allow header containing a list of valid + * methods for the requested resource. + */ + public static final HttpStatusCode E_METHOD = + new HttpStatusCode("E_METHOD",HttpServletResponse.SC_METHOD_NOT_ALLOWED); + + /** + * 406 Not Acceptable. The resource identified by the request is only capable of generating response + * entities which have content characteristics not acceptable according to the accept headers sent in the request. + */ + public static final HttpStatusCode E_NOTACCEPTABLE = + new HttpStatusCode("E_NOTACCEPTABLE",HttpServletResponse.SC_NOT_ACCEPTABLE); + + /** + * 407 Proxy Authentication Required. This code is similar to 401 (Unauthorized), but indicates that + * the client must first authenticate itself with the proxy. The proxy MUST return a Proxy-Authenticate + * header field containing a challenge applicable to the proxy for the requested resource. The client MAY + * repeat the request with a suitable Proxy-Authorization header field. + */ + public static final HttpStatusCode E_PROXY_AUTH = + new HttpStatusCode("E_PROXY_AUTH",HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED); + + /** + * 408 Request Timeout. The client did not produce a request within the time that the server was + * prepared to wait. The client MAY repeat the request without modifications at any later time. + */ + public static final HttpStatusCode E_TIMEOUT = + new HttpStatusCode("E_TIMEOUT",HttpServletResponse.SC_REQUEST_TIMEOUT); + + /** + * 409 Conflict. The request could not be completed due to a conflict with the current state of the + * resource. This code is only allowed in situations where it is expected that the user might be able to + * resolve the conflict and resubmit the request. The response body SHOULD include enough information for + * the user to recognize the source of the conflict. Ideally, the response entity would include enough + * information for the user or user agent to fix the problem; however, that might not be possible and is + * not required. + */ + public static final HttpStatusCode E_CONFLICT = + new HttpStatusCode("E_CONFLICT",HttpServletResponse.SC_CONFLICT); + + /** + * 410 Gone. The requested resource is no longer available at the server and no forwarding address + * is known. This condition is expected to be considered permanent. Clients with link editing capabilities + * SHOULD delete references to the Request-URI after user approval. If the server does not know, or has no + * facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD + * be used instead. + */ + public static final HttpStatusCode E_GONE = + new HttpStatusCode("E_GONE",HttpServletResponse.SC_GONE); + + /** + * 411 Length Required. The server refuses to accept the request without a defined Content-Length. + * The client MAY repeat the request if it adds a valid Content-Length header field containing the length + * of the message-body in the request message. + */ + public static final HttpStatusCode E_NOLENGTH = + new HttpStatusCode("E_NOLENGTH",HttpServletResponse.SC_LENGTH_REQUIRED); + + /** + * 412 Precondition Failed. The precondition given in one or more of the request-header fields + * evaluated to false when it was tested on the server. This response code allows the client to place + * preconditions on the current resource metainformation (header field data) and thus prevent the + * requested method from being applied to a resource other than the one intended. + */ + public static final HttpStatusCode E_PRECONDITION = + new HttpStatusCode("E_PRECONDITION",HttpServletResponse.SC_PRECONDITION_FAILED); + + /** + * 413 Request Entity Too Large. The server is refusing to process a request because the request + * entity is larger than the server is willing or able to process. The server MAY close the connection to + * prevent the client from continuing the request. If the condition is temporary, the server SHOULD include + * a Retry-After header field to indicate that it is temporary and after what time the client MAY try again. + */ + public static final HttpStatusCode E_ENTITYTOOBIG = + new HttpStatusCode("E_ENTITYTOOBIG",HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE); + + /** + * 414 Request URI Too Long. The server is refusing to service the request because the Request-URI is + * longer than the server is willing to interpret. This rare condition is only likely to occur when a client + * has improperly converted a POST request to a GET request with long query information, when the client has + * descended into a URI "black hole" of redirection (e.g., a redirected URI prefix that points to a suffix of + * itself), or when the server is under attack by a client attempting to exploit security holes present in + * some servers using fixed-length buffers for reading or manipulating the Request-URI. + */ + public static final HttpStatusCode E_URITOOLONG = + new HttpStatusCode("E_URITOOLONG",HttpServletResponse.SC_REQUEST_URI_TOO_LONG); + + /** + * 415 Media Type Not Supported. The server is refusing to service the request because the entity of + * the request is in a format not supported by the requested resource for the requested method. + */ + public static final HttpStatusCode E_BAD_TYPE = + new HttpStatusCode("E_BAD_TYPE",HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE); + + /** + * 416 Requested Range Not Satisfiable. A server SHOULD return a response with this status code if + * a request included a Range request-header field, and none of the range-specifier values in this field + * overlap the current extent of the selected resource, and the request did not include an If-Range + * request-header field. (For byte-ranges, this means that the first-byte-pos of all of the byte-range-spec + * values were greater than the current length of the selected resource.) When this status code is returned + * for a byte-range request, the response SHOULD include a Content-Range entity-header field specifying the + * current length of the selected resource. This response MUST NOT use the multipart/byteranges content-type. + */ + public static final HttpStatusCode E_BAD_RANGE = + new HttpStatusCode("E_BAD_RANGE",HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); + + /** + * 417 Expectation Failed. The expectation given in an Expect request-header field could not be met by + * this server, or, if the server is a proxy, the server has unambiguous evidence that the request could not + * be met by the next-hop server. + */ + public static final HttpStatusCode E_EXPECTATION = + new HttpStatusCode("E_EXPECTATION",HttpServletResponse.SC_EXPECTATION_FAILED); + + /** + * 500 Internal Server Error. The server encountered an unexpected condition which prevented it + * from fulfilling the request. + */ + public static final HttpStatusCode E_INTERNAL = + new HttpStatusCode("E_INTERNAL",HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + + /** + * 501 Not Implemented. The server does not support the functionality required to fulfill the request. + * This is the appropriate response when the server does not recognize the request method and is not capable + * of supporting it for any resource. + */ + public static final HttpStatusCode E_NOTIMPL = + new HttpStatusCode("E_NOTIMPL",HttpServletResponse.SC_NOT_IMPLEMENTED); + + /** + * 502 Bad Gateway. The server, while acting as a gateway or proxy, received an invalid response from + * the upstream server it accessed in attempting to fulfill the request. + */ + public static final HttpStatusCode E_BAD_GATEWAY = + new HttpStatusCode("E_BAD_GATEWAY",HttpServletResponse.SC_BAD_GATEWAY); + + /** + * 503 Service Unavailable. The server is currently unable to handle the request due to a temporary + * overloading or maintenance of the server. The implication is that this is a temporary condition which will + * be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. + * If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response. + */ + public static final HttpStatusCode E_UNAVAILABLE = + new HttpStatusCode("E_UNAVAILABLE",HttpServletResponse.SC_SERVICE_UNAVAILABLE); + + /** + * 504 Gateway Timeout. The server, while acting as a gateway or proxy, did not receive a timely + * response from the upstream server specified by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary + * server (e.g. DNS) it needed to access in attempting to complete the request. + */ + public static final HttpStatusCode E_GATEWAY_TIMEOUT = + new HttpStatusCode("E_GATEWAY_TIMEOUT",HttpServletResponse.SC_GATEWAY_TIMEOUT); + + /** + * 505 HTTP Version Not Supported. The server does not support, or refuses to support, the HTTP + * protocol version that was used in the request message. The server is indicating that it is unable or + * unwilling to complete the request using the same major version as the client, other than with this + * error message. The response SHOULD contain an entity describing why that version is not supported and + * what other protocols are supported by that server. + */ + public static final HttpStatusCode E_BAD_VERSION = + new HttpStatusCode("E_BAD_VERSION",HttpServletResponse.SC_HTTP_VERSION_NOT_SUPPORTED); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Internal constructor which creates a new element of this enumerated type. + * + * @param name The name of the HttpStatusCode to be created. + * @param value The numeric value to assign to the HttpStatusCode. + */ + private HttpStatusCode(String name, int value) + { + super(name,value); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Standard static method implementations + *-------------------------------------------------------------------------------- + */ + + /** + * Gets a HttpStatusCode by name. + * + * @param name The name of the HttpStatusCode to get; may be null. + * @return The HttpStatusCode object, or null if the HttpStatusCode + * does not exist. + */ + public static HttpStatusCode getEnum(String name) + { + return (HttpStatusCode)getEnum(HttpStatusCode.class,name); + + } // end getEnum + + /** + * Gets a HttpStatusCode by numeric value. + * + * @param code The numeric value of the HttpStatusCode to get. + * @return The HttpStatusCode object, or null if the HttpStatusCode + * does not exist. + */ + public static HttpStatusCode getEnum(int code) + { + return (HttpStatusCode)getEnum(HttpStatusCode.class,code); + + } // end getEnum + + /** + * Gets the Map of HttpStatusCode objects by name. + * + * @return The HttpStatusCode object Map. + */ + public static Map getEnumMap() + { + return getEnumMap(HttpStatusCode.class); + + } // end getEnumMap + + /** + * Gets the List of HttpStatusCode objects, in the order in which the objects are listed + * in the code above. + * + * @return The HttpStatusCode object List. + */ + public static List getEnumList() + { + return getEnumList(HttpStatusCode.class); + + } // end getEnumList + + /** + * Gets an iterator over all HttpStatusCode objects, in the order in which the objects are listed + * in the code above. + * + * @return The HttpStatusCode object iterator. + */ + public static Iterator iterator() + { + return iterator(HttpStatusCode.class); + + } // end iterator + +} // end class HttpStatusCode diff --git a/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java b/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java new file mode 100644 index 0000000..99c9f53 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java @@ -0,0 +1,77 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +/** + * Contains various namespaces which are used to designate objects in the global + * {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} and other contexts. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public interface Namespaces +{ + /** + * Namespace used for objects provided by the application substrate object. + */ + public static final String SUBSTRATE_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/11/29/substrate.objects"; + + /** + * Namespace used to retrieve servlet initialization parameters. + */ + public static final String SERVLET_INIT_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/12/22/servlet.init.params"; + + /** + * Namespace used to retrieve servlet context initialization parameters. + */ + public static final String SERVLET_CONTEXT_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/12/22/servlet.context.params"; + + /** + * Namespace under which the database connections are stored. + */ + public static final String DATABASE_CONNECTIONS_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/12/08/database.connections"; + + /** + * Namespace under which the Dynamo objects are stored. + */ + public static final String DYNAMO_OBJECT_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/12/07/dynamo.objects"; + + /** + * Namespace under which the Dynamo application-level objects are stored. + */ + public static final String DYNAMO_APPLICATION_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/12/08/dynamo.application"; + + /** + * Namespace used to retrieve user information for mail messages. + */ + public static final String DYNAMO_USER_INFO_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/12/13/user.information"; + + /** + * Namespace used to designate group permissions. + */ + public static final String GROUP_PERMISSIONS_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2002/12/27/group.permissions"; + +} // end interface Namespaces diff --git a/src/dynamo-framework/com/silverwrist/dynamo/RequestType.java b/src/dynamo-framework/com/silverwrist/dynamo/RequestType.java new file mode 100644 index 0000000..1b954d2 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/RequestType.java @@ -0,0 +1,142 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +import java.util.*; +import org.apache.commons.lang.enum.*; + +/** + * A type-safe enumerated type that indicates the type of a {@link com.silverwrist.dynamo.iface.Request Request} + * that comes in from the framework. It is also used to indicate the type of a + * {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} object. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public final class RequestType extends Enum +{ + /*-------------------------------------------------------------------------------- + * The actual enumeration values + *-------------------------------------------------------------------------------- + */ + + /** + * A "null" request type, only used to label certain sessions. + * + * @see com.silverwrist.dynamo.util.NullSessionInfo + */ + public static final RequestType _NULL = new RequestType("_NULL"); + + /** + * This RequestType is used to label the {@link com.silverwrist.dynamo.iface.Request Request} passed + * along with the event that is fired when the application starts up. + * + * @see com.silverwrist.dynamo.event.ApplicationEvent + */ + public static final RequestType _APPLICATION = new RequestType("_APPLICATION"); + + /** + * This RequestType is used to label the {@link com.silverwrist.dynamo.iface.Request Request} passed + * along with the event that is fired when a new session is created. + * + * @see com.silverwrist.dynamo.event.SessionInfoEvent + */ + public static final RequestType _SESSION = new RequestType("_SESSION"); + + /** + * Designates a {@link com.silverwrist.dynamo.iface.Request Request} or + * {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} associated with standard HTTP requests. + */ + public static final RequestType HTTP = new RequestType("HTTP"); + + /** + * Designates a {@link com.silverwrist.dynamo.iface.Request Request} or + * {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} associated with XML-RPC requests, usually + * transmitted over HTTP. + */ + public static final RequestType XMLRPC = new RequestType("XMLRPC"); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Internal constructor which creates a new element of this enumerated type. + * + * @param name The name of the RequestType to be created. + */ + private RequestType(String name) + { + super(name); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Standard static method implementations + *-------------------------------------------------------------------------------- + */ + + /** + * Gets a RequestType by name. + * + * @param name The name of the RequestType to get; may be null. + * @return The RequestType object, or null if the RequestType does not exist. + */ + public static RequestType getEnum(String name) + { + return (RequestType)getEnum(RequestType.class,name); + + } // end getEnum + + /** + * Gets the Map of RequestType objects by name. + * + * @return The RequestType object Map. + */ + public static Map getEnumMap() + { + return getEnumMap(RequestType.class); + + } // end getEnumMap + + /** + * Gets the List of RequestType objects, in the order in which the objects are listed + * in the code above. + * + * @return The RequestType object List. + */ + public static List getEnumList() + { + return getEnumList(RequestType.class); + + } // end getEnumList + + /** + * Gets an iterator over all RequestType objects, in the order in which the objects are listed + * in the code above. + * + * @return The RequestType object iterator. + */ + public static Iterator iterator() + { + return iterator(RequestType.class); + + } // end iterator + +} // end class RequestType diff --git a/src/dynamo-framework/com/silverwrist/dynamo/UserInfoNamespace.java b/src/dynamo-framework/com/silverwrist/dynamo/UserInfoNamespace.java new file mode 100644 index 0000000..7156b06 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/UserInfoNamespace.java @@ -0,0 +1,64 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +/** + * Describes the attributes used by the Dynamo mail component to retrieve user information. Also contains + * the name for the default authenticator and default user permissons. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public interface UserInfoNamespace +{ + /** + * The property namespace that contains the user information. + */ + public static final String NAMESPACE = Namespaces.DYNAMO_USER_INFO_NAMESPACE; + + /** + * Property name designating the user's full name. + */ + public static final String ATTR_FULLNAME = "full.name"; + + /** + * Property name designating the user E-mail address. + */ + public static final String ATTR_EMAIL_ADDRESS = "email.address"; + + /** + * Property name designating the numeric user ID. + */ + public static final String ATTR_ID = "user.id"; + + /** + * Property name designating the user name. + */ + public static final String ATTR_USERNAME = "user.name"; + + /** + * Used to designate the default hash password authenticator. + */ + public static final String AUTH_DEFAULT = "default.hash.password"; + + /** + * The permission that allows user information to be edited. + */ + public static final String PERM_EDIT_ALL = "edit.all"; + +} // end interface UserInfoNamespace diff --git a/src/dynamo-framework/com/silverwrist/dynamo/Verb.java b/src/dynamo-framework/com/silverwrist/dynamo/Verb.java new file mode 100644 index 0000000..a4ee2b1 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/Verb.java @@ -0,0 +1,132 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +import java.util.*; +import org.apache.commons.lang.enum.*; + +/** + * A type-safe enumerated type that indicates the action of a {@link com.silverwrist.dynamo.iface.Request Request} + * that comes in from the framework. Verb objects correspond roughly to HTTP methods. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public final class Verb extends Enum +{ + /*-------------------------------------------------------------------------------- + * The actual enumeration values + *-------------------------------------------------------------------------------- + */ + + /** + * Indicates a request to delete a resource identified by a URI. Corresponds to HTTP DELETE method. + */ + public static final Verb DELETE = new Verb("DELETE"); // (standard) + + /** + * Indicates a request to retrieve a resource identified by a URI. Corresponds to HTTP GET method. + */ + public static final Verb GET = new Verb("GET"); // (standard) + + /** + * Indicates a request to interact with a resource identified by a URI. Corresponds to HTTP POST method. + * All XML-RPC requests use this verb. + */ + public static final Verb POST = new Verb("POST"); // (standard) + + /** + * Indicates a request to overwrite a resource identified by a URI. Corresponds to HTTP PUT method. + */ + public static final Verb PUT = new Verb("PUT"); // (standard) + + /** + * Indicates a request to get the last modification time of a resource identified by a URI. Often associated + * with a HTTP GET method. + */ + public static final Verb _LASTMOD = new Verb("_LASTMOD"); // extended for getLastModified + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Internal constructor which creates a new element of this enumerated type. + * + * @param name The name of the Verb to be created. + */ + private Verb(String name) + { + super(name); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Standard static method implementations + *-------------------------------------------------------------------------------- + */ + + /** + * Gets a Verb by name. + * + * @param name The name of the Verb to get; may be null. + * @return The Verb object, or null if the Verb does not exist. + */ + public static Verb getEnum(String name) + { + return (Verb)getEnum(Verb.class,name); + + } // end getEnum + + /** + * Gets the Map of Verb objects by name. + * + * @return The Verb object Map. + */ + public static Map getEnumMap() + { + return getEnumMap(Verb.class); + + } // end getEnumMap + + /** + * Gets the List of Verb objects, in the order in which the objects are listed + * in the code above. + * + * @return The Verb object List. + */ + public static List getEnumList() + { + return getEnumList(Verb.class); + + } // end getEnumList + + /** + * Gets an iterator over all Verb objects, in the order in which the objects are listed + * in the code above. + * + * @return The Verb object iterator. + */ + public static Iterator iterator() + { + return iterator(Verb.class); + + } // end iterator + +} // end class Verb diff --git a/src/dynamo-framework/com/silverwrist/dynamo/WebConstants.java b/src/dynamo-framework/com/silverwrist/dynamo/WebConstants.java new file mode 100644 index 0000000..fc173ba --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/WebConstants.java @@ -0,0 +1,134 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo; + +/** + * Contains the names of various application, session, and request attributes and initialization parameters + * used by the Dynamo servlet interface. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public interface WebConstants +{ + /** + * Prefix for all Dynamo-specific application (ServletContext) attributes. + */ + public static final String APPLICATION_PREFIX = "com.silverwrist.dynamo."; + + /** + * Application attribute that records whether or not logging has been initiated. + */ + public static final String LOGGING_ATTRIBUTE = APPLICATION_PREFIX + "LoggingStarted"; + + /** + * Application attribute that holds the Dynamo + * {@link com.silverwrist.dynamo.app.ApplicationContainer ApplicationContainer} object. + */ + public static final String APPLICATION_ATTRIBUTE = APPLICATION_PREFIX + "app.ApplicationContainer"; + + /** + * Application attribute used to store the {@link com.silverwrist.dynamo.iface.MIMETypeMapper MIMETypeMapper} + * object created to tap into the servlet container's MIME type maps. + */ + public static final String SERVLET_MAPPER_ATTRIBUTE = APPLICATION_PREFIX + "servlet.MIMETypeMapper"; + + /** + * Servlet context initialization parameter that tells Dynamo where to find the logging configuration file. + */ + public static final String LOGGING_INIT_PARAM = "logging.config"; + + /** + * Servlet context initialization parameter that tells Dynamo where to find the Dynamo XML configuration file. + */ + public static final String CONFIG_INIT_PARAM = "dynamo.config"; + + /** + * Prefix for all Dynamo-specific session (HttpSession) attributes. + */ + public static final String SESSION_PREFIX = "com.silverwrist.dynamo."; + + /** + * Session attribute used to store the HTTP-specific {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} + * object. + */ + public static final String SESSION_PARAM = SESSION_PREFIX + "session"; + + /** + * Session attribute used to store the connection-specific + * {@link com.silverwrist.dynamo.iface.BrowserData BrowserData} object. + */ + public static final String SESSION_BROWSER_DATA_PARAM = SESSION_PREFIX + "browser.data"; + + /** + * Prefix for all Dynamo-specific request (ServletRequest) attributes. + */ + public static final String REQUEST_PREFIX = "com.silverwrist.dynamo."; + + /** + * Request attribute which stores the per-request + * {@link com.silverwrist.dynamo.iface.SessionInfoProvider SessionInfoProvider} object. + */ + public static final String REQUEST_SESSION_PROVIDER_ATTR = REQUEST_PREFIX + "session.provider"; + + /** + * Request attribute which contains a reference to a new HTTP session that must be initialized. + */ + public static final String REQUEST_SESSIONINIT_ATTR = REQUEST_PREFIX + "HTTPsession.init"; + + /** + * Request attribute which contains a reference to the connection-specific + * {@link com.silverwrist.dynamo.iface.BrowserData BrowserData} object. + */ + public static final String REQUEST_BROWSER_DATA_ATTR = REQUEST_PREFIX + "browser.data"; + + /** + * Request attribute which contains a reference to the set of all cookies currently defined + * on the connection. + */ + public static final String REQUEST_COOKIESET_ATTR = REQUEST_PREFIX + "browser.cookieset"; + + /** + * Request attribute containing a list of all new cookies set on the output, which cannot be set until + * the start of the output phase. + */ + public static final String REQUEST_NEWCOOKIEHOLDER_ATTR = REQUEST_PREFIX + "browser.NewCookieHolder"; + + /** + * Request attribute containing a list of all new headers set on the output, which cannot be set until + * the start of the output phase. + */ + public static final String REQUEST_NEWHEADERHOLDER_ATTR = REQUEST_PREFIX + "servlet.NewHeaderHolder"; + + /** + * Request attribute containing a backreference to the {@link com.silverwrist.dynamo.iface.Request Request} + * object for the current request. + */ + public static final String REQUEST_SELF_ATTR = REQUEST_PREFIX + "request.self"; + + /** + * The HTTP header which requests a page only if it's been modified since a specific time. + */ + public static final String HDR_IF_MODIFIED_SINCE = "If-Modified-Since"; + + /** + * The HTTP header which returns when a page was last modified. + */ + public static final String HDR_LAST_MODIFIED = "Last-Modified"; + +} // end interface WebConstants diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java new file mode 100644 index 0000000..436ab23 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java @@ -0,0 +1,1292 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.io.*; +import java.util.*; +import javax.servlet.*; +import javax.servlet.http.*; +import org.apache.commons.collections.*; +import org.apache.log4j.Logger; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.DynamoVersion; +import com.silverwrist.dynamo.Namespaces; +import com.silverwrist.dynamo.event.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.script.ScriptController; +import com.silverwrist.dynamo.util.*; + +/** + * The main "engine" class of the Dynamo framework, which holds most of the service providers and other + * classes registered (usually by the defined {@link com.silverwrist.dynamo.iface.Application Application} class). + * Exactly one of these is created per Dynamo instance; for Dynamo Web applications, a reference to it is saved + * in the servlet context attributes. It is also responsible for reading and parsing the Dynamo XML configuration + * file and instantiating components defined therein. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class ApplicationContainer + implements ResourceProvider, ResourceProviderManager, RendererRegistration, ObjectProvider, + EventListenerRegistration, OutputObjectFilterRegistration, QueryRenderer, PostDynamicUpdate, + RenderImmediate, RequestPreprocessorRegistration, ExceptionTranslatorRegistration +{ + /*-------------------------------------------------------------------------------- + * Internal class recording renderer registrations and providing a + * "shutdown hook" + *-------------------------------------------------------------------------------- + */ + + private class RegisteredRenderer implements ComponentShutdown + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private Renderer m_renderer; + private HashSet m_known_classes; + + /*==================================================================== + * Constructors + *==================================================================== + */ + + RegisteredRenderer(Class klass, Renderer renderer) + { + m_renderer = renderer; + m_known_classes = new HashSet(); + m_known_classes.add(klass); + + } // end constructor + + RegisteredRenderer(DynamicClass dclass, Renderer renderer) + { + m_renderer = renderer; + m_known_classes = new HashSet(); + m_known_classes.add(dclass); + + } // end constructor + + /*==================================================================== + * Implementations from interface ComponentShutdown + *==================================================================== + */ + + public synchronized void shutdown() + { + Iterator it = m_known_classes.iterator(); + while (it.hasNext()) + { // remove all class rendering entries registered with this "event" + Object obj = it.next(); + if (obj instanceof Class) + m_class_renderers.remove(obj); + else if (obj instanceof DynamicClass) + m_class_renderers.remove(obj); + + } // end while + + m_known_classes.clear(); + + } // end shutdown + + /*==================================================================== + * External operations + *==================================================================== + */ + + public Renderer getRenderer() + { + return m_renderer; + + } // end getRenderer + + public synchronized void add(Class klass) + { + m_known_classes.add(klass); + + } // end add + + public synchronized void add(DynamicClass dclass) + { + m_known_classes.add(dclass); + + } // end add + + } // end class RegisteredRenderer + + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(ApplicationContainer.class); + + private static final String[] SUBSTRATE_MAP_KEYS = + { ApplicationSubstrate.OBJ_BASE_PATH, ApplicationSubstrate.OBJ_CODE_PATH, + ApplicationSubstrate.OBJ_CLASSES_PATH, ApplicationSubstrate.OBJ_LIBS_PATH + }; + + private static final ApplicationListener[] APP_LISTENER_TEMPLATE = new ApplicationListener[0]; + private static final SessionInfoListener[] SESSION_LISTENER_TEMPLATE = new SessionInfoListener[0]; + + private static final String TEMPLATE_CLASSNAME = "$$$BLORT$$$"; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private int m_refs; // reference count + private ApplicationSubstrate m_substrate; // application substrate object + private File m_resource_base; // base directory for resources + private Vector m_resource_providers = new Vector(); // resource providers + private LinkedList m_shutdown_list = new LinkedList(); // list of objects to shut down + private HashMap m_connections = new HashMap(); // list of connection pools + private HashMap m_objects = new HashMap(); // list of base objects + private Application m_application = null; // the application object + private Hashtable m_class_renderers = new Hashtable(); // renderers for static classes + private Hashtable m_dclass_renderers = new Hashtable(); // renderers for dynamic classes + private Vector m_application_listeners = new Vector(); // application event listeners + private Vector m_session_listeners = new Vector(); // session event listeners + private BackgroundProcessor m_background; // background processor + private ScriptController m_script_ctrl; // script controller + private ApplicationServiceManager m_app_sm; // application service manager + private PropertySerializationSupport m_pss; // property serialization support + private Set m_known_sessions; // known sessions + private String m_identity; // server identity + private Map m_rewrite_rules; // URL rewriting rules + private Vector m_output_filters = new Vector(); // output filters + private HashMap m_update_listeners = new HashMap(); // update listeners + private Vector m_request_preprocessors = new Vector(); // request preprocessors + private Vector m_exception_xlators = new Vector(); // exception translators + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Creates the application container. + * + * @param config_file A reference to the Dynamo XML configuration file. + * @param substrate A reference to the {@link com.silverwrist.dynamo.iface.ApplicationSubstrate ApplicationSubstrate} + * object, which provides certain services and object references to the + * ApplicationContainer. (Usually, this will be specific to the Dynamo application + * type, for example, Web application.) + * @exception com.silverwrist.dynamo.except.ConfigException If there is an error in the configuration which will + * not allow Dynamo to be initialized. + */ + public ApplicationContainer(File config_file, ApplicationSubstrate substrate) throws ConfigException + { + if (logger.isDebugEnabled()) + logger.debug("new ApplicationContainer - config file is " + config_file.getAbsolutePath()); + substrate.initialize(); + m_substrate = substrate; + m_refs = 1; + m_app_sm = new ApplicationServiceManager(); + m_pss = new PropertySerializationSupport(); + m_known_sessions = Collections.synchronizedSet(new HashSet()); + XMLLoader loader = XMLLoader.get(); + + // Initialize the init services and runtime services with defaults. + m_app_sm.addInitService(ResourceProvider.class,(ResourceProvider)this); + m_app_sm.addInitService(ResourceProviderManager.class,(ResourceProviderManager)this); + m_app_sm.addInitService(RendererRegistration.class,(RendererRegistration)this); + m_app_sm.addInitService(ObjectProvider.class,(ObjectProvider)this); + m_app_sm.addInitService(EventListenerRegistration.class,(EventListenerRegistration)this); + m_app_sm.addInitService(OutputObjectFilterRegistration.class,(OutputObjectFilterRegistration)this); + m_app_sm.addInitService(PropertySerializer.class,(PropertySerializer)m_pss); + m_app_sm.addInitService(PropertySerializerRegistration.class,(PropertySerializerRegistration)m_pss); + m_app_sm.addInitService(PostDynamicUpdate.class,(PostDynamicUpdate)this); + m_app_sm.addInitService(RequestPreprocessorRegistration.class,(RequestPreprocessorRegistration)this); + m_app_sm.addInitService(ExceptionTranslatorRegistration.class,(ExceptionTranslatorRegistration)this); + + m_app_sm.addRuntimeService(ResourceProvider.class,(ResourceProvider)this); + m_app_sm.addRuntimeService(ObjectProvider.class,(ObjectProvider)this); + m_app_sm.addRuntimeService(EventListenerRegistration.class,(EventListenerRegistration)this); + m_app_sm.addRuntimeService(PropertySerializer.class,(PropertySerializer)m_pss); + m_app_sm.addRuntimeService(PostDynamicUpdate.class,(PostDynamicUpdate)this); + m_app_sm.addRuntimeService(RenderImmediate.class,(RenderImmediate)this); + + m_app_sm.addOutputService(ResourceProvider.class,(ResourceProvider)this); + m_app_sm.addOutputService(ObjectProvider.class,(ObjectProvider)this); + m_app_sm.addOutputService(QueryRenderer.class,(QueryRenderer)this); + + // Create initialization services interface object. + ServiceProvider init_svcs = m_app_sm.createInitServices(); + + try + { // load the configuration file + Document config_doc = loader.load(config_file,false); + Element root = loader.getRootElement(config_doc,"configuration"); + + // get the element and process it + Element control = loader.getSubElement(root,"control"); + processControlSection(control); + m_shutdown_list.addFirst(m_background); + m_app_sm.addInitService(BackgroundScheduler.class,m_background); + m_app_sm.addRuntimeService(BackgroundScheduler.class,m_background); + + // initialize some default renderers + m_shutdown_list.addFirst(registerRenderer(DataItem.class,new DataItemRenderer())); + m_shutdown_list.addFirst(registerRenderer(java.util.List.class,new ListRenderer())); + + // initialize the scripting engine + m_script_ctrl = new ScriptController(); + m_script_ctrl.initialize(control,init_svcs); + m_shutdown_list.addFirst(m_script_ctrl); + + // add the scripting engine's services so they can be used by external components + m_app_sm.addInitService(ScriptEngineConfig.class,m_script_ctrl); + m_app_sm.addRuntimeService(ScriptExecute.class,m_script_ctrl); + + // get all database connection configurations + List l = loader.getMatchingSubElements(root,"dbconnection"); + Iterator it = l.iterator(); + Element elt; + while (it.hasNext()) + { // get each element in turn + elt = (Element)(it.next()); + DBConnectionPool pool = (DBConnectionPool)createNamedObject(elt,init_svcs,DBConnectionPool.class, + "no.notDBPool"); + m_connections.put(pool.getName(),pool); + + } // end while + + m_app_sm.addInitService(HookServiceProviders.class,m_app_sm); + + // Sort the "object" definitions by priority order to determine in what order to instantiate them. + l = loader.getMatchingSubElements(root,"object"); + if (!(l.isEmpty())) + { // copy elements into binary heap + it = l.iterator(); + BinaryHeap prioheap = new BinaryHeap(l.size()); + while (it.hasNext()) + { // sort elements by priority + elt = (Element)(it.next()); + prioheap.insert(new HeapContents(elt)); + + } // end while + + while (prioheap.size()>0) + { // now remove and instantiate the elements + HeapContents hc = (HeapContents)(prioheap.remove()); + NamedObject nobj = createNamedObject(hc.getElement(),init_svcs,null,null); + m_objects.put(nobj.getName(),nobj); + + } // end while + + } // end if + + // Find the application definition and initialize the application. + elt = loader.getSubElement(root,"application"); + m_application = (Application)createNamedObject(elt,init_svcs,Application.class,"no.notApp"); + + } // end try + catch (IOException e) + { // unable to read config file - send back a ConfigException + logger.fatal("ApplicationContainer config read failed",e); + ConfigException ce = new ConfigException(ApplicationContainer.class,"ApplicationContainerMessages", + "creation.ioError",e); + ce.setParameter(0,config_file.getAbsolutePath()); + throw ce; + + } // end catch + catch (XMLLoadException e) + { // XML loader failed - send back a ConfigException + logger.fatal("ApplicationContainer config load failed",e); + throw new ConfigException(e); + + } // end catch + + // Create the "server identity" string. + StringBuffer buf = new StringBuffer(); + String app_id = m_application.getIdentity(); + if (app_id!=null) + buf.append(app_id).append(' '); + buf.append("Dynamo/").append(DynamoVersion.VERSION); + m_identity = buf.toString(); + logger.info("Server: " + m_identity); + + // Fire the "application initialized" events. + ApplicationListener[] listeners = + (ApplicationListener[])(m_application_listeners.toArray(APP_LISTENER_TEMPLATE)); + if (listeners.length>0) + { // call the event handlers... + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer: " + listeners.length + " init handler(s) to call"); + ApplicationEventRequest req = new ApplicationEventRequest(m_app_sm.createRuntimeServices(),true); + ApplicationEvent evt = new ApplicationEvent(req,m_application); + for (int i=0; iComponentInitialize associated with the object, or null + * if there is no such instance. + */ + private static final ComponentInitialize getComponentInitialize(Object obj) + { + if (obj instanceof ComponentInitialize) + return (ComponentInitialize)obj; + if (obj instanceof ServiceProvider) + { // it may be a service provider interface + try + { // look for ComponentInitialize as a service + ServiceProvider sp = (ServiceProvider)obj; + ComponentInitialize rc = (ComponentInitialize)(sp.queryService(ComponentInitialize.class)); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // do nothing here + } // end catch + + } // end if + + return null; // no dice! + + } // end getComponentInitialize + + /** + * Finds an instance of the {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} interface + * associated with the given object, either through implementation of the interface, or by querying its + * {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} implementation. + * + * @param obj The object to be queried. + * @return The instance of ComponentShutdown associated with the object, or null + * if there is no such instance. + */ + private static final ComponentShutdown getComponentShutdown(Object obj) + { + if (obj instanceof ComponentShutdown) + return (ComponentShutdown)obj; + if (obj instanceof ServiceProvider) + { // it may be a service provider interface + try + { // look for ComponentShutdown as a service + ServiceProvider sp = (ServiceProvider)obj; + ComponentShutdown rc = (ComponentShutdown)(sp.queryService(ComponentShutdown.class)); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // do nothing here + } // end catch + + } // end if + + return null; // no dice! + + } // end getComponentShutdown + + /** + * Destroys all data associated with this ApplicationContainer. + */ + private final synchronized void destroy() + { + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer.destroy(): " + m_known_sessions.size() + " sessions to shutdown"); + Iterator it = m_known_sessions.iterator(); + while (it.hasNext()) + { // shut down each session + ComponentShutdown cs = (ComponentShutdown)(it.next()); + cs.shutdown(); + + } // end while + + m_known_sessions.clear(); + + // Fire the "application exiting" events. + ApplicationListener[] listeners = + (ApplicationListener[])(m_application_listeners.toArray(APP_LISTENER_TEMPLATE)); + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer.destroy(): " + listeners.length + " exit handlers to call"); + if (listeners.length>0) + { // call the event handlers... + ApplicationEventRequest req = new ApplicationEventRequest(m_app_sm.createRuntimeServices(),false); + ApplicationEvent evt = new ApplicationEvent(req,m_application); + for (int i=0; i0) + { // shut down all components in reverse order of creation + ComponentShutdown sd = (ComponentShutdown)(m_shutdown_list.removeFirst()); + sd.shutdown(); + + } // end while + + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer.destroy(): clearing internal data structures"); + m_connections.clear(); + m_objects.clear(); + m_class_renderers.clear(); + m_dclass_renderers.clear(); + m_application = null; + m_resource_providers.clear(); + m_application_listeners.clear(); + m_session_listeners.clear(); + + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer.destroy(): terminating substrate"); + m_substrate.terminate(); + m_substrate = null; + + } // end destroy + + private final Map getSubstrateReplaceMap() + { + HashMap rc = new HashMap(); + for (int i=0; imax_munch) + { // found one that munches more...save it + wrp = tmp; + max_munch = test; + + } // end if + + } // end while + + } // end synchronized block + + return wrp; + + } // end locateResourceProvider + + private final InputStream getResourceInternal(ComponentResName crn) throws IOException + { + File res_file = new File(m_resource_base,crn.getStringValue(0,false)); + if (!(res_file.exists()) || res_file.isDirectory() || !(res_file.canRead())) + throw new NoSuchResourceException(crn.getStringValue(0,true)); + return new FileInputStream(res_file); + + } // end getResourceInternal + + private final long getResourceModTimeInternal(ComponentResName crn) + { + File res_file = new File(m_resource_base,crn.getStringValue(0,false)); + if (!(res_file.exists()) || res_file.isDirectory() || !(res_file.canRead())) + return 0; + return res_file.lastModified(); + + } // end getResourceModTimeInternal + + private final RegisteredRenderer searchDClassRenderers(DynamicClass dclass) + { + return (RegisteredRenderer)(m_dclass_renderers.get(dclass)); + + } // end searchDClassRenderer + + private final RegisteredRenderer searchArrayRenderers(Class klass, String template) + { + if (klass.isPrimitive() || (klass==Object.class)) + return null; // should have been picked up already + + // look at this level for the class member + RegisteredRenderer rc = null; + try + { // load the array class corresponding to the right depth, then check the renderer map + Class tmp = Class.forName(StringUtils.replace(template,TEMPLATE_CLASSNAME,klass.getName())); + rc = (RegisteredRenderer)(m_class_renderers.get(tmp)); + if (rc!=null) + return rc; + + } // end try + catch (ClassNotFoundException e) + { // this class was not found, so it can't be present + rc = null; + + } // end catch + + // Try all interfaces implemented by the object. + Class[] ifaces = klass.getInterfaces(); + for (int i=0; iObjectProvider. + * + * @param namespace The namespace to interpret the name relative to. + * @param name The name of the object to be retrieved. + * @return The object reference specified. + */ + public Object getObject(String namespace, String name) + { + if (namespace.equals(Namespaces.SUBSTRATE_NAMESPACE)) + return m_substrate.getObject(namespace,name); + + if (namespace.equals(Namespaces.DATABASE_CONNECTIONS_NAMESPACE)) + { // get a database connection + Object rc = m_connections.get(name); + if (rc!=null) + return rc; + + } // end if + + if (namespace.equals(Namespaces.DYNAMO_OBJECT_NAMESPACE)) + { // get an object + Object rc = m_objects.get(name); + if (rc!=null) + return rc; + + } // end if + + if (namespace.equals(Namespaces.DYNAMO_APPLICATION_NAMESPACE)) + { // return one of the application data elements + if (name.equals("application")) + return m_application; + else if (name.equals("identity")) + return m_identity; + else if (name.equals("__container__")) + return this; + + } // end if + + throw new NoSuchObjectException("ApplicationContainer",namespace,name); + + } // end getObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface EventListenerRegistration + *-------------------------------------------------------------------------------- + */ + + public ComponentShutdown registerApplicationListener(ApplicationListener listener) + { + m_application_listeners.add(listener); + return new ShutdownVectorRemove(m_application_listeners,listener); + + } // end registerApplicationListener + + public ComponentShutdown registerSessionInfoListener(SessionInfoListener listener) + { + m_session_listeners.add(listener); + return new ShutdownVectorRemove(m_session_listeners,listener); + + } // end registerSessionInfoListener + + public synchronized ComponentShutdown registerDynamicUpdateListener(Class event_type, + DynamicUpdateListener listener) + { + if (!(DynamicUpdateEvent.class.isAssignableFrom(event_type))) + throw new IllegalArgumentException("event type is not valid"); + Vector vec = (Vector)(m_update_listeners.get(event_type)); + if (vec==null) + { // creatr vector for this event type + vec = new Vector(); + m_update_listeners.put(event_type,vec); + + } // end if + + vec.add(listener); + return new ShutdownVectorRemove(vec,listener); + + } // end registerDynamicUpdateListener + + /*-------------------------------------------------------------------------------- + * Implementations from interface OutputObjectFilterRegistration + *-------------------------------------------------------------------------------- + */ + + public ComponentShutdown registerOutputObjectFilter(OutputObjectFilter filter) + { + if (logger.isDebugEnabled()) + logger.debug("Registering new OutputObjectFilter: " + filter); + m_output_filters.add(filter); + return new ShutdownVectorRemove(m_output_filters,filter); + + } // end registerOutputObjectFilter + + /*-------------------------------------------------------------------------------- + * Implementations from interface QueryRenderer + *-------------------------------------------------------------------------------- + */ + + public Renderer getRendererForObject(Object obj) + { + RegisteredRenderer rc = null; + if (obj instanceof DynamicObject) + { // this is a dynamic object - search by its dynamic class first + DynamicClass dclass = ((DynamicObject)obj).getDClass(); + rc = (RegisteredRenderer)(m_dclass_renderers.get(dclass)); + if (rc==null) + { // search for ancestor class, "snap" reference if possible + rc = searchDClassRenderers(dclass); + if (rc!=null) + { // add this class to the mapping + m_dclass_renderers.put(dclass,rc); + rc.add(dclass); + + } // end if + + } // end if + + if (rc!=null) + return rc.getRenderer(); + + } // end if + + Class klass = obj.getClass(); + rc = (RegisteredRenderer)(m_class_renderers.get(klass)); + if (rc==null) + { // search for ancestor class, "snap" reference if possible + rc = searchClassRenderers(klass); + if (rc!=null) + { // found it - add this class to the mapping + m_class_renderers.put(klass,rc); + rc.add(klass); + + } // end if + + } // end if + + return ((rc==null) ? null : rc.getRenderer()); + + } // end getRendererForObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface PostDynamicUpdate + *-------------------------------------------------------------------------------- + */ + + public void postUpdate(DynamicUpdateEvent event) + { + if (logger.isDebugEnabled()) + logger.debug("PostDynamicUpdate: posting an event of type " + event.getClass().getName()); + Class klass = event.getClass(); + for (;;) + { // get the event listeners + Vector vec = (Vector)(m_update_listeners.get(klass)); + if (vec!=null) + { // call the event handlers + Iterator it = vec.iterator(); + while (it.hasNext()) + ((DynamicUpdateListener)(it.next())).updateReceived(event); + + } // end if + + if (klass==DynamicUpdateEvent.class) + break; + + klass = klass.getSuperclass(); + + } // end for (ever) + + } // end postUpdate + + /*-------------------------------------------------------------------------------- + * Implementations from interface RenderImmediate + *-------------------------------------------------------------------------------- + */ + + public String renderTextObject(Object obj) throws IOException, RenderingException + { + if (logger.isDebugEnabled()) + logger.debug("RenderImmediate rendering an object of type " + obj.getClass().getName()); + BufferTextRenderControl control = new BufferTextRenderControl(wrapOutputServices(null)); + control.renderSubObject(obj); + return control.getData(); + + } // end renderTextObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface RequestPreprocessorRegistration + *-------------------------------------------------------------------------------- + */ + + public ComponentShutdown registerRequestPreprocessor(RequestPreprocessor rp) + { + if (logger.isDebugEnabled()) + logger.debug("Registering new RequestPreprocessor: " + rp); + m_request_preprocessors.add(rp); + return new ShutdownVectorRemove(m_request_preprocessors,rp); + + } // end registerRequestPreprocessor + + /*-------------------------------------------------------------------------------- + * Implementations from interface ExceptionTranslatorRegistration + *-------------------------------------------------------------------------------- + */ + + public ComponentShutdown registerExceptionTranslator(ExceptionTranslator xlat) + { + if (logger.isDebugEnabled()) + logger.debug("Registering new ExceptionTranslator: " + xlat); + m_exception_xlators.add(xlat); + return new ShutdownVectorRemove(m_exception_xlators,xlat); + + } // end registerExceptionTranslator + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + /** + * Adds a reference to the reference count of the ApplicationContainer. Each servlet + * or other initializing component that attempts to initialize the ApplicationContainer + * increases its reference count by 1. + */ + public synchronized void addRef() + { + ++m_refs; + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer.addRef(): refcount now " + m_refs); + + } // end addRef + + /** + * Removes a reference from the reference count of the ApplicationContainer. Each servlet that + * references the ApplicationContainer and is destroyed decreases the reference count by 1. + * When the reference count reaches 0, the ApplicationContainer is destroyed. + * + * @return true if the ApplicationContainer was destroyed, false if not. + */ + public synchronized boolean release() + { + if (--m_refs==0) + { // clean up this stuff + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer.release(): refcount now 0 - destroying!"); + destroy(); + return true; + + } // end if + + if (logger.isDebugEnabled()) + logger.debug("ApplicationContainer.release(): refcount now " + m_refs); + + return false; + + } // end release + + /** + * Returns the instance of the {@link com.silverwrist.dynamo.iface.Application Application} object defined in + * the Dynamo XML configuration file and instantiated when the ApplicationContainer was created. + * + * @return The Application object. + */ + public Application getApplication() + { + return m_application; + + } // end getApplication + + public ServiceProvider getInitServices() + { + return m_app_sm.createInitServices(); + + } // end getInitServices + + public ServiceProvider wrapServices(ServiceProvider sp) + { + return m_app_sm.createRuntimeServices(sp); + + } // end wrapServices + + public ServiceProvider wrapOutputServices(ServiceProvider sp) + { + return m_app_sm.createOutputServices(sp); + + } // end wrapOutputServices + + /** + * Returns a list of all registered {@link com.silverwrist.dynamo.event.SessionInfoListener SessionInfoListener} + * objects. + * + * @return A list of all registered SessionInfoListener objects. + */ + public SessionInfoListener[] getSessionListeners() + { + return (SessionInfoListener[])(m_session_listeners.toArray(SESSION_LISTENER_TEMPLATE)); + + } // end getSessionListeners + + /** + * Adds a session to our list of known sessions, which will be shut down when the application container + * is itself destroyed. + * + * @param link The link to the session. + */ + public void addSessionLink(ComponentShutdown link) + { + m_known_sessions.add(link); + + } // end addSessionLink + + /** + * Removes a session from our list of known sessions, so it will no longer be automatically shut down + * when the application container is itself destroyed. + * + * @param link The link to the session. + */ + public void removeSessionLink(ComponentShutdown link) + { + m_known_sessions.remove(link); + + } // end removeSessionLink + + public void setServerHeader(HttpServletResponse resp) + { + resp.setHeader("Server",m_identity); + + } // end setServerHeader + + public Map getRewriteRuleMap() + { + return m_rewrite_rules; + + } // end getRewriteRuleMap + + public Object filterOutput(Object out, Request r) throws RenderingException + { + Object rc = out; + for (int i=(m_output_filters.size()-1); i>=0; i--) + { // look for new objects that filter this one + OutputObjectFilter filt = (OutputObjectFilter)(m_output_filters.get(i)); + Object tmp_rc = filt.filterObject(rc,r); + if (tmp_rc!=null) + rc = tmp_rc; + + } // end for + + return rc; + + } // end filterOutput + + public void preprocessRequest(Request r) + { + for (int i=(m_request_preprocessors.size()-1); i>=0; i--) + { // preprocess the request, if we have any preprocessors installed + RequestPreprocessor rp = (RequestPreprocessor)(m_request_preprocessors.get(i)); + rp.preprocessRequest(r); + + } // end for + + } // end preprocessRequest + + public Object translateException(Request r, Exception e) + { + for (int i=(m_exception_xlators.size()-1); i>=0; i--) + { // try to translate exceptions + ExceptionTranslator xlat = (ExceptionTranslator)(m_exception_xlators.get(i)); + Object o = xlat.translateException(r,e); + if (o!=null) + return o; // found a translation + + } // end for + + return e; // return the exception itself as a last resort + + } // end translateException + + public String translateSubstratePathName(String input) + { + return StringUtils.replaceAllVariables(input,getSubstrateReplaceMap()); + + } // end translateSubstratePathName + +} // end class ApplicationContainer diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainerMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainerMessages.properties new file mode 100644 index 0000000..17f1c65 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainerMessages.properties @@ -0,0 +1,27 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# --------------------------------------------------------------------------------- +# This file has been localized for the en_US locale +creation.ioError=Unable to read from configuration file {0}. +no.classNotFound=The object class {0} was not found. +no.createError=Unable to create new object of class {0}. +no.notDynamo=The object class {0} is not a valid Dynamo NamedObject, +no.notDBPool=The object class {0} is not a valid Dynamo database connection pool. +no.notApp=The object class {0} is not a valid Dynamo application. +resource.rootErr=The resource root directory {0} does not exist. +mountRP.badName=Invalid mount path for resources: {0} +mountRP.already=Resource provider already mounted on path {0}. +registerRenderer.already=Renderer already registered for class {0}. diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationServiceManager.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationServiceManager.java new file mode 100644 index 0000000..00125f3 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationServiceManager.java @@ -0,0 +1,675 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.util.*; +import org.apache.log4j.Logger; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +class ApplicationServiceManager implements HookServiceProviders +{ + /*-------------------------------------------------------------------------------- + * Internal class implementing initialization services + *-------------------------------------------------------------------------------- + */ + + private class InitServices extends BaseDelegatingServiceProvider + { + /*==================================================================== + * Constructors + *==================================================================== + */ + + InitServices() + { + super("Initialization Services"); + + } // end constructor + + InitServices(ServiceProvider sp) + { + super("Initialization Services",sp); + + } // end constructor + + /*==================================================================== + * Overrides from class BaseDelegatingServiceProvider + *==================================================================== + */ + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass) + { + Object rc = m_init_service_cache.get(klass); + if (rc!=null) // found in the cache! + return rc; + + for (int i=(m_init_service_hooks.size()-1); i>=0; i--) + { // call the hooks + try + { // get hooks in reverse order of installation and try them + ServiceProvider sp = (ServiceProvider)(m_init_service_hooks.get(i)); + rc = sp.queryService(klass); + m_init_service_cache.put(klass,rc); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // cycle around and keep trying + } // end catch + + } // end for + + rc = m_init_services.get(klass); + if (rc!=null) + { // cache the service + m_init_service_cache.put(klass,rc); + return rc; + + } // end if + + return super.queryService(klass); + + } // end queryService + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @param serviceid ID for the service to be requested, to further discriminate between requests. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass, String serviceid) + { + ServiceKey key = new ServiceKey(klass,serviceid); + Object rc = m_init_service_cache.get(key); + if (rc!=null) + return rc; + + for (int i=(m_init_service_hooks.size()-1); i>=0; i--) + { // call the hooks + try + { // get hooks in reverse order of installation and try them + ServiceProvider sp = (ServiceProvider)(m_init_service_hooks.get(i)); + rc = sp.queryService(klass,serviceid); + m_init_service_cache.put(key,rc); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // cycle around and keep trying + } // end catch + + } // end for + + try + { // call through to superclass + return super.queryService(klass,serviceid); + + } // end try + catch (NoSuchServiceException e) + { // OK, try it without the service ID + rc = queryService(klass); + m_init_service_cache.put(key,rc); + return rc; + + } // end catch + + } // end queryService + + } // end class InitServices + + /*-------------------------------------------------------------------------------- + * Internal class implementing runtime services + *-------------------------------------------------------------------------------- + */ + + private class RuntimeServices extends BaseDelegatingServiceProvider + { + /*==================================================================== + * Constructors + *==================================================================== + */ + + RuntimeServices() + { + super("Application Services"); + + } // end constructor + + RuntimeServices(ServiceProvider sp) + { + super("Application Services",sp); + + } // end constructor + + /*==================================================================== + * Overrides from class BaseDelegatingServiceProvider + *==================================================================== + */ + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass) + { + Object rc = m_runtime_service_cache.get(klass); + if (rc!=null) + return rc; + + for (int i=(m_runtime_service_hooks.size()-1); i>=0; i--) + { // call the hooks + try + { // get hooks in reverse order of installation and try them + ServiceProvider sp = (ServiceProvider)(m_runtime_service_hooks.get(i)); + rc = sp.queryService(klass); + m_runtime_service_cache.put(klass,rc); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // cycle around and keep trying + } // end catch + + } // end for + + rc = m_runtime_services.get(klass); + if (rc!=null) + { // cache the service + m_runtime_service_cache.put(klass,rc); + return rc; + + } // end if + + return super.queryService(klass); + + } // end queryService + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @param serviceid ID for the service to be requested, to further discriminate between requests. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass, String serviceid) + { + ServiceKey key = new ServiceKey(klass,serviceid); + Object rc = m_runtime_service_cache.get(key); + if (rc!=null) + return rc; + + for (int i=(m_runtime_service_hooks.size()-1); i>=0; i--) + { // call the hooks + try + { // get hooks in reverse order of installation and try them + ServiceProvider sp = (ServiceProvider)(m_runtime_service_hooks.get(i)); + rc = sp.queryService(klass,serviceid); + m_runtime_service_cache.put(key,rc); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // cycle around and keep trying + } // end catch + + } // end for + + try + { // call through to superclass + return super.queryService(klass,serviceid); + + } // end try + catch (NoSuchServiceException e) + { // OK, try it without the service ID + rc = queryService(klass); + m_runtime_service_cache.put(key,rc); + return rc; + + } // end catch + + } // end queryService + + } // end class RuntimeServices + + /*-------------------------------------------------------------------------------- + * Internal class implementing output services + *-------------------------------------------------------------------------------- + */ + + private class OutputServices extends BaseDelegatingServiceProvider + { + /*==================================================================== + * Constructors + *==================================================================== + */ + + OutputServices() + { + super("Application Output Services"); + + } // end constructor + + OutputServices(ServiceProvider sp) + { + super("Application Output Services",sp); + + } // end constructor + + /*==================================================================== + * Overrides from class BaseDelegatingServiceProvider + *==================================================================== + */ + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass) + { + Object rc = m_output_service_cache.get(klass); + if (rc!=null) + return rc; + + for (int i=(m_output_service_hooks.size()-1); i>=0; i--) + { // call the hooks + try + { // get hooks in reverse order of installation and try them + ServiceProvider sp = (ServiceProvider)(m_output_service_hooks.get(i)); + rc = sp.queryService(klass); + m_output_service_cache.put(klass,rc); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // cycle around and keep trying + } // end catch + + } // end for + + rc = m_output_services.get(klass); + if (rc!=null) + { // cache the service + m_output_service_cache.put(klass,rc); + return rc; + + } // end if + + return super.queryService(klass); + + } // end queryService + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @param serviceid ID for the service to be requested, to further discriminate between requests. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass, String serviceid) + { + ServiceKey key = new ServiceKey(klass,serviceid); + Object rc = m_output_service_cache.get(key); + if (rc!=null) + return rc; + + for (int i=(m_output_service_hooks.size()-1); i>=0; i--) + { // call the hooks + try + { // get hooks in reverse order of installation and try them + ServiceProvider sp = (ServiceProvider)(m_output_service_hooks.get(i)); + rc = sp.queryService(klass,serviceid); + m_output_service_cache.put(key,rc); + return rc; + + } // end try + catch (NoSuchServiceException e) + { // cycle around and keep trying + } // end catch + + } // end for + + try + { // call through to superclass + return super.queryService(klass,serviceid); + + } // end try + catch (NoSuchServiceException e) + { // OK, try it without the service ID + rc = queryService(klass); + m_output_service_cache.put(key,rc); + return rc; + + } // end catch + + } // end queryService + + } // end class OutputServices + + /*-------------------------------------------------------------------------------- + * Internal class implementing removal of init service hook + *-------------------------------------------------------------------------------- + */ + + private class RemoveInitServiceHook implements ComponentShutdown + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private ServiceProvider m_sp; + + /*==================================================================== + * Constructor + *==================================================================== + */ + + RemoveInitServiceHook(ServiceProvider sp) + { + m_sp = sp; + + } // end constructor + + /*==================================================================== + * Implementations from interface ComponentShutdown + *==================================================================== + */ + + public void shutdown() + { + m_init_service_hooks.remove(m_sp); + m_init_service_cache.clear(); + + } // end shutdown + + } // end class RemoveInitServiceHook + + /*-------------------------------------------------------------------------------- + * Internal class implementing removal of runtime service hook + *-------------------------------------------------------------------------------- + */ + + private class RemoveRuntimeServiceHook implements ComponentShutdown + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private ServiceProvider m_sp; + + /*==================================================================== + * Constructor + *==================================================================== + */ + + RemoveRuntimeServiceHook(ServiceProvider sp) + { + m_sp = sp; + + } // end constructor + + /*==================================================================== + * Implementations from interface ComponentShutdown + *==================================================================== + */ + + public void shutdown() + { + m_runtime_service_hooks.remove(m_sp); + m_runtime_service_cache.clear(); + + } // end shutdown + + } // end class RemoveRuntimeServiceHook + + /*-------------------------------------------------------------------------------- + * Internal class implementing removal of output service hook + *-------------------------------------------------------------------------------- + */ + + private class RemoveOutputServiceHook implements ComponentShutdown + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private ServiceProvider m_sp; + + /*==================================================================== + * Constructor + *==================================================================== + */ + + RemoveOutputServiceHook(ServiceProvider sp) + { + m_sp = sp; + + } // end constructor + + /*==================================================================== + * Implementations from interface ComponentShutdown + *==================================================================== + */ + + public void shutdown() + { + m_output_service_hooks.remove(m_sp); + m_output_service_cache.clear(); + + } // end shutdown + + } // end class RemoveOutputServiceHook + + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(ApplicationServiceManager.class); + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private Hashtable m_init_services = new Hashtable(); // initializing services + private Vector m_init_service_hooks = new Vector(); // hooks for initializing services + private Hashtable m_init_service_cache = new Hashtable(); // cache of init services + private Hashtable m_runtime_services = new Hashtable(); // runtime services + private Vector m_runtime_service_hooks = new Vector(); // hooks for runtime services + private Hashtable m_runtime_service_cache = new Hashtable(); // cache of runtime services + private Hashtable m_output_services = new Hashtable(); // output services + private Vector m_output_service_hooks = new Vector(); // hooks for output services + private Hashtable m_output_service_cache = new Hashtable(); // cache of output services + private InitServices m_solo_init = null; // only one "null" init service + private RuntimeServices m_solo_runtime = null; // only one "null" runtime service + private OutputServices m_solo_output = null; // only one "null" output service + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + ApplicationServiceManager() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface HookServiceProviders + *-------------------------------------------------------------------------------- + */ + + public ServiceProvider getCurrentInitServices() + { + return createInitServices(); + + } // end getCurrentInitServices + + public ServiceProvider getCurrentRuntimeServices() + { + return createRuntimeServices(); + + } // end getCurrentRuntimeServices + + public ServiceProvider getCurrentOutputServices() + { + return createOutputServices(); + + } // end getCurrentOutputServices + + public ComponentShutdown hookInitServiceProvider(ServiceProvider sp) + { + m_init_service_hooks.add(sp); + m_init_service_cache.clear(); + return new RemoveInitServiceHook(sp); + + } // end hookInitServiceProvider + + public ComponentShutdown hookRuntimeServiceProvider(ServiceProvider sp) + { + m_runtime_service_hooks.add(sp); + m_runtime_service_cache.clear(); + return new RemoveRuntimeServiceHook(sp); + + } // end hookRuntimeServiceProvider + + public ComponentShutdown hookOutputServiceProvider(ServiceProvider sp) + { + m_output_service_hooks.add(sp); + m_output_service_cache.clear(); + return new RemoveOutputServiceHook(sp); + + } // end hookOutputServiceProvider + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + void addInitService(Class klass, Object svc) + { + m_init_services.put(klass,svc); + + } // end addInitService + + void addRuntimeService(Class klass, Object svc) + { + m_runtime_services.put(klass,svc); + + } // end addRuntimeService + + void addOutputService(Class klass, Object svc) + { + m_output_services.put(klass,svc); + + } // end addRuntimeService + + ServiceProvider createInitServices() + { + if (m_solo_init==null) + m_solo_init = new InitServices(); + return m_solo_init; + + } // end createInitServices + + ServiceProvider createInitServices(ServiceProvider sp) + { + if (sp==null) + return createInitServices(); + return new InitServices(sp); + + } // end createRuntimeServices + + ServiceProvider createRuntimeServices() + { + if (m_solo_runtime==null) + m_solo_runtime = new RuntimeServices(); + return m_solo_runtime; + + } // end createRuntimeServices + + ServiceProvider createRuntimeServices(ServiceProvider sp) + { + if (sp==null) + return createRuntimeServices(); + return new RuntimeServices(sp); + + } // end createRuntimeServices + + ServiceProvider createOutputServices() + { + if (m_solo_output==null) + m_solo_output = new OutputServices(); + return m_solo_output; + + } // end createOutputServices + + ServiceProvider createOutputServices(ServiceProvider sp) + { + if (sp==null) + return createOutputServices(); + return new OutputServices(sp); + + } // end createOutputServices + +} // end class ApplicationServiceManager diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/BackgroundProcessor.java b/src/dynamo-framework/com/silverwrist/dynamo/app/BackgroundProcessor.java new file mode 100644 index 0000000..d44f228 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/BackgroundProcessor.java @@ -0,0 +1,490 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.util.*; +import org.apache.log4j.Logger; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +/** + * A class used internally by the {@link com.silverwrist.dynamo.app.ApplicationContainer ApplicationContainer} + * to handle background execution of tasks. It implements the + * {@link com.silverwrist.dynamo.iface.BackgroundScheduler BackgroundScheduler} service. + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +class BackgroundProcessor implements BackgroundScheduler, ComponentShutdown +{ + /*-------------------------------------------------------------------------------- + * Internal thread class for scheduling normal-priority background tasks + *-------------------------------------------------------------------------------- + */ + + private class NormalPriorityThread extends Thread + { + /*==================================================================== + * Constructor + *==================================================================== + */ + + NormalPriorityThread(int index) + { + super("BG-Normal-" + index); + setPriority(NORM_PRIORITY); + + } // end constructor + + /*==================================================================== + * Overrides from class Thread + *==================================================================== + */ + + public void run() + { + while (m_running) + { // get tasks then execute them + BackgroundTask task = null; + synchronized (m_normal_sync) + { // test and remove from normal queue + boolean get_task = true; + while (get_task && m_normal_queue.isEmpty()) + { // nothing to run right now... + try + { // sleep waiting for a new background task + m_normal_sync.wait(); + + } // end try + catch (InterruptedException e) + { // don't bother getting a task + get_task = false; + + } // end catch + + } // end if + + if (get_task) + task = (BackgroundTask)(m_normal_queue.removeFirst()); + + } // end synchronized block + + if (task!=null) + { // found a task to run, now execute it + try + { // run the task + task.run(m_services); + task = null; + + } // end try + catch (Exception e) + { // whoops! don't let this stop us + logger.warn("BackgroundTask threw exception",e); + + } // end catch + + } // end if + + } // end while + + } // end run + + } // end class NormalPriorityThread + + /*-------------------------------------------------------------------------------- + * Internal thread class for scheduling low-priority background tasks + *-------------------------------------------------------------------------------- + */ + + private class LowPriorityThread extends Thread + { + /*==================================================================== + * Constructor + *==================================================================== + */ + + LowPriorityThread(int index) + { + super("BG-Low-" + index); + setPriority(MIN_PRIORITY); + + } // end constructor + + /*==================================================================== + * Overrides from class Thread + *==================================================================== + */ + + public void run() + { + while (m_running) + { // get tasks then execute them + BackgroundTask task = null; + synchronized (m_lp_sync) + { // test and remove from normal queue + boolean get_task = true; + while (get_task && m_lp_queue.isEmpty()) + { // nothing to run right now... + try + { // sleep waiting for a new background task + m_lp_sync.wait(); + + } // end try + catch (InterruptedException e) + { // don't bother getting a task + get_task = false; + + } // end catch + + } // end if + + // Get the task we waited for. + if (get_task) + task = (BackgroundTask)(m_lp_queue.removeFirst()); + + } // end synchronized block + + if (task!=null) + { // found a task to run, now execute it + try + { // run the task + task.run(m_services); + task = null; + + } // end try + catch (Exception e) + { // whoops! don't let this stop us + logger.warn("BackgroundTask threw exception",e); + + } // end catch + + } // end if + + } // end while + + } // end run + + } // end class LowPriorityThread + + /*-------------------------------------------------------------------------------- + * Internal class for timer operations + *-------------------------------------------------------------------------------- + */ + + private class MyTimerTask extends TimerTask implements ComponentShutdown + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private BackgroundTask m_task; + + /*==================================================================== + * Constructor + *==================================================================== + */ + + MyTimerTask(BackgroundTask task) + { + super(); + m_task = task; + + } // end constructor + + /*==================================================================== + * Overrides from class TimerTask + *==================================================================== + */ + + public void run() + { + try + { // run the task + m_task.run(m_services); + + } // end try + catch (Exception e) + { // whoops! don't let this stop us + logger.warn("BackgroundTask threw exception",e); + + } // end catch + + } // end run + + /*==================================================================== + * Implementations from interface ComponentShutdown + *==================================================================== + */ + + /** + * Shuts down the component associated with this interface, in a component-specific manner. + */ + public void shutdown() + { + cancel(); + + } // end shutdown + + } // end class MyTimerTask + + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(BackgroundProcessor.class); + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private ServiceProvider m_services; + private volatile boolean m_running = true; + private Object m_normal_sync = new Object(); + private LinkedList m_normal_queue = new LinkedList(); + private Thread[] m_normal_threads; + private Object m_lp_sync = new Object(); + private LinkedList m_lp_queue = new LinkedList(); + private Thread[] m_lp_threads; + private Timer m_timer; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs the instance of the BackgroundProcessor internal to the + * {@link com.silverwrist.dynamo.app.ApplicationContainer ApplicationContainer}. + * + * @param num_normal_threads Number of "normal" threads in our runtime thread pool. + * @param num_lp_threads Number of "low priority" threads in our runtime thread pool. + * @param services The {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} to be supplied + * to all {@link com.silverwrist.dynamo.iface.BackgroundTask BackgroundTask}s. + */ + BackgroundProcessor(int num_norm_threads, int num_lp_threads, ServiceProvider services) + { + m_services = new SingletonServiceProvider("BackgroundProcessor",services,BackgroundScheduler.class,this); + + // Create the normal priority background threads. + m_normal_threads = new Thread[num_norm_threads]; + int i; + for (i=0; itrue, the task is handled by a pool of low-priority threads + * instead of by a pool of normal-priority threads. Low-priority threads will generally + * execute only after normal-priority threads, but are not guaranteed to. + */ + public void runTaskLater(BackgroundTask task, boolean low_priority) + { + if (low_priority) + { // add to low priority queue + synchronized (m_lp_sync) + { // add item and notify a thread to wake up + m_lp_queue.addLast(task); + m_lp_sync.notify(); + + } // end synchronized block + + } // end if + else + { // add to normal queue + synchronized (m_normal_sync) + { // add item and notify a thread to wake up + m_normal_queue.addLast(task); + m_normal_sync.notify(); + + } // end synchronized block + + } // end else + + } // end runTaskLater + + /** + * Schedule a task to be run on a one-shot basis after a delay. + * + * @param task The task to be scheduled to run. + * @param delay The delay, in milliseconds, before this task is to be run. The actual delay may be longer + * than this. + * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object, + * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be + * called to abort the execution of this task at any time before it is actually run. If this is called + * after the task is run, it has no effect. + */ + public ComponentShutdown runTaskAfter(BackgroundTask task, long delay) + { + MyTimerTask my_task = new MyTimerTask(task); + m_timer.schedule(my_task,delay); + return my_task; + + } // end runTaskAfter + + /** + * Schedule a task to be run on a one-shot basis at a certain time. + * + * @param task The task to be scheduled to run. + * @param when The date/time at which the task is to be run. The actual task start time may be any time + * after this. + * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object, + * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be + * called to abort the execution of this task at any time before it is actually run. If this is called + * after the task is run, it has no effect. + */ + public ComponentShutdown runTaskAt(BackgroundTask task, Date when) + { + MyTimerTask my_task = new MyTimerTask(task); + m_timer.schedule(my_task,when); + return my_task; + + } // end runTaskAt + + /** + * Schedule a task to be run periodically, after a delay. + * + * @param task The task to be scheduled to run. + * @param delay The delay, in milliseconds, before this task is to be run for the first time. The actual + * delay may be longer than this. + * @param period The time, in milliseconds, between successive executions of the task. The task will be + * scheduled for repeated execution, delaying at least this long between executions. + * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object, + * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be + * called to abort the periodic execution of this task at any time. + */ + public ComponentShutdown runTaskPeriodic(BackgroundTask task, long delay, long period) + { + MyTimerTask my_task = new MyTimerTask(task); + m_timer.schedule(my_task,delay,period); + return my_task; + + } // end runTaskPeriodic + + /** + * Schedule a task to be run periodically, beginning at a specified time. + * + * @param task The task to be scheduled to run. + * @param when The date/time at which the task is to be run for the first time. The actual task start time + * may be any time after this. + * @param period The time, in milliseconds, between successive executions of the task. The task will be + * scheduled for repeated execution, delaying at least this long between executions. + * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object, + * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be + * called to abort the periodic execution of this task at any time. + */ + public ComponentShutdown runTaskPeriodic(BackgroundTask task, Date start, long period) + { + MyTimerTask my_task = new MyTimerTask(task); + m_timer.schedule(my_task,start,period); + return my_task; + + } // end runTaskPeriodic + + /** + * Schedule a task to be run periodically, after a delay. + * + * @param task The task to be scheduled to run. + * @param delay The delay, in milliseconds, before this task is to be run for the first time. The actual + * delay may be longer than this. + * @param period The time, in milliseconds, between successive executions of the task. The task will be + * scheduled for repeated execution, with the task being started with roughly this many + * milliseconds between each start attempt. If execution is delayed, this task will try to + * "catch up" by scheduling executions more frequently. + * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object, + * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be + * called to abort the periodic execution of this task at any time. + */ + public ComponentShutdown runTaskFixedRate(BackgroundTask task, long delay, long period) + { + MyTimerTask my_task = new MyTimerTask(task); + m_timer.scheduleAtFixedRate(my_task,delay,period); + return my_task; + + } // end runTaskFixedRate + + /** + * Schedule a task to be run periodically, beginning at a specified time. + * + * @param task The task to be scheduled to run. + * @param when The date/time at which the task is to be run for the first time. The actual task start time + * may be any time after this. + * @param period The time, in milliseconds, between successive executions of the task. The task will be + * scheduled for repeated execution, with the task being started with roughly this many + * milliseconds between each start attempt. If execution is delayed, this task will try to + * "catch up" by scheduling executions more frequently. + * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object, + * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be + * called to abort the periodic execution of this task at any time. + */ + public ComponentShutdown runTaskFixedRate(BackgroundTask task, Date start, long period) + { + MyTimerTask my_task = new MyTimerTask(task); + m_timer.scheduleAtFixedRate(my_task,start,period); + return my_task; + + } // end runTaskFixedRate + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentShutdown + *-------------------------------------------------------------------------------- + */ + + /** + * Shuts down the BackgroundProcessor, stopping all its associated threads and tasks. + */ + public void shutdown() + { + m_timer.cancel(); + m_running = false; + int i; + for (i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; + +class ComponentResName +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String[] m_components; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + ComponentResName(String resource_path) + { + if (!(resource_path.startsWith("/"))) + throw new NoSuchResourceException(resource_path); + m_components = StringUtils.split(resource_path.substring(1),"/"); + if ((m_components==null) || (m_components.length==0)) + throw new NoSuchResourceException(resource_path); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class Object + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object obj) + { + if ((obj==null) || !(obj instanceof ComponentResName)) + return false; + ComponentResName other = (ComponentResName)obj; + if (m_components.length!=other.m_components.length) + return false; + return (getMatchCount(other)==m_components.length); + + } // end equals + + public int hashCode() + { + int rc = 0; + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +public class ConnectionManager implements NamedObject, ComponentInitialize, ComponentShutdown +{ + /*-------------------------------------------------------------------------------- + * Internal class implementing the initialization service hook + *-------------------------------------------------------------------------------- + */ + + private class InitService implements ServiceProvider, ConnectionFrontEnd, ConnectionBackEnd + { + /*==================================================================== + * Constructor + *==================================================================== + */ + + InitService() + { // do nothing + } // end constructor + + /*==================================================================== + * Implementations from interface ServiceProvider + *==================================================================== + */ + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass) + { + if (klass==ConnectionFrontEnd.class) + return (ConnectionFrontEnd)this; + if (klass==ConnectionBackEnd.class) + return (ConnectionBackEnd)this; + throw new NoSuchServiceException("ConnectionManager.InitService",klass); + + } // end queryService + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @param serviceid ID for the service to be requested, to further discriminate between requests. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass, String serviceid) + { + if (klass==ConnectionFrontEnd.class) + return (ConnectionFrontEnd)this; + if (klass==ConnectionBackEnd.class) + return (ConnectionBackEnd)this; + throw new NoSuchServiceException("ConnectionManager.InitService",klass,serviceid); + + } // end queryService + + /*==================================================================== + * Implementations from interface ConnectionFrontEnd + *==================================================================== + */ + + public Object getInterface(String connection_point, Class expected_class) throws ConfigException + { + return getConnectionPoint(connection_point).getInterface(expected_class); + + } // end getInterface + + /*==================================================================== + * Implementations from interface ConnectionBackEnd + *==================================================================== + */ + + public void connectObject(String connection_point, Object object) throws ConfigException + { + getConnectionPoint(connection_point).connectObject(object); + + } // end connectObject + + } // end class InitService + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_name; + private Hashtable m_connection_points = new Hashtable(); + private ComponentShutdown m_shutdown_hook; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public ConnectionManager() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final ConnectionPoint getConnectionPoint(String name) throws ConfigException + { + ConnectionPoint rc = (ConnectionPoint)(m_connection_points.get(name)); + if (rc!=null) + return rc; + ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","cpoint.notFound"); + ce.setParameter(0,name); + throw ce; + + } // end getConnectionPoint + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamedObject + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentInitialize + *-------------------------------------------------------------------------------- + */ + + public void initialize(Element config_root, ServiceProvider services) throws ConfigException + { + XMLLoader loader = XMLLoader.get(); + try + { // verify the right node name + loader.verifyNodeName(config_root,"object"); + + // get the object's name + m_name = loader.getAttribute(config_root,"name"); + + // get the connection points list and try to load them + List l = loader.getMatchingSubElements(config_root,"connection-point"); + Iterator it = l.iterator(); + while (it.hasNext()) + { // create the connection points + Element elt = (Element)(it.next()); + ConnectionPoint cpoint = new ConnectionPoint(elt); + m_connection_points.put(cpoint.getName(),cpoint); + + } // end while + + } // end try + catch (XMLLoadException e) + { // error loading XML config data + throw new ConfigException(e); + + } // end catch + + // Hook the init service provider to provide our services. + HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class)); + m_shutdown_hook = hooker.hookInitServiceProvider(new InitService()); + + } // end initialize + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentShutdown + *-------------------------------------------------------------------------------- + */ + + public void shutdown() + { + m_shutdown_hook.shutdown(); + + Iterator it = m_connection_points.values().iterator(); + while (it.hasNext()) + { // shut down those connection points + ComponentShutdown cs = (ComponentShutdown)(it.next()); + cs.shutdown(); + + } // end while + + m_connection_points.clear(); + + } // end shutdown + +} // end class ConnectionManager diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionMessages.properties new file mode 100644 index 0000000..e0b4242 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionMessages.properties @@ -0,0 +1,23 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# --------------------------------------------------------------------------------- +# This file has been localized for the en_US locale +cpoint.noInterface=Unable to find the connection point interface class "{0}". +cpoint.notValid=The connection point class "{0}" is not a valid interface. +iface.type=Connection point "{0}"'s interface type {1} cannot be assigned to the desired type {2}. +connect.already=The connection point "{0}" has already been connected. +connect.wrongType=The connection point "{0}" expects to connect to an object of type {1}. +cpoint.notFound=No connection point "{0}" defined. diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionPoint.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionPoint.java new file mode 100644 index 0000000..91d35e3 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionPoint.java @@ -0,0 +1,179 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.lang.reflect.*; +import org.w3c.dom.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +class ConnectionPoint implements NamedObject, InvocationHandler, ComponentShutdown +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_name; // name of this connection point + private Class m_interface; // interface associated with this connection point + private Object m_proxy_obj; // proxy object that provides the "head end" of the cpoint + private Object m_target_obj = null; // object on the "tail end" of the cpoint + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + ConnectionPoint(Element config) throws ConfigException + { + XMLLoader loader = XMLLoader.get(); + String iface_name = null; + try + { // verify the right node name + loader.verifyNodeName(config,"connection-point"); + + // get the connection point's name + m_name = loader.getAttribute(config,"name"); + + // get the interface represented by this proxy + iface_name = loader.getAttribute(config,"interface"); + m_interface = Class.forName(iface_name); + if (!(m_interface.isInterface())) + { // the class name does not specify an interface + ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages", + "cpoint.notValid"); + ce.setParameter(0,iface_name); + throw ce; + + } // end if + + // Create the proxy object. + Class[] arg = new Class[1]; + arg[0] = m_interface; + m_proxy_obj = Proxy.newProxyInstance(m_interface.getClassLoader(),arg,this); + + } // end try + catch (XMLLoadException e) + { // error loading XML config data + throw new ConfigException(e); + + } // end catch + catch (ClassNotFoundException e) + { // unable to find the interface + ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages", + "cpoint.noInterface",e); + ce.setParameter(0,iface_name); + throw ce; + + } // end catch + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamedObject + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface InvocationHandler + *-------------------------------------------------------------------------------- + */ + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + if (m_target_obj==null) + throw new ProxyException(new NullPointerException("target not yet connected for " + m_name + "/" + + m_interface.getName())); + try + { // invoke the method on the real target! + return method.invoke(m_target_obj,args); + + } // end try + catch (IllegalAccessException e) + { // turn into the runtime ProxyException + throw new ProxyException(e); + + } // end catch + catch (InvocationTargetException e) + { // "unwrap" this exception type and throw it + throw e.getCause(); + + } // end catch + + } // end invoke + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentShutdown + *-------------------------------------------------------------------------------- + */ + + public void shutdown() + { + m_proxy_obj = null; + m_target_obj = null; + + } // end shutdown + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + Object getInterface(Class expected_class) throws ConfigException + { + if (expected_class.isAssignableFrom(m_interface)) + return m_proxy_obj; + ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","iface.type"); + ce.setParameter(0,m_name); + ce.setParameter(1,m_interface.getName()); + ce.setParameter(2,expected_class.getName()); + throw ce; + + } // end getInterface + + synchronized void connectObject(Object obj) throws ConfigException + { + if (m_target_obj!=null) + { // this connection point has already been connected + ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","connect.already"); + ce.setParameter(0,m_name); + throw ce; + + } // end if + + if (!(m_interface.isInstance(obj))) + { // the object is of the wrong type + ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","connect.wrongType"); + ce.setParameter(0,m_name); + ce.setParameter(1,m_interface.getName()); + throw ce; + + } // end if + + m_target_obj = obj; + + } // end connectObject + +} // end class ConnectionPoint diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/DataItemRenderer.java b/src/dynamo-framework/com/silverwrist/dynamo/app/DataItemRenderer.java new file mode 100644 index 0000000..5790572 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/DataItemRenderer.java @@ -0,0 +1,52 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.io.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.RenderingException; +import com.silverwrist.dynamo.iface.*; + +class DataItemRenderer implements BinaryRenderer +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + DataItemRenderer() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface BinaryRenderer + *-------------------------------------------------------------------------------- + */ + + public void render(Object obj, BinaryRenderControl control) throws IOException, RenderingException + { + DataItem di = (DataItem)obj; + control.setContentType(di.getMimeType()); + control.setContentLength(di.getSize()); + OutputStream stm = control.getStream(); + IOUtils.copy(di.getDataStream(),stm); + stm.flush(); + + } // end render + +} // end class DataItemRenderer diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/HeapContents.java b/src/dynamo-framework/com/silverwrist/dynamo/app/HeapContents.java new file mode 100644 index 0000000..e1a07a3 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/HeapContents.java @@ -0,0 +1,88 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import org.w3c.dom.Element; +import com.silverwrist.util.xml.*; + +class HeapContents implements Comparable +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + Element m_elt; // element we're sorting + int m_priority; // its priority + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + HeapContents(Element elt) throws XMLLoadException + { + m_elt = elt; + m_priority = XMLLoader.get().getAttributeInt(elt,"priority",0); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class Object + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object o) + { + if (!(o instanceof HeapContents)) + return false; + HeapContents other = (HeapContents)o; + return (m_priority==other.m_priority); + + } // end equals + + public int hashCode() + { + return m_priority; + + } // end hashCode + + /*-------------------------------------------------------------------------------- + * Implementations from interface Comparable + *-------------------------------------------------------------------------------- + */ + + public int compareTo(Object o) + { + HeapContents other = (HeapContents)o; // may throw ClassCastException + return m_priority - other.m_priority; + + } // end compareTo + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + Element getElement() + { + return m_elt; + + } // end getElement + +} // end class HeapContents diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ListRenderer.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ListRenderer.java new file mode 100644 index 0000000..4075d2e --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ListRenderer.java @@ -0,0 +1,50 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.io.IOException; +import java.util.*; +import com.silverwrist.dynamo.except.RenderingException; +import com.silverwrist.dynamo.iface.*; + +class ListRenderer implements TextRenderer +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + ListRenderer() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface TextRenderer + *-------------------------------------------------------------------------------- + */ + + public void render(Object obj, TextRenderControl control) throws IOException, RenderingException + { + List list = (List)obj; + Iterator it = list.iterator(); + while (it.hasNext()) + control.renderSubObject(it.next()); + + } // end render + +} // end class ListRenderer diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/PropertySerializationSupport.java b/src/dynamo-framework/com/silverwrist/dynamo/app/PropertySerializationSupport.java new file mode 100644 index 0000000..bcff801 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/PropertySerializationSupport.java @@ -0,0 +1,270 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.text.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +class PropertySerializationSupport implements PropertySerializer, PropertySerializerRegistration +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final Map SIMPLE_TYPE_SERIALIZE; + + private static final DateFormat s_iso8601; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private static Vector m_extern_calls = new Vector(); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + PropertySerializationSupport() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final String builtinSerialize(Object value) + { + String prefix = (String)(SIMPLE_TYPE_SERIALIZE.get(value.getClass())); + if (prefix!=null) + return prefix + value.toString(); + + if (value instanceof Boolean) + return (((Boolean)value).booleanValue() ? "Y" : "Z"); + + if (value instanceof java.util.Date) + return "T" + s_iso8601.format((java.util.Date)value); + + if (value instanceof TimeZone) + return "_TZ:" + ((TimeZone)value).getID(); + + if (value instanceof Language) + return "_LANG:" + ((Language)value).getCode(); + + if (value instanceof Country) + return "_CTRY:" + ((Country)value).getCode(); + + if (value instanceof OptionSet) + return "_OS:" + ((OptionSet)value).asString(); + + return null; + + } // end builtInSerialize + + private final Object extendedDecode(String s) + { + if (s.startsWith("_LOC:")) + { // need to break down + s = s.substring(5); + int p = s.indexOf('_'); + if (p>=0) + { // language + country, maybe + variant + String language = s.substring(0,p); + s = s.substring(p+1); + p = s.indexOf('_'); + if (p>=0) + return new Locale(language,s.substring(0,p),s.substring(p+1)); + else + return new Locale(language,s); + + } // end if + else // just language + return new Locale(s); + + } // end if + else if (s.startsWith("_TZ:")) + return TimeZone.getTimeZone(s.substring(4)); + else if (s.startsWith("_LANG:")) + return International.get().getLanguageForCode(s.substring(6)); + else if (s.startsWith("_CTRY:")) + return International.get().getCountryForCode(s.substring(6)); + else if (s.startsWith("_OS:")) + return new OptionSet(s.substring(4)); + else + return null; + + } // end extendedDecode + + /*-------------------------------------------------------------------------------- + * Implementations from interface PropertySerializer + *-------------------------------------------------------------------------------- + */ + + public String serializeProperty(Object value) + { + if (value==null) + return null; + + String rc = builtinSerialize(value); + if (rc!=null) + return rc; + + Iterator it = m_extern_calls.iterator(); + while (it.hasNext()) + { // try the external serializers + PropertySerializer psz = (PropertySerializer)(it.next()); + rc = psz.serializeProperty(value); + if (rc!=null) + return "." + rc; + + } // end while + + return null; // cannot serialize + + } // end serializeProperty + + public Object deserializeProperty(String value) + { + if (value==null) + return null; + + try + { // the first character is the flag... + switch (value.charAt(0)) + { + case 'B': + return new Byte(value.substring(1)); + + case 'C': + return new Character(value.charAt(1)); + + case 'D': + return new Double(value.substring(1)); + + case 'F': + return new Float(value.substring(1)); + + case 'I': + return new Integer(value.substring(1)); + + case 'J': + return new Long(value.substring(1)); + + case 'S': + return new Short(value.substring(1)); + + case 'T': + return s_iso8601.parse(value.substring(1)); + + case 'Y': + return Boolean.TRUE; + + case 'Z': + return Boolean.FALSE; + + case '!': + return value.substring(1); + + case '_': + return extendedDecode(value); + + case '.': + { // run through the external decoders + String s = value.substring(1); + Iterator it = m_extern_calls.iterator(); + while (it.hasNext()) + { // try the external serializers + PropertySerializer psz = (PropertySerializer)(it.next()); + Object rc = psz.deserializeProperty(s); + if (rc!=null) + return rc; + + } // end while + + } // end case + break; + + default: + break; + + } // end switch + + } // end try + catch (ParseException e) + { // if we threw this, we're h0s3d anyway + return null; + + } // end catch + + return null; + + } // end deserializeProperty + + /*-------------------------------------------------------------------------------- + * Implementations from interface PropertySerializerRegistration + *-------------------------------------------------------------------------------- + */ + + public ComponentShutdown registerPropertySerializer(PropertySerializer psz) + { + m_extern_calls.add(psz); + return new ShutdownVectorRemove(m_extern_calls,psz); + + } // end registerPropertySerializer + + /*-------------------------------------------------------------------------------- + * Static initializer + *-------------------------------------------------------------------------------- + */ + + static + { + HashMap tmp = new HashMap(); + tmp.put(Byte.class,"B"); + tmp.put(Byte.TYPE,"B"); + tmp.put(Character.class,"C"); + tmp.put(Character.TYPE,"C"); + tmp.put(Double.class,"D"); + tmp.put(Double.TYPE,"D"); + tmp.put(Float.class,"F"); + tmp.put(Float.TYPE,"F"); + tmp.put(Integer.class,"I"); + tmp.put(Integer.TYPE,"I"); + tmp.put(Long.class,"J"); + tmp.put(Long.TYPE,"J"); + tmp.put(Short.class,"S"); + tmp.put(Short.TYPE,"S"); + tmp.put(String.class,"!"); + tmp.put(StringBuffer.class,"!"); + tmp.put(Locale.class,"_LOC:"); + SIMPLE_TYPE_SERIALIZE = Collections.unmodifiableMap(tmp); + + SimpleDateFormat iso = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss"); + iso.setCalendar(new GregorianCalendar(new SimpleTimeZone(0,"UTC"))); + s_iso8601 = iso; + + } // end static initializer + +} // end class PropertySerializationSupport diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/RewriteRule.java b/src/dynamo-framework/com/silverwrist/dynamo/app/RewriteRule.java new file mode 100644 index 0000000..bea9837 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/RewriteRule.java @@ -0,0 +1,71 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import org.w3c.dom.*; +import com.silverwrist.util.xml.*; + +public class RewriteRule +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_name; + private boolean m_encode; + private String m_template; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + RewriteRule(Element elt) throws XMLLoadException + { + XMLLoader loader = XMLLoader.get(); + m_name = loader.getAttribute(elt,"type").trim().toUpperCase(); + m_encode = loader.getAttributeBoolean(elt,"encode"); + m_template = loader.getText(elt); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Public getters + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + public boolean getEncode() + { + return m_encode; + + } // end getEncode + + public String getTemplate() + { + return m_template; + + } // end getTemplate + +} // end class RewriteRule diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ServiceKey.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ServiceKey.java new file mode 100644 index 0000000..1eeeddb --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ServiceKey.java @@ -0,0 +1,62 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +class ServiceKey +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private Class m_class; + private String m_serviceid; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + ServiceKey(Class klass, String serviceid) + { + m_class = klass; + m_serviceid = serviceid; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class Object + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object obj) + { + if ((obj==null) || !(obj instanceof ServiceKey)) + return false; + ServiceKey other = (ServiceKey)obj; + return (m_class==other.m_class) && m_serviceid.equals(other.m_serviceid); + + } // end equals + + public int hashCode() + { + return m_class.hashCode() ^ m_serviceid.hashCode(); + + } // end hashCode + +} // end class ServiceKey diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/WrappedResourceProvider.java b/src/dynamo-framework/com/silverwrist/dynamo/app/WrappedResourceProvider.java new file mode 100644 index 0000000..c2346be --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/WrappedResourceProvider.java @@ -0,0 +1,98 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.app; + +import java.io.InputStream; +import java.io.IOException; +import com.silverwrist.dynamo.except.NoSuchResourceException; +import com.silverwrist.dynamo.iface.ResourceProvider; + +class WrappedResourceProvider +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private ComponentResName m_mount_point; + private ResourceProvider m_provider; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + WrappedResourceProvider(ComponentResName mount_point, ResourceProvider provider) + { + m_mount_point = mount_point; + m_provider = provider; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class Object + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object obj) + { + if ((obj==null) || !(obj instanceof WrappedResourceProvider)) + return false; + WrappedResourceProvider other = (WrappedResourceProvider)obj; + return m_mount_point.equals(other.m_mount_point); + + } // end equals + + public int hashCode() + { + return m_mount_point.hashCode(); + + } // end hashCode + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + int getMatchCount(ComponentResName crn) + { + int rc = m_mount_point.getMatchCount(crn); + if (rc!=m_mount_point.getComponentCount()) + return -1; + return rc; + + } // end getMatchCount + + InputStream getResource(ComponentResName crn) throws IOException + { + if (m_mount_point.getMatchCount(crn)!=m_mount_point.getComponentCount()) + throw new NoSuchResourceException(crn.getStringValue(0,true)); + return m_provider.getResource(crn.getStringValue(m_mount_point.getComponentCount(),true)); + + } // end getResource + + long getResourceModTime(ComponentResName crn) + { + if (m_mount_point.getMatchCount(crn)!=m_mount_point.getComponentCount()) + return 0; + return m_provider.getResourceModTime(crn.getStringValue(m_mount_point.getComponentCount(),true)); + + } // end getResourceModTime + +} // end class WrappedResourceProvider + diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl.java new file mode 100644 index 0000000..17c032c --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl.java @@ -0,0 +1,141 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.lang.reflect.*; +import java.sql.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.iface.DBUtilities; + +abstract class DBUtilitiesImpl implements DBUtilities +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final Class[] ARGS_TYPE = new Class[0]; + private static final Object[] ARGS = new Object[0]; + + private static final String SQL_WILDCARD_CHARS = "%_'"; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected DBUtilitiesImpl() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface DBUtilities + *-------------------------------------------------------------------------------- + */ + + public String encodeString(String data) + { + if (data==null) + return null; // safety feature + int ndx = data.indexOf('\''); + if (ndx<0) + return data; + StringBuffer buf = new StringBuffer(); + while (ndx>=0) + { // convert each single quote mark to a pair of them + if (ndx>0) + buf.append(data.substring(0,ndx)); + buf.append("''"); + data = data.substring(ndx+1); + ndx = data.indexOf('\''); + + } // end while + + buf.append(data); + return buf.toString(); + + } // end encodeString + + public String encodeStringWildcards(String data) + { + if (data==null) + return null; // safety feature + AnyCharMatcher nhc = new AnyCharMatcher(SQL_WILDCARD_CHARS); + int ndx = nhc.get(data); + if (ndx<0) + return data; // trivial short-circuit case + StringBuffer buf = new StringBuffer(); + while (ndx>=0) + { // append the matched "head" and then the encoded character + if (ndx>0) + buf.append(data.substring(0,ndx)); + switch (data.charAt(ndx++)) + { + case '%': + buf.append("\\%"); + break; + + case '_': + buf.append("\\_"); + break; + + case '\'': + buf.append("\'\'"); + break; + + } // end switch + + if (ndx==data.length()) + return buf.toString(); // munched the entire string - all done! + data = data.substring(ndx); + ndx = nhc.get(data); + + } // end while + + buf.append(data); // append the unmatched tail + return buf.toString(); + + } // end encodeStringWildcards + + /*-------------------------------------------------------------------------------- + * Abstract declarations from interface DBUtilities + *-------------------------------------------------------------------------------- + */ + + public abstract java.util.Date getDateTime(ResultSet rs, String column) throws SQLException; + + public abstract java.util.Date getDateTime(ResultSet rs, int column) throws SQLException; + + public abstract void setDateTime(PreparedStatement stmt, int index, java.util.Date date) throws SQLException; + + public abstract void testDatabase(Connection conn) throws SQLException; + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + public static DBUtilities get(String type) throws Exception + { + String impl_class_name = DBUtilitiesImpl.class.getName() + "_" + type.toLowerCase(); + Method m = Class.forName(impl_class_name).getMethod("get",ARGS_TYPE); + return (DBUtilities)(m.invoke(null,ARGS)); + + } // end get + +} // end class DBUtilitiesImpl diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl_mysql.java new file mode 100644 index 0000000..9a8971e --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl_mysql.java @@ -0,0 +1,201 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import com.silverwrist.util.SQLUtils; +import com.silverwrist.dynamo.iface.DBUtilities; + +public class DBUtilitiesImpl_mysql extends DBUtilitiesImpl +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static DBUtilitiesImpl_mysql _self = null; + + // used to convert dates and times to UTC for sending to SQL + private static SimpleTimeZone utc = new SimpleTimeZone(0,"UTC"); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + private DBUtilitiesImpl_mysql() + { + super(); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + /** + * Converts a date-and-time string (an SQL DATETIME value) to a standard Java date. + * + * @param dstr The date-and-time string to convert, presumed to be in UTC. + * @return The converted date and time. + * @exception java.sql.SQLException The date and time string was in an invalid format. + */ + private static final java.util.Date convertDateTimeString(String dstr) throws SQLException + { + if (dstr==null) + return null; // null values are the same + + try + { // do almost the reverse process of formatting it into a string + GregorianCalendar cal = new GregorianCalendar(utc); + cal.set(Calendar.YEAR,Integer.parseInt(dstr.substring(0,4))); + cal.set(Calendar.MONTH,Integer.parseInt(dstr.substring(5,7)) - 1 + Calendar.JANUARY); + cal.set(Calendar.DAY_OF_MONTH,Integer.parseInt(dstr.substring(8,10))); + cal.set(Calendar.HOUR_OF_DAY,Integer.parseInt(dstr.substring(11,13))); + cal.set(Calendar.MINUTE,Integer.parseInt(dstr.substring(14,16))); + cal.set(Calendar.SECOND,Integer.parseInt(dstr.substring(17,19))); + return cal.getTime(); + + } // end try + catch (NumberFormatException e) + { // the NumberFormatException becomes an SQLException + throw new SQLException("invalid DATETIME field format"); + + } // end catch + + } // end convertDateString + + /** + * Encodes a date as an SQL date/time string, expressed in UTC. + * + * @param d The date to be encoded. + * @return The string equivalent of that date. + */ + private static final String encodeDate(java.util.Date d) + { + // Break down the date as a UTC value. + GregorianCalendar cal = new GregorianCalendar(utc); + cal.setTime(d); + + // Create the two string buffers converting the date. + StringBuffer rc = new StringBuffer(); + StringBuffer conv = new StringBuffer(); + String c; + + // Encode the year first. + conv.append("0000").append(cal.get(Calendar.YEAR)); + c = conv.toString(); + rc.append(c.substring(c.length()-4)).append('-'); + + // Now the month... + conv.setLength(0); + conv.append("00").append(cal.get(Calendar.MONTH) - Calendar.JANUARY + 1); + c = conv.toString(); + rc.append(c.substring(c.length()-2)).append('-'); + + // And the day... + conv.setLength(0); + conv.append("00").append(cal.get(Calendar.DAY_OF_MONTH)); + c = conv.toString(); + rc.append(c.substring(c.length()-2)).append(' '); + + // And the hour... + conv.setLength(0); + conv.append("00").append(cal.get(Calendar.HOUR_OF_DAY)); + c = conv.toString(); + rc.append(c.substring(c.length()-2)).append(':'); + + // And the minute... + conv.setLength(0); + conv.append("00").append(cal.get(Calendar.MINUTE)); + c = conv.toString(); + rc.append(c.substring(c.length()-2)).append(':'); + + // And the second... + conv.setLength(0); + conv.append("00").append(cal.get(Calendar.SECOND)); + c = conv.toString(); + rc.append(c.substring(c.length()-2)); + + // This is the resulting date/time value. + return rc.toString(); + + } // end encodeDate + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class DBUtilitiesImpl + *-------------------------------------------------------------------------------- + */ + + public java.util.Date getDateTime(ResultSet rs, String column) throws SQLException + { + return convertDateTimeString(rs.getString(column)); + + } // end getDateTime + + public java.util.Date getDateTime(ResultSet rs, int column) throws SQLException + { + return convertDateTimeString(rs.getString(column)); + + } // end getDateTime + + public void setDateTime(PreparedStatement stmt, int index, java.util.Date date) throws SQLException + { + stmt.setString(index,encodeDate(date)); + + } // end setDateTime + + public void testDatabase(Connection conn) throws SQLException + { + Statement stmt = null; + ResultSet rs = null; + try + { // execute a simple SQL statement + stmt = conn.createStatement(); + rs = stmt.executeQuery("SELECT 1;"); + if (!rs.next()) + throw new SQLException("MySQL database test failed(1)"); + if (rs.getInt(1)!=1) + throw new SQLException("MySQL database test failed(2)"); + + } // end try + finally + { // close down statement and result set + SQLUtils.shutdown(rs); + SQLUtils.shutdown(conn); + + } // end finally + + } // end testDatabase + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + public static DBUtilities get() + { + if (_self==null) + _self = new DBUtilitiesImpl_mysql(); + return _self; + + } // end get + +} // end class DBUtilitiesImpl_mysql diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseConnectionPool.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseConnectionPool.java new file mode 100644 index 0000000..a3298af --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseConnectionPool.java @@ -0,0 +1,652 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import org.apache.log4j.Logger; +import org.w3c.dom.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.Namespaces; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +/** + * A simple pooling system for JDBC connections, which allows connections to be kept in a pool until + * they're needed, avoiding the overhead of opening and closing connections for each transaction, or + * keeping one database connection open for each user.

+ * Based on some code from Marty Hall's Core Servlets and Java Server Pages (Prentice Hall/ + * Sun Microsystems, 2000). + * + * @author Eric J. Bowersox <erbo@silcom.com> + * @version X + */ +public class DatabaseConnectionPool implements DBConnectionPool, ComponentInitialize, ComponentShutdown +{ + /*-------------------------------------------------------------------------------- + * Internal background thread object + *-------------------------------------------------------------------------------- + */ + + private class BackgroundThread extends Thread + { + /*==================================================================== + * Constructor + *==================================================================== + */ + + BackgroundThread() + { + super("DatabaseConnectionPool_bkgd_" + (s_thread_counter++)); + + } // end constructor + + /*==================================================================== + * Overrides from class Thread + *==================================================================== + */ + + public void run() + { + try + { // attempt to create another connection in the background + Connection c = makeNewConnection(); + synchronized (DatabaseConnectionPool.this) + { // we've got a new available connection - let everyone know + if (logger.isDebugEnabled()) + logger.debug("created new connection in the background"); + m_avail_connections.addElement(c); + m_pending = false; + DatabaseConnectionPool.this.notifyAll(); + + } // end synchronized block + + } // end try + catch (Exception e) + { // caught an SQLException or an OutOfMemory exception + logger.warn("background connection thread caught exception",e); + // ditch this new connection and wait until an existing one frees up + + } // end catch + + } // end run + + } // end BackgroundThread + + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(DatabaseConnectionPool.class); + + private static final Map INFER_TYPE_MAP; // used to infer database type from JDBC driver classname + + private static int s_thread_counter = 1; // counter for data pool threads + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_name; // name of connection pool + private String m_dbtype; // database type + private String m_driver; // name of JDBC driver class + private String m_url; // URL for JDBC connection + private String m_username; // username for JDBC connection + private String m_password; // password for JDBC connection + private int m_max_conns; // maximum number of possible connections + private boolean m_wait_if_busy; // do we wait for a connection if none is available? + private boolean m_pending = false; // pending connection being created? + private Vector m_avail_connections = null; // connections which are available for use + private Vector m_busy_connections = null; // connections which are currently in use + private DBUtilities m_util_object; // utilities object + private PropertySerializer m_psz; // property serializer object + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + /** + * Creates a new DatabaseCOnnectionPool object. Commonly called at initialization time, + * when the objects are created from the Dynamo XML configuration file. + */ + public DatabaseConnectionPool() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + /** + * Creates a standard database exception. + * + * @param message The message ID from the "DatabaseMessages" bundle to load. + * @return The new exception object. + */ + private static final DatabaseException newException(String message) + { + return new DatabaseException(DatabaseConnectionPool.class,"DatabaseMessages",message); + + } // end newException + + /** + * Creates a standard database exception. + * + * @param message The message ID from the "DatabaseMessages" bundle to load. + * @param inner The exception to wrap in the new + * {@link com.silverwrist.dynamo.except.DatabaseException DatabaseException} object. + * @return The new exception object. + */ + private static final DatabaseException newException(String message, Throwable inner) + { + return new DatabaseException(DatabaseConnectionPool.class,"DatabaseMessages",message,inner); + + } // end newException + + /** + * Closes all database connections in the specified vector. + * + * @param vconn Vector of connections to be closed. + */ + private static final void closeConnections(Vector vconn) + { + if (logger.isDebugEnabled()) + logger.debug("closeConnections(" + vconn.size() + " to be closed)"); + + for (int i=0; iklass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass) + { + if (klass==DBUtilities.class) + return m_util_object; + if (klass==PropertySerializer.class) + return m_psz; + if (klass==DBConnectionPool.class) + return (DBConnectionPool)this; + throw new NoSuchServiceException("DatabaseConnectionPool",klass); + + } // end queryService + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @param serviceid ID for the service to be requested, to further discriminate between requests. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass, String serviceid) + { + return this.queryService(klass); + + } // end queryService + + /*-------------------------------------------------------------------------------- + * Implementations from interface DBConnectionPool + *-------------------------------------------------------------------------------- + */ + + /** + * Returns a simple string identifying the database type. This is commonly used in database operations + * classes to create classnames that are dynamically loaded. + * + * @return The database identifier. + */ + public String getDatabaseType() + { + return m_dbtype; + + } // end getDatabaseType + + /** + * Returns the number of connections currently being managed by this connection pool. + * + * @return The number of connections currently being managed by this connection pool. + */ + public int numConnections() + { + if (m_busy_connections==null) + return 0; + int rc = m_avail_connections.size() + m_busy_connections.size(); + if (logger.isDebugEnabled()) + logger.debug("numConnections() => " + rc); + return rc; + + } // end numConnections + + /** + * Obtains a database connection object from the connection pool. + * + * @return The Connection object. + * @exception com.silverwrist.dynamo.except.DatabaseException If a connection could not be obtained. + */ + public synchronized Connection getConnection() throws DatabaseException + { + if (m_busy_connections==null) + throw newException("dbx.notInitialized"); + + for (;;) + { // loop until we get a connection or throw an exception + if (m_avail_connections.isEmpty()) + { // no connections available - we may need to make a new one + if (logger.isDebugEnabled()) + logger.debug("no connections available - looking to get one"); + if ((numConnections() < m_max_conns) && !m_pending) + makeBackgroundConnection(); // try to create a new connection + else if (!m_wait_if_busy) + { // don't want to wait? tough, we're h0sed! + logger.error("exhausted maximum connection limit (" + m_max_conns + ")"); + throw newException("dbx.connectionLimit"); + + } // end else if + + // Wait for the background connect attempt to finish, or for + // someone to return a connection. + try + { // park the thread here until we know what's up + wait(); + + } // end try + catch (InterruptedException e) + { // do nothing + } // end catch + + // now fall through the loop and try again + + } // end if + else + { // pull the last connection off the available list... + int ndx = m_avail_connections.size() - 1; + Connection rc = (Connection)(m_avail_connections.elementAt(ndx)); + m_avail_connections.removeElementAt(ndx); + try + { // see if this is a good connection or not... + if (rc.isClosed()) + { // this connection is closed - discard it, and notify any waiters that a slot + // has opened up + if (logger.isDebugEnabled()) + logger.debug("discarding closed connection"); + notifyAll(); + rc = null; + // fall out to the end of the loop and try again + + } // end if + else + { // this connection is OK - return it + m_busy_connections.addElement(rc); + return rc; + + } // end else + + } // end try + catch (SQLException e) + { // if isClosed() throws a SQLException, the connection is somehow broken + logger.warn("connection is borked, discarding",e); + notifyAll(); + rc = null; + // fall out to the end of the loop and try again + + } // end catch + + } // end else (at least one connection available) + + } // end for (ever) + + } // end getConnection + + /** + * Returns a database connection object to the connection pool. + * + * @param conn The Connection object to be released. + * @exception com.silverwrist.dynamo.except.DatabaseException If there was an error returning the connection. + */ + public synchronized void releaseConnection(Connection conn) throws DatabaseException + { + if (m_busy_connections==null) + throw newException("dbx.notInitialized"); + + if (conn!=null) + { // move from one vector to another + m_busy_connections.removeElement(conn); + m_avail_connections.addElement(conn); + notifyAll(); // wake up! Got a new connection for you! + + } // end if + + } // end releaseConnection + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentInitialize + *-------------------------------------------------------------------------------- + */ + + /** + * Initialize the database connection. + * + * @param config_root Pointer to the <dbconnection/> section of the Dynamo XML configuration file that + * configures this database connection. This is to be considered "read-only" by the component. + * @param services An implementation of {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} + * which provides initialization services to the component. This will include an implementation + * of {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} which may be used to + * get information about other objects previously initialized by the application. + * @exception com.silverwrist.dynamo.except.ConfigException If an error is encountered in the component + * configuration. + */ + public void initialize(Element config_root, ServiceProvider services) throws ConfigException + { + XMLLoader loader = XMLLoader.get(); + try + { // verify the right node name + loader.verifyNodeName(config_root,"dbconnection"); + + // get the object's name + m_name = loader.getAttribute(config_root,"name"); + + // get the various settings + DOMElementHelper h = new DOMElementHelper(config_root); + m_dbtype = h.getSubElementText("dbtype"); + if (logger.isDebugEnabled() && (m_dbtype!=null)) + logger.debug("DatabaseConnectionPool specified database type: " + m_dbtype); + + m_driver = loader.getSubElementText(h,"driver"); + if (logger.isDebugEnabled()) + logger.debug("DatabaseConnectionPool driver: " + m_driver); + + // If the database type is not known, try to infer it from the driver name. + if (m_dbtype==null) + m_dbtype = (String)(INFER_TYPE_MAP.get(m_driver)); + if (m_dbtype==null) + { // wasn't specified, can't infer it - we are HOSED! + ConfigException ce = new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages", + "config.inferType"); + ce.setParameter(0,m_driver); + throw ce; + + } // end if + else if (logger.isDebugEnabled()) + logger.debug("DatabaseConnectionPool inferred database type: " + m_dbtype); + + m_url = loader.getSubElementText(h,"uri"); + if (logger.isDebugEnabled()) + logger.debug("DatabaseConnectionPool URI: " + m_url); + + m_username = loader.getSubElementText(h,"username"); + if (logger.isDebugEnabled()) + logger.debug("DatabaseConnectionPool user name: " + m_username); + + m_password = loader.getSubElementText(h,"password"); + + Element elt = loader.getSubElement(h,"connections"); + int initial_conn = loader.getAttributeInt(elt,"initial",0); + if (initial_conn<0) + throw new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages","config.initialConn"); + if (logger.isDebugEnabled()) + logger.debug("DatabaseConnectionPool initial connections: " + initial_conn); + + m_max_conns = loader.getAttributeInt(elt,"max"); + if (m_max_conns<0) + throw new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages","config.maxConn"); + if (logger.isDebugEnabled()) + logger.debug("DatabaseConnectionPool maximum connections: " + m_max_conns); + + m_wait_if_busy = loader.getAttributeBoolean(elt,"busywait",true); + if (logger.isDebugEnabled()) + logger.debug("DatabaseConnectionPool wait if busy: " + m_wait_if_busy); + + if (initial_conn>m_max_conns) + { // fix initial value if above maximum + if (logger.isDebugEnabled()) + logger.debug("N.B.: reducing configured initial connections"); + initial_conn = m_max_conns; + + } // end if + + try + { // get the appropriate utilities object + m_util_object = DBUtilitiesImpl.get(m_dbtype); + + } // end if + catch (Exception e) + { // the utilities are not implemented + ConfigException ce = new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages", + "utils.impl",e); + ce.setParameter(0,m_dbtype); + throw ce; + + } // end catch + + // Get the master property serializer so we can offer it as a service. + m_psz = (PropertySerializer)(services.queryService(PropertySerializer.class)); + + // Create the vectors that hold connections. + m_avail_connections = new Vector(initial_conn); + m_busy_connections = new Vector(); + + // Populate the "available connection" vector. + for (int i=0; iConnection objects. + */ + public void shutdown() + { + closeConnections(m_avail_connections); + m_avail_connections = null; + closeConnections(m_busy_connections); + m_busy_connections = null; + + } // end shutdown + + /*-------------------------------------------------------------------------------- + * Static initializer + *-------------------------------------------------------------------------------- + */ + + static + { // Create the database type inference map. + HashMap map = new HashMap(); + map.put("com.mysql.jdbc.Driver","mysql"); + map.put("org.gjt.mm.mysql.Driver","mysql"); + INFER_TYPE_MAP = Collections.unmodifiableMap(map); + + } // end static initializer + +} // end class DatabaseConnectionPool diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseMessages.properties new file mode 100644 index 0000000..6ca3d36 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseMessages.properties @@ -0,0 +1,58 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# --------------------------------------------------------------------------------- +# This file has been localized for the en_US locale +dbx.notInitialized=The connection pool object has not been initialized +dbx.classNotFound=Can't find JDBC driver class: {0} +dbx.illegalAccess=Can't access JDBC driver class: {0} +dbx.instantiation=Can't create JDBC driver class: {0} +dbx.sqlMakeNewConn=Can't create new database connection +dbx.connectionLimit=Connection limit reached +dbx.testfail=Test failed on database {0} (url {1}): {2} +config.inferType=Database type was not specified, and unable to infer it from JDBC driver name "{0}". +config.initialConn=Invalid initial connections parameter +config.maxConn=Invalid maximum connections parameter +config.create=Unable to create initial database connections +utils.impl=Database utilities are not implemented for database type "{0}". +load.opsClass=Unable to load {2} class for database "{1}": {0} +general=Database access failure: {0} +nsCache.notFound=Unknown namespace ID seen; possible internal error. +property.serialize=The value of property "{0}" could not be serialized. +property.deserialize=The value of property "{0}" could not be deserialized. +ose.setProperty=Unable to set the value of property "{1}" in namespace "{0}". +ose.removeProperty=Unable to remove the value of property "{1}" in namespace "{0}". +ose.getNamespaces=Unable to enumerate the namespaces in this ObjectStore. +ose.getNames=Unable to enumerate the object names in namespace "{0}". +auth.register=Authenticator already registered for namespace "{0}", name "{1}". +auth.notFound=No authenticator registered for namespace "{0}", name "{1}". +auth.noUserData=User cannot authenticate with authenticator namespace "{0}", name "{1}". +ose.setBlock=Unable to set the value of block "{1}" in namespace "{0}". +ose.removeBlock=Unable to remove the value of block "{1}" in namespace "{0}". +sec.changeUser=You are not permitted to change the attributes of user "{0}". +sec.needSec=You cannot perform this operation on a group without specifying a user making the change. +sec.setGroupProperty=You are not permitted to set property values for group "{0}". +sec.removeGroupProperty=You are not permitted to remove property values from group "{0}". +sec.addGroupMember=You are not permitted to add members to group "{0}". +sec.removeGroupMember=You are not permitted to remove members from group "{0}". +sec.setGroupAcl=You are not permitted to change the access control list of group "{0}". +sec.setGlobalProperty=You are not permitted to set the global property. +sec.removeGlobalProperty=You are not permitted to remove the global property. +sec.setGlobalBlock=You are not permitted to set the global block. +sec.removeGlobalBlock=You are not permitted to remove the global block. +img.loadFail=Failed to load image {0} due to I/O error. +img.badOwner=Invalid owner for new image. +img.notOwner=You are not the owner of image {0}. +img.normalize=Image normalization of {0} failed: {1}. diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DefaultHashAuthenticator.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DefaultHashAuthenticator.java new file mode 100644 index 0000000..b0767b3 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DefaultHashAuthenticator.java @@ -0,0 +1,111 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.security.MessageDigest; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +class DefaultHashAuthenticator implements Authenticator +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + DefaultHashAuthenticator() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * IMplementations from interface Authenticator + *-------------------------------------------------------------------------------- + */ + + public boolean authenticate(String stored_data, String input_data) throws AuthenticationException + { + return stored_data.equals(hashPassword(input_data)); + + } // end authenticate + + public String processInputData(String input_data) throws AuthenticationException + { + return hashPassword(input_data); + + } // end processInputData + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + public static final String hashPassword(String password) + { + if ((password!=null) && (password.length()>0)) + { // hash the password and save the hash value + MessageDigest hasher; + + try + { // get a hasher implementing the Secure Hashing Algorithm + hasher = MessageDigest.getInstance("SHA"); + + } // end try + catch (java.security.NoSuchAlgorithmException e) + { // SHA should be a standard algorithm...if it isn't, we're h0sed + throw new RuntimeException("HOSED JRE - SHA should be a standard algorithm"); + + } // end catch + + try + { // update the hasher with the UTF-8 bytes of the password + hasher.update(password.getBytes("UTF8")); + + } // end try + catch (java.io.UnsupportedEncodingException e) + { // WTF? How can the JRE NOT know about UTF-8? HOW?!? + throw new RuntimeException("HOSED JRE - UTF-8 encoding should be supported"); + + } // end catch + + // Retrieve the raw hash value (should be 160 bits, or 20 bytes) + byte[] raw_hash = hasher.digest(); + + // Convert the hash value to a hexadecimal string (40 chars in length) + StringBuffer hash_buf = new StringBuffer(raw_hash.length * 2); + StringBuffer tmp_buf = new StringBuffer(); + String tmp; + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.event.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.security.SecurityReferenceMonitor; +import com.silverwrist.dynamo.util.*; + +class GlobalBlocksObject implements SecureObjectStore +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private GlobalBlocksOps m_ops; // operations object + private NamespaceCache m_ns_cache; // namespace cache + private SecurityReferenceMonitor m_srm; // security reference monitor + private PostDynamicUpdate m_post; // where we post dynamic events + private HardSoftCache m_cache; // our cache + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + GlobalBlocksObject(DBConnectionPool pool, NamespaceCache ns_cache, SecurityReferenceMonitor srm, + PostDynamicUpdate post, int hard_limit, int soft_limit) throws ConfigException + { + m_ops = GlobalBlocksOps.get(pool); + m_ns_cache = ns_cache; + m_srm = srm; + m_post = post; + m_cache = new HardSoftCache(hard_limit,soft_limit); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final void testPermission(DynamoUser caller, String perm_namespace, String perm_name, + String fail_message) throws DatabaseException, DynamoSecurityException + { + if (caller.equals(m_srm.getAdminUser())) + return; // Administrator can do anything + if (m_srm.getGlobalAcl().testPermission(caller,perm_namespace,perm_name)) + return; // we have the right permission in the ACL + throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages",fail_message); + + } // end testPermission + + /*-------------------------------------------------------------------------------- + * Implementations from interface ObjectProvider + *-------------------------------------------------------------------------------- + */ + + /** + * Retrieves an object from this ObjectProvider. + * + * @param namespace The namespace to interpret the name relative to. + * @param name The name of the object to be retrieved. + * @return The object reference specified. + */ + public Object getObject(String namespace, String name) + { + try + { // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + Object rc = null; + synchronized (this) + { // start by looking in the block cache + rc = m_cache.get(key); + if (rc==null) + { // no use - need to try the database + rc = m_ops.getBlock(key); + if (rc!=null) + m_cache.put(key,rc); + + } // end if + + } // end synchronized block + + if (rc==null) + throw new NoSuchObjectException(this.toString(),namespace,name); + return rc; + + } // end try + catch (DatabaseException e) + { // translate into our NoSuchObjectException but retain the DatabaseException + throw new NoSuchObjectException(this.toString(),namespace,name,e); + + } // end catch + + } // end getObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface SecureObjectStore + *-------------------------------------------------------------------------------- + */ + + public Object setObject(DynamoUser caller, String namespace, String name, Object value) + throws DatabaseException, DynamoSecurityException + { + testPermission(caller,namespace,"set.block","sec.setGlobalBlock"); + Object rc = null; + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (this) + { // start by setting the database value + rc = m_ops.putBlock(key,value.toString()); + + // and cache it, too + m_cache.put(key,value.toString()); + + } // end synchronized block + + m_post.postUpdate(new GlobalBlockUpdateEvent(this,namespace,name)); + return rc; + + } // end setObject + + public Object removeObject(DynamoUser caller, String namespace, String name) + throws DatabaseException, DynamoSecurityException + { + testPermission(caller,namespace,"remove.block","sec.removeGlobalBlock"); + Object rc = null; + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (this) + { // start by killing the database value + rc = m_ops.removeBlock(key); + + // and remove the cached value, too + m_cache.remove(key); + + } // end synchronized block + + m_post.postUpdate(new GlobalBlockUpdateEvent(this,namespace,name)); + return rc; + + } // end removeObject + + public Collection getNamespaces() throws DatabaseException + { + // call through to the database to get the list of namespace IDs + int[] ids = m_ops.getBlockNamespaceIDs(); + + ArrayList rc = new ArrayList(ids.length); + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.util.*; + +abstract class GlobalBlocksOps extends OpsBase +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected GlobalBlocksOps(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class OpsBase + *-------------------------------------------------------------------------------- + */ + + public void dispose() + { + super.dispose(); + + } // end dispose + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + abstract String getBlock(PropertyKey key) throws DatabaseException; + + abstract String putBlock(PropertyKey key, String data) throws DatabaseException; + + abstract String removeBlock(PropertyKey key) throws DatabaseException; + + abstract int[] getBlockNamespaceIDs() throws DatabaseException; + + abstract Collection getAllBlockNames(int nsid) throws DatabaseException; + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + static GlobalBlocksOps get(DBConnectionPool pool) throws ConfigException + { + return (GlobalBlocksOps)get(pool,GlobalBlocksOps.class.getClassLoader(), + GlobalBlocksOps.class.getName() + "_","GlobalBlocksOps"); + + } // end get + +} // end class GlobalBlocksOps diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps_mysql.java new file mode 100644 index 0000000..59b4d69 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps_mysql.java @@ -0,0 +1,284 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +public class GlobalBlocksOps_mysql extends GlobalBlocksOps +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DBUtilities m_utils; // reference to utilities object + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public GlobalBlocksOps_mysql(DBConnectionPool pool) + { + super(pool); + m_utils = (DBUtilities)(pool.queryService(DBUtilities.class)); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class GlobalBlocksOps + *-------------------------------------------------------------------------------- + */ + + String getBlock(PropertyKey key) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // look up the block + stmt = conn.prepareStatement("SELECT block FROM globalblock WHERE nsid = ? AND block_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // block not found + return rs.getString(1); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end getBlock + + String putBlock(PropertyKey key, String data) throws DatabaseException + { + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES globalblock WRITE;"); + + // look to see if the block value is already there + stmt = conn.prepareStatement("SELECT block FROM globalblock WHERE nsid = ? AND block_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + if (old_value!=null) + { // prepare the statement to update the existing record + stmt = conn.prepareStatement("UPDATE globalblock SET block = ? WHERE nsid = ? AND block_name = ?;"); + stmt.setString(1,data); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + + } // end if + else + { // prepare the statement to insert a new record + stmt = conn.prepareStatement("INSERT INTO globalblock (nsid, block_name, block) VALUES (?, ?, ?);"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + stmt.setString(3,data); + + } // end else + + stmt.executeUpdate(); // execute it! + + return old_value; // return previous value + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end putBlock + + String removeBlock(PropertyKey key) throws DatabaseException + { + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES globalblock WRITE;"); + + // look to see if the property value is already there + stmt = conn.prepareStatement("SELECT block FROM globalblock WHERE nsid = ? AND block_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + else + return null; // no need to remove anything + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + // delete the database row + stmt = conn.prepareStatement("DELETE FROM globalblock WHERE nsid = ? AND block_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + stmt.executeUpdate(); + + return old_value; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end removeBlock + + int[] getBlockNamespaceIDs() throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the query! + stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM globalblock;"); + rs = stmt.executeQuery(); + + // read out a list of the namespace IDs + ArrayList tmp = new ArrayList(); + while (rs.next()) + tmp.add(new Integer(rs.getInt(1))); + + // create and return the array + int[] rc = new int[tmp.size()]; + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import org.w3c.dom.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.security.SecurityReferenceMonitor; +import com.silverwrist.dynamo.util.*; + +public class GlobalDataManagerObject + implements NamedObject, ComponentInitialize, ComponentShutdown, ServiceProvider +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final int DEFAULT_HARD_LIMIT = 5; + private static final int DEFAULT_SOFT_LIMIT = 20; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_name; // object name + private DBConnectionPool m_pool; // database connection pool + private NamespaceCache m_ns_cache; // namespace cache object + private SecurityReferenceMonitor m_srm; // security reference monitor + private PostDynamicUpdate m_post; // dynamic update poster + private GlobalPropertiesObject m_properties; // global properties object + private GlobalBlocksObject m_blocks; // global blocks object + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public GlobalDataManagerObject() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamedObject + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentInitialize + *-------------------------------------------------------------------------------- + */ + + public void initialize(Element config_root, ServiceProvider services) throws ConfigException + { + String conn_name = null; + String nscache_name = null; + String srm_name = null; + int hard_limit = DEFAULT_HARD_LIMIT; + int soft_limit = DEFAULT_SOFT_LIMIT; + XMLLoader loader = XMLLoader.get(); + try + { // verify the right node name + loader.verifyNodeName(config_root,"object"); + + // get the object's name + m_name = loader.getAttribute(config_root,"name"); + + // get the database configuration connection + DOMElementHelper config_root_h = new DOMElementHelper(config_root); + Element elt = loader.getSubElement(config_root_h,"database"); + conn_name = loader.getAttribute(elt,"connection"); + nscache_name = loader.getAttribute(elt,"namespaces"); + + // get the security reference monitor reference + elt = loader.getSubElement(config_root_h,"security"); + srm_name = loader.getAttribute(elt,"object"); + + // get the block cache information + elt = config_root_h.getSubElement("block-cache"); + if (elt!=null) + { // get the cache limits + hard_limit = loader.getAttributeInt(elt,"hardlimit",DEFAULT_HARD_LIMIT); + soft_limit = loader.getAttributeInt(elt,"softlimit",DEFAULT_SOFT_LIMIT); + + } // end if + + } // end try + catch (XMLLoadException e) + { // error loading XML config data + throw new ConfigException(e); + + } // end catch + + // Get the database connection pool and the namespace cache. + m_pool = GetObjectUtils.getDatabaseConnection(services,conn_name); + m_ns_cache = + (NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name)); + m_srm = + (SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class, + srm_name)); + m_post = (PostDynamicUpdate)(services.queryService(PostDynamicUpdate.class)); + + // Create the subobjects. + m_properties = new GlobalPropertiesObject(m_pool,m_ns_cache,m_srm,m_post); + m_blocks = new GlobalBlocksObject(m_pool,m_ns_cache,m_srm,m_post,hard_limit,soft_limit); + + } // end initialize + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentShutdown + *-------------------------------------------------------------------------------- + */ + + public void shutdown() + { + m_pool = null; + m_ns_cache = null; + m_srm = null; + m_post = null; + + } // end shutdown + + /*-------------------------------------------------------------------------------- + * Implementations from interface ServiceProvider + *-------------------------------------------------------------------------------- + */ + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass) + { + if ((klass==SecureObjectStore.class) || (klass==ObjectProvider.class)) + return (SecureObjectStore)m_properties; + throw new NoSuchServiceException("GlobalDataManagerObject",klass); + + } // end queryService + + /** + * Queries this object for a specified service. + * + * @param klass The class of the object that should be returned as a service. + * @param serviceid ID for the service to be requested, to further discriminate between requests. + * @return A service object. The service object is guaranteed to be of the class + * specified by klass; that is, if queryService(klass) + * yields some object x, then the expression klass.isInstance(x) + * is true. + * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in + * the specified class. + */ + public Object queryService(Class klass, String serviceid) + { + if ((klass==SecureObjectStore.class) || (klass==ObjectProvider.class)) + { // return service + if ((serviceid==null) || serviceid.equals("properties")) + return (SecureObjectStore)m_properties; + if (serviceid.equals("blocks")) + return (SecureObjectStore)m_blocks; + throw new NoSuchServiceException("GlobalDataManagerObject",klass,serviceid); + + } // end if + + try + { // look for the class without a service ID + return this.queryService(klass); + + } // end try + catch (NoSuchServiceException e) + { // transform exception for return + throw new NoSuchServiceException(e.getContext(),klass,serviceid,e); + + } // end catch + + } // end queryService + +} // end class GlobalDataManagerObject diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesObject.java new file mode 100644 index 0000000..11c5132 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesObject.java @@ -0,0 +1,201 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import org.apache.commons.collections.*; +import com.silverwrist.dynamo.event.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.security.SecurityReferenceMonitor; +import com.silverwrist.dynamo.util.*; + +class GlobalPropertiesObject implements SecureObjectStore +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private GlobalPropertiesOps m_ops; // operations object + private NamespaceCache m_ns_cache; // namespace cache + private SecurityReferenceMonitor m_srm; // security reference monitor + private PostDynamicUpdate m_post; // where we post dynamic events + private ReferenceMap m_properties; // cached property values + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + GlobalPropertiesObject(DBConnectionPool pool, NamespaceCache ns_cache, SecurityReferenceMonitor srm, + PostDynamicUpdate post) throws ConfigException + { + m_ops = GlobalPropertiesOps.get(pool); + m_ns_cache = ns_cache; + m_srm = srm; + m_post = post; + m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final void testPermission(DynamoUser caller, String perm_namespace, String perm_name, + String fail_message) throws DatabaseException, DynamoSecurityException + { + if (caller.equals(m_srm.getAdminUser())) + return; // Administrator can do anything + if (m_srm.getGlobalAcl().testPermission(caller,perm_namespace,perm_name)) + return; // we have the right permission in the ACL + throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages",fail_message); + + } // end testPermission + + /*-------------------------------------------------------------------------------- + * Implementations from interface ObjectProvider + *-------------------------------------------------------------------------------- + */ + + /** + * Retrieves an object from this ObjectProvider. + * + * @param namespace The namespace to interpret the name relative to. + * @param name The name of the object to be retrieved. + * @return The object reference specified. + */ + public Object getObject(String namespace, String name) + { + try + { // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + Object rc = null; + synchronized (this) + { // start by looking in the properties map + rc = m_properties.get(key); + if (rc==null) + { // no use - need to try the database + rc = m_ops.getProperty(key); + if (rc!=null) + m_properties.put(key,rc); + + } // end if + + } // end synchronized block + + if (rc==null) + throw new NoSuchObjectException(this.toString(),namespace,name); + return rc; + + } // end try + catch (DatabaseException e) + { // translate into our NoSuchObjectException but retain the DatabaseException + throw new NoSuchObjectException(this.toString(),namespace,name,e); + + } // end catch + + } // end getObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface SecureObjectStore + *-------------------------------------------------------------------------------- + */ + + public Object setObject(DynamoUser caller, String namespace, String name, Object value) + throws DatabaseException, DynamoSecurityException + { + testPermission(caller,namespace,"set.property","sec.setGlobalProperty"); + Object rc = null; + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (this) + { // start by setting the database value + rc = m_ops.setProperty(key,value); + + // and cache it, too + m_properties.put(key,value); + + } // end synchronized block + + m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name)); + return rc; + + } // end setObject + + public Object removeObject(DynamoUser caller, String namespace, String name) + throws DatabaseException, DynamoSecurityException + { + testPermission(caller,namespace,"remove.property","sec.removeGlobalProperty"); + Object rc = null; + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (this) + { // start by killing the database value + rc = m_ops.removeProperty(key); + + // and remove the cached value, too + m_properties.remove(key); + + } // end synchronized block + + m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name)); + return rc; + + } // end removeObject + + public Collection getNamespaces() throws DatabaseException + { + // call through to the database to get the list of namespace IDs + int[] ids = m_ops.getPropertyNamespaceIDs(); + + ArrayList rc = new ArrayList(ids.length); + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.util.*; + +abstract class GlobalPropertiesOps extends OpsBase +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected GlobalPropertiesOps(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class OpsBase + *-------------------------------------------------------------------------------- + */ + + public void dispose() + { + super.dispose(); + + } // end dispose + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + abstract Object getProperty(PropertyKey key) throws DatabaseException; + + abstract Object setProperty(PropertyKey key, Object value) throws DatabaseException; + + abstract Object removeProperty(PropertyKey key) throws DatabaseException; + + abstract int[] getPropertyNamespaceIDs() throws DatabaseException; + + abstract Map getAllProperties(int namespace) throws DatabaseException; + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + static GlobalPropertiesOps get(DBConnectionPool pool) throws ConfigException + { + return (GlobalPropertiesOps)get(pool,GlobalPropertiesOps.class.getClassLoader(), + GlobalPropertiesOps.class.getName() + "_","GlobalPropertiesOps"); + + } // end get + +} // end class GlobalPropertiesOps diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps_mysql.java new file mode 100644 index 0000000..c04cbfb --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps_mysql.java @@ -0,0 +1,344 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +public class GlobalPropertiesOps_mysql extends GlobalPropertiesOps +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DBUtilities m_utils; // reference to utilities object + private PropertySerializer m_psz; // reference to property serializer + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public GlobalPropertiesOps_mysql(DBConnectionPool pool) + { + super(pool); + m_utils = (DBUtilities)(pool.queryService(DBUtilities.class)); + m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class)); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class GlobalPropertiesOps + *-------------------------------------------------------------------------------- + */ + + Object getProperty(PropertyKey key) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + String rc_str = null; + try + { // get a connection + conn = getConnection(); + + // look up the property + stmt = conn.prepareStatement("SELECT prop_value FROM globalprop WHERE nsid = ? AND prop_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // property not found + + rc_str = rs.getString(1); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(rc_str); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end getProperty + + Object setProperty(PropertyKey key, Object value) throws DatabaseException + { + String serialized_value = m_psz.serializeProperty(value); + if (serialized_value==null) + { // serialization exception - throw it + DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages", + "property.serialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end if + + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES globalprop WRITE;"); + + // look to see if the property value is already there + stmt = conn.prepareStatement("SELECT prop_value FROM globalprop WHERE nsid = ? AND prop_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + if (old_value!=null) + { // prepare the statement to update the existing record + stmt = conn.prepareStatement("UPDATE globalprop SET prop_value = ? WHERE nsid = ? AND prop_name = ?;"); + stmt.setString(1,serialized_value); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + + } // end if + else + { // prepare the statement to insert a new record + stmt = conn.prepareStatement("INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES (?, ?, ?);"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + stmt.setString(3,serialized_value); + + } // end else + + stmt.executeUpdate(); // execute it! + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + if (old_value==null) + return null; // no previous value + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(old_value); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end setProperty + + Object removeProperty(PropertyKey key) throws DatabaseException + { + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES globalprop WRITE;"); + + // look to see if the property value is already there + stmt = conn.prepareStatement("SELECT prop_value FROM globalprop WHERE nsid = ? AND prop_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + else + return null; // no need to remove anything + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + // delete the database row + stmt = conn.prepareStatement("DELETE FROM globalprop WHERE nsid = ? AND prop_name = ?;"); + stmt.setInt(1,key.getNamespaceID()); + stmt.setString(2,key.getName()); + stmt.executeUpdate(); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(old_value); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end removeProperty + + int[] getPropertyNamespaceIDs() throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the query! + stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM globalprop;"); + rs = stmt.executeQuery(); + + // read out a list of the namespace IDs + ArrayList tmp = new ArrayList(); + while (rs.next()) + tmp.add(new Integer(rs.getInt(1))); + + // create and return the array + int[] rc = new int[tmp.size()]; + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.security.Principal; +import java.security.acl.AclNotFoundException; +import java.util.*; +import org.apache.commons.collections.*; +import com.silverwrist.dynamo.Namespaces; +import com.silverwrist.dynamo.UserInfoNamespace; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.security.SecurityReferenceMonitor; +import com.silverwrist.dynamo.util.*; + +class GroupObject implements DynamoGroup +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final String PERM_NAMESPACE = Namespaces.GROUP_PERMISSIONS_NAMESPACE; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private GroupObjectOps m_ops; // operations object + private NamespaceCache m_ns_cache; // namespace cache object + private SecurityReferenceMonitor m_srm; // security reference monitor + private UserProxyManagement m_upm; // user proxy manager + private int m_gid; // group ID + private String m_groupname; // group name + private int m_gaclid; // group ACL ID + private ReferenceMap m_properties; // cached property values + private Object m_properties_sync = new Object(); // synchronization for above + private HashSet m_known_members = new HashSet(); // known members + private HashSet m_known_nonmembers = new HashSet(); // known nonmembers + private Object m_members_sync = new Object(); // synchronization for above + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + GroupObject(Map data, GroupObjectOps ops, NamespaceCache ns_cache, SecurityReferenceMonitor srm, + UserProxyManagement upm) + { + m_ops = ops; + m_ns_cache = ns_cache; + m_srm = srm; + m_upm = upm; + m_gid = ((Integer)(data.get(UserManagerOps.HMKEY_GID))).intValue(); + m_groupname = (String)(data.get(UserManagerOps.HMKEY_GROUPNAME)); + m_gaclid = ((Integer)(data.get(UserManagerOps.HMKEY_GACLID))).intValue(); + m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private static final int getPrincipalUID(Principal p) + { + if (p instanceof DynamoUser) + return ((DynamoUser)p).getUID(); + else + return -1; + + } // end getPrincipalUID + + private final void testOperationWithoutSecurity() + { + if (m_gaclid==-1) + return; + throw new GroupRuntimeException(new DynamoSecurityException(GroupObject.class,"DatabaseMessages", + "sec.needSec")); + + } // end testOperationWithoutSecurity + + private final void testPermission(DynamoUser caller, String perm_namespace, String perm_name, + String fail_message) throws DatabaseException, DynamoSecurityException + { + if (m_gaclid==-1) + return; + if (caller==null) + throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages","sec.needSec"); + if (caller.equals(m_srm.getAdminUser())) + return; // Administrator can do anything + if (m_srm.testPermission(m_gaclid,caller,perm_namespace,perm_name)) + return; // we have the right permission in the ACL + DynamoSecurityException dse = new DynamoSecurityException(GroupObject.class,"DatabaseMessages", + fail_message); + dse.setParameter(0,m_groupname); + throw dse; + + } // end testPermission + + private final void testPermission(DynamoUser caller, int target_uid, String perm_namespace, String perm_name, + String perm2_name, String fail_message) + throws DatabaseException, DynamoSecurityException + { + if (m_gaclid==-1) + return; + if (caller==null) + throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages","sec.needSec"); + if (caller.equals(m_srm.getAdminUser())) + return; // Administrator can do anything + if ((caller.getUID()==target_uid) && m_srm.testPermission(m_gaclid,caller,perm_namespace,perm2_name)) + return; // we can "join group" or "unjoin group" if we have the right permissions + if (m_srm.testPermission(m_gaclid,caller,perm_namespace,perm_name)) + return; // we have the right permission in the ACL + DynamoSecurityException dse = new DynamoSecurityException(GroupObject.class,"DatabaseMessages", + fail_message); + dse.setParameter(0,m_groupname); + throw dse; + + } // end testPermission + + private final void testAclOwner(DynamoUser caller) throws DatabaseException, DynamoSecurityException + { + if (m_gaclid==-1) + return; + if (caller==null) + throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages","sec.needSec"); + if (caller.equals(m_srm.getAdminUser())) + return; // Administrator can do anything + if (m_srm.isOwnerOfAcl(m_gaclid,caller)) + return; // we own this ACL + DynamoSecurityException dse = new DynamoSecurityException(GroupObject.class,"DatabaseMessages", + "sec.setGroupAcl"); + dse.setParameter(0,m_groupname); + throw dse; + + } // end testAclOwner + + private final boolean addUIDInternal(int uid) throws DatabaseException + { + Integer key = new Integer(uid); + synchronized (m_members_sync) + { // look in the cache first + if (m_known_members.contains(key)) + return false; // we're already a known member + + // fiddle the database + boolean rc = m_ops.addMember(m_gid,uid); + m_known_members.add(key); // update the cache to reflect reality + if (m_known_nonmembers!=null) + m_known_nonmembers.remove(key); + return rc; + + } // end synchronized block + + } // end addUIDInternal + + private final boolean removeUIDInternal(int uid) throws DatabaseException + { + Integer key = new Integer(uid); + synchronized (m_members_sync) + { // look in the cache first + if (m_known_nonmembers!=null) + { // are we a known nonmember? + if (m_known_nonmembers.contains(key)) + return false; // already a nonmember + + } // end if + else + { // in this circumstance, everyone not in the members set is a nonmember + if (!(m_known_members.contains(key))) + return false; // already a nonmember + + } // end else + + // fiddle the database + boolean rc = m_ops.removeMember(m_gid,uid); + m_known_members.remove(key); // update the cache to reflect reality + if (m_known_nonmembers!=null) + m_known_nonmembers.add(key); + return rc; + + } // end synchronized block + + } // end removeUIDInternal + + /*-------------------------------------------------------------------------------- + * Implementations from interface Principal + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object another) + { + if (another==null) + return false; + if (another instanceof DynamoGroup) + return (m_gid==((DynamoGroup)another).getGID()); + return false; + + } // end equals + + public String toString() + { + return "group " + m_groupname; + + } // end toString + + public int hashCode() + { + return m_gid; + + } // end hashCode + + public String getName() + { + return m_groupname; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface Group + *-------------------------------------------------------------------------------- + */ + + public boolean addMember(Principal user) + { + testOperationWithoutSecurity(); + try + { // break down the operations... + if (user instanceof DynamoUser) + return this.addUIDInternal(((DynamoUser)user).getUID()); + else if (user instanceof DynamoGroup) + { // add all UIDs contained in this group + int[] uids = ((DynamoGroup)user).getUIDs(); + boolean rc = false; + for (int i=0; iObjectProvider. + * + * @param namespace The namespace to interpret the name relative to. + * @param name The name of the object to be retrieved. + * @return The object reference specified. + */ + public Object getObject(String namespace, String name) + { + try + { // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + Object rc = null; + synchronized (m_properties_sync) + { // start by looking in the properties map + rc = m_properties.get(key); + if (rc==null) + { // no use - need to try the database + rc = m_ops.getProperty(m_gid,key); + if (rc!=null) + m_properties.put(key,rc); + + } // end if + + } // end synchronized block + + if (rc==null) + throw new NoSuchObjectException(this.toString(),namespace,name); + return rc; + + } // end try + catch (DatabaseException e) + { // translate into our NoSuchObjectException but retain the DatabaseException + throw new NoSuchObjectException(this.toString(),namespace,name,e); + + } // end catch + + } // end getObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface SecureObjectStore + *-------------------------------------------------------------------------------- + */ + + public Object setObject(DynamoUser caller, String namespace, String name, Object value) + throws DatabaseException, DynamoSecurityException + { + testPermission(caller,namespace,"set.property","sec.setGroupProperty"); + Object rc = null; + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (m_properties_sync) + { // start by setting the database value + rc = m_ops.setProperty(m_gid,key,value); + + // and cache it, too + m_properties.put(key,value); + + } // end synchronized block + + return rc; + + } // end setObject + + public Object removeObject(DynamoUser caller, String namespace, String name) + throws DatabaseException, DynamoSecurityException + { + testPermission(caller,namespace,"remove.property","sec.removeGroupProperty"); + Object rc = null; + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (m_properties_sync) + { // start by killing the database value + rc = m_ops.removeProperty(m_gid,key); + + // and remove the cached value, too + m_properties.remove(key); + + } // end synchronized block + + return rc; + + } // end removeObject + + public Collection getNamespaces() throws DatabaseException + { + // call through to the database to get the list of namespace IDs + int[] ids = m_ops.getPropertyNamespaceIDs(m_gid); + + ArrayList rc = new ArrayList(ids.length); + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.util.*; + +abstract class GroupObjectOps extends OpsBase +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected GroupObjectOps(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + abstract Object getProperty(int gid, PropertyKey key) throws DatabaseException; + + abstract Object setProperty(int gid, PropertyKey key, Object value) throws DatabaseException; + + abstract Object removeProperty(int gid, PropertyKey key) throws DatabaseException; + + abstract int[] getPropertyNamespaceIDs(int gid) throws DatabaseException; + + abstract Map getAllProperties(int gid, int namespace) throws DatabaseException; + + abstract boolean testMember(int gid, int uid) throws DatabaseException; + + abstract boolean addMember(int gid, int uid) throws DatabaseException; + + abstract boolean removeMember(int gid, int uid) throws DatabaseException; + + abstract int[] getMembers(int gid) throws DatabaseException; + + abstract void setAclID(int gid, int aclid) throws DatabaseException; + +} // end class GroupObjectOps diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps_mysql.java new file mode 100644 index 0000000..d82b59f --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps_mysql.java @@ -0,0 +1,556 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +class GroupObjectOps_mysql extends GroupObjectOps +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DBUtilities m_utils; + private PropertySerializer m_psz; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + GroupObjectOps_mysql(DBConnectionPool pool, DBUtilities utils) + { + super(pool); + m_utils = utils; + m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class)); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class GroupObjectOps + *-------------------------------------------------------------------------------- + */ + + Object getProperty(int gid, PropertyKey key) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + String rc_str = null; + try + { // get a connection + conn = getConnection(); + + // look up the property + stmt = conn.prepareStatement("SELECT prop_value FROM groupprop WHERE gid = ? AND nsid = ? " + + "AND prop_name = ?;"); + stmt.setInt(1,gid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // property not found + + rc_str = rs.getString(1); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(rc_str); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end getProperty + + Object setProperty(int gid, PropertyKey key, Object value) throws DatabaseException + { + String serialized_value = m_psz.serializeProperty(value); + if (serialized_value==null) + { // serialization exception - throw it + DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages", + "property.serialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end if + + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES groupprop WRITE;"); + + // look to see if the property value is already there + stmt = conn.prepareStatement("SELECT prop_value FROM groupprop WHERE gid = ? AND nsid = ? " + + "AND prop_name = ?;"); + stmt.setInt(1,gid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + if (old_value!=null) + { // prepare the statement to update the existing record + stmt = conn.prepareStatement("UPDATE groupprop SET prop_value = ? WHERE gid = ? " + + "AND nsid = ? AND prop_name = ?;"); + stmt.setString(1,serialized_value); + stmt.setInt(2,gid); + stmt.setInt(3,key.getNamespaceID()); + stmt.setString(4,key.getName()); + + } // end if + else + { // prepare the statement to insert a new record + stmt = conn.prepareStatement("INSERT INTO groupprop (gid, nsid, prop_name, prop_value) " + + "VALUES (?, ?, ?, ?);"); + stmt.setInt(1,gid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + stmt.setString(4,serialized_value); + + } // end else + + stmt.executeUpdate(); // execute it! + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + if (old_value==null) + return null; // no previous value + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(old_value); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end setProperty + + Object removeProperty(int gid, PropertyKey key) throws DatabaseException + { + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES groupprop WRITE;"); + + // look to see if the property value is already there + stmt = conn.prepareStatement("SELECT prop_value FROM groupprop WHERE gid = ? AND nsid = ? " + + "AND prop_name = ?;"); + stmt.setInt(1,gid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + else + return null; // no need to remove anything + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + // delete the database row + stmt = conn.prepareStatement("DELETE FROM groupprop WHERE gid = ? AND nsid = ? AND prop_name = ?;"); + stmt.setInt(1,gid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + stmt.executeUpdate(); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(old_value); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end removeProperty + + int[] getPropertyNamespaceIDs(int gid) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the query! + stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM groupprop WHERE gid = ?;"); + stmt.setInt(1,gid); + rs = stmt.executeQuery(); + + // read out a list of the namespace IDs + ArrayList tmp = new ArrayList(); + while (rs.next()) + tmp.add(new Integer(rs.getInt(1))); + + // create and return the array + int[] rc = new int[tmp.size()]; + for (int i=0; i0); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end removeMember + + int[] getMembers(int gid) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + ArrayList tmp = null; + try + { // get a connection + conn = getConnection(); + + // create a query to get all the UIDs + stmt = conn.prepareStatement("SELECT uid FROM groupmembers WHERE gid = ?;"); + stmt.setInt(1,gid); + rs = stmt.executeQuery(); + + // fill the intermediate ArrayList + tmp = new ArrayList(); + while (rs.next()) + tmp.add(new Integer(rs.getInt(1))); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + // now translate into an integer array + int[] rc = new int[tmp.size()]; + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.security.Principal; +import java.security.acl.AclNotFoundException; +import java.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +abstract class GroupProxy implements DynamoGroup, DynamicWrapper +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + protected int m_gid; + protected String m_groupname; + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + protected GroupProxy(int gid) + { + m_gid = gid; + m_groupname = null; + + } // end constructor + + protected GroupProxy(int gid, String groupname) + { + m_gid = gid; + m_groupname = groupname; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + protected abstract DynamoGroup getRealGroup(); + + /*-------------------------------------------------------------------------------- + * Implementations from interface Principal + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object another) + { + if (another==null) + return false; + if (another instanceof DynamoGroup) + return (m_gid==((DynamoGroup)another).getGID()); + return false; + + } // end equals + + public String toString() + { + if (m_groupname!=null) + return "group " + m_groupname; + return getRealGroup().toString(); + + } // end toString + + public int hashCode() + { + return m_gid; + + } // end hashCode + + public String getName() + { + if (m_groupname!=null) + return m_groupname; + return getRealGroup().getName(); + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface Group + *-------------------------------------------------------------------------------- + */ + + public boolean addMember(Principal user) + { + return getRealGroup().addMember(user); + + } // end addMember + + public boolean removeMember(Principal user) + { + return getRealGroup().removeMember(user); + + } // end removeMember + + public boolean isMember(Principal member) + { + return getRealGroup().isMember(member); + + } // end isMember + + public Enumeration members() + { + return getRealGroup().members(); + + } // end members + + /*-------------------------------------------------------------------------------- + * Implementations from interface ObjectProvider + *-------------------------------------------------------------------------------- + */ + + /** + * Retrieves an object from this ObjectProvider. + * + * @param namespace The namespace to interpret the name relative to. + * @param name The name of the object to be retrieved. + * @return The object reference specified. + */ + public Object getObject(String namespace, String name) + { + return getRealGroup().getObject(namespace,name); + + } // end getObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface SecureObjectStore + *-------------------------------------------------------------------------------- + */ + + public Object setObject(DynamoUser caller, String namespace, String name, Object value) + throws DatabaseException, DynamoSecurityException + { + return getRealGroup().setObject(caller,namespace,name,value); + + } // end setObject + + public Object removeObject(DynamoUser caller, String namespace, String name) + throws DatabaseException, DynamoSecurityException + { + return getRealGroup().removeObject(caller,namespace,name); + + } // end removeObject + + public Collection getNamespaces() throws DatabaseException + { + return getRealGroup().getNamespaces(); + + } // end getNamespaces + + public Collection getNamesForNamespace(String namespace) throws DatabaseException + { + return getRealGroup().getNamesForNamespace(namespace); + + } // end getNamesForNamespace + + /*-------------------------------------------------------------------------------- + * Implementations from interface DynamoGroup + *-------------------------------------------------------------------------------- + */ + + public int getGID() + { + return m_gid; + + } // end getGID + + public boolean addUID(DynamoUser caller, int uid) throws DatabaseException, DynamoSecurityException + { + return getRealGroup().addUID(caller,uid); + + } // end addUID + + public boolean removeUID(DynamoUser caller, int uid) throws DatabaseException, DynamoSecurityException + { + return getRealGroup().removeUID(caller,uid); + + } // end removeUID + + public boolean testUID(int uid) throws DatabaseException + { + return getRealGroup().testUID(uid); + + } // end testUID + + public int[] getUIDs() throws DatabaseException + { + return getRealGroup().getUIDs(); + + } // end getUIDs + + public boolean addMember(DynamoUser caller, Principal member) + throws DatabaseException, DynamoSecurityException + { + return getRealGroup().addMember(caller,member); + + } // end addMember + + public boolean removeMember(DynamoUser caller, Principal member) + throws DatabaseException, DynamoSecurityException + { + return getRealGroup().removeMember(caller,member); + + } // end removeMember + + public DynamoAcl getAcl() throws DatabaseException, AclNotFoundException + { + return getRealGroup().getAcl(); + + } // end getAcl + + public void setAcl(DynamoUser caller, DynamoAcl acl) throws DatabaseException, DynamoSecurityException + { + getRealGroup().setAcl(caller,acl); + + } // end setAcl + + /*-------------------------------------------------------------------------------- + * Implementations from interface DynamicWrapper + *-------------------------------------------------------------------------------- + */ + + public Object unwrap() + { + return getRealGroup(); + + } // end unwrap + +} // end class GroupProxy diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStore.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStore.java new file mode 100644 index 0000000..5909667 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStore.java @@ -0,0 +1,42 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.security.Principal; +import com.silverwrist.dynamo.except.DatabaseException; +import com.silverwrist.dynamo.except.DynamoSecurityException; +import com.silverwrist.dynamo.iface.DataItem; +import com.silverwrist.dynamo.iface.DynamoUser; + +public interface ImageStore +{ + public DataItem getImage(int id) throws DatabaseException; + + public int saveNewImage(String type_namespace, String type_name, Principal owner, DataItem image) + throws DatabaseException; + + public void replaceImage(DynamoUser caller, int image_id, DataItem image) + throws DatabaseException, DynamoSecurityException; + + public int findImageID(String type_namespace, String type_name, Principal owner) throws DatabaseException; + + public void deleteImage(DynamoUser caller, int image_id) throws DatabaseException, DynamoSecurityException; + + public DataItem normalizeImage(DataItem source, int width, int height, String new_type) throws Exception; + +} // end interface ImageStore diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreObject.java new file mode 100644 index 0000000..ba7b48b --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreObject.java @@ -0,0 +1,249 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.security.Principal; +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.image.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +public class ImageStoreObject implements NamedObject, ComponentInitialize, ComponentShutdown, ImageStore +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_name; // object name + private NamespaceCache m_ns_cache; // namespace cache object + private ImageStoreOps m_ops; // image store operations + private Hashtable m_imagetype_tlb = new Hashtable(); // translates imagetypes + private Hashtable m_imagetype_rev_tlb = new Hashtable(); // translates imagetypes + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public ImageStoreObject() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final int imageTypeToIndex(PropertyKey pkey) throws DatabaseException + { + Integer foo = (Integer)(m_imagetype_tlb.get(pkey)); + if (foo!=null) + return foo.intValue(); + + int rc = m_ops.imageTypeToIndex(pkey); + foo = new Integer(rc); + m_imagetype_tlb.put(pkey,foo); + m_imagetype_rev_tlb.put(foo,pkey); + return rc; + + } // end imageTypeToIndex + + private final int imageTypeToIndex(int nsid, String name) throws DatabaseException + { + return imageTypeToIndex(new PropertyKey(nsid,name)); + + } // end imageTypeToIndex + + private final int imageTypeToIndex(String namespace, String name) throws DatabaseException + { + return imageTypeToIndex(new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name)); + + } // end imageTypeToIndex + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamedObject + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentInitialize + *-------------------------------------------------------------------------------- + */ + + public void initialize(Element config_root, ServiceProvider services) throws ConfigException + { + String conn_name = null; + String nscache_name = null; + XMLLoader loader = XMLLoader.get(); + try + { // verify the right node name + loader.verifyNodeName(config_root,"object"); + + // get the object's name + m_name = loader.getAttribute(config_root,"name"); + + // get the database configuration connection + DOMElementHelper config_root_h = new DOMElementHelper(config_root); + Element elt = loader.getSubElement(config_root_h,"database"); + conn_name = loader.getAttribute(elt,"connection"); + nscache_name = loader.getAttribute(elt,"namespaces"); + + } // end try + catch (XMLLoadException e) + { // error loading XML config data + throw new ConfigException(e); + + } // end catch + + // Get the database connection pool and namespace cache. + DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name); + m_ns_cache = + (NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name)); + + // Get the operations object. + m_ops = ImageStoreOps.get(pool); + + } // end initialize + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentShutdown + *-------------------------------------------------------------------------------- + */ + + public void shutdown() + { + m_ops.dispose(); + m_ops = null; + m_ns_cache = null; + + } // end shutdown + + /*-------------------------------------------------------------------------------- + * Implementations from interface ImageStore + *-------------------------------------------------------------------------------- + */ + + public DataItem getImage(int id) throws DatabaseException + { + return m_ops.getImage(id); + + } // end getImage + + public int saveNewImage(String type_namespace, String type_name, Principal owner, DataItem image) + throws DatabaseException + { + int image_type = imageTypeToIndex(type_namespace,type_name); + int owner_id = 0, owner_flag = 0; + if (owner instanceof DynamoUser) + owner_id = ((DynamoUser)owner).getUID(); + else if (owner instanceof DynamoGroup) + { // get the GID + owner_id = ((DynamoGroup)owner).getGID(); + owner_flag = 1; + + } // end else if + else + throw new DatabaseException(ImageStoreObject.class,"DatabaseMessages","img.badOwner"); + + // call down to the database to save it all off + return m_ops.saveNewImage(image_type,owner_id,owner_flag,image); + + } // end saveNewImage + + public void replaceImage(DynamoUser caller, int image_id, DataItem image) + throws DatabaseException, DynamoSecurityException + { + if (m_ops.canReplaceImage(caller.getUID(),image_id)) + m_ops.replaceImage(image_id,image); + else + { // throw a security exception here + DynamoSecurityException dse = new DynamoSecurityException(ImageStoreObject.class,"DatabaseMessages", + "img.notOwner"); + dse.setParameter(0,String.valueOf(image_id)); + throw dse; + + } // end else + + } // end replaceImage + + public int findImageID(String type_namespace, String type_name, Principal owner) throws DatabaseException + { + int image_type = imageTypeToIndex(type_namespace,type_name); + int owner_id = 0, owner_flag = 0; + if (owner instanceof DynamoUser) + owner_id = ((DynamoUser)owner).getUID(); + else if (owner instanceof DynamoGroup) + { // get the GID + owner_id = ((DynamoGroup)owner).getGID(); + owner_flag = 1; + + } // end else if + else + throw new DatabaseException(ImageStoreObject.class,"DatabaseMessages","img.badOwner"); + + // call down to find it + return m_ops.findImageID(image_type,owner_id,owner_flag); + + } // end findImageID + + public void deleteImage(DynamoUser caller, int image_id) throws DatabaseException, DynamoSecurityException + { + if (m_ops.canReplaceImage(caller.getUID(),image_id)) + m_ops.deleteImage(image_id); + else + { // throw a security exception here + DynamoSecurityException dse = new DynamoSecurityException(ImageStoreObject.class,"DatabaseMessages", + "img.notOwner"); + dse.setParameter(0,String.valueOf(image_id)); + throw dse; + + } // end else + + } // end deleteImage + + public DataItem normalizeImage(DataItem source, int width, int height, String new_type) throws Exception + { + try + { // normalize the image and encapsulate it in a StaticDataItem + byte[] data = ImageNormalizer.normalizeImage(source.getDataStream(),width,height,new_type); + return new StaticDataItem(source.getName() + "-converted",new_type,data.length,data); + + } // end try + catch (ImageNormalizerException e) + { // morph the exception + ExternalException ee = new ExternalException(ImageStoreObject.class,"DatabaseMessages", + "img.normalize",e); + ee.setParameter(0,source.getName()); + ee.setParameter(1,e.getMessage()); + throw ee; + + } // end catch + + } // end normalizeImage + +} // end class ImageStoreObject diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps.java new file mode 100644 index 0000000..de65d33 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps.java @@ -0,0 +1,80 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +abstract class ImageStoreOps extends OpsBase +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected ImageStoreOps(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class OpsBase + *-------------------------------------------------------------------------------- + */ + + public void dispose() + { + super.dispose(); + + } // end dispose + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + abstract int imageTypeToIndex(PropertyKey pkey) throws DatabaseException; + + abstract DataItem getImage(int id) throws DatabaseException; + + abstract int saveNewImage(int typecode, int owner_id, int owner_flag, DataItem image) + throws DatabaseException; + + abstract boolean canReplaceImage(int uid, int image_id) throws DatabaseException; + + abstract void replaceImage(int image_id, DataItem image) throws DatabaseException; + + abstract int findImageID(int typecode, int owner_id, int owner_flag) throws DatabaseException; + + abstract void deleteImage(int image_id) throws DatabaseException; + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + static ImageStoreOps get(DBConnectionPool pool) throws ConfigException + { + return (ImageStoreOps)get(pool,ImageStoreOps.class.getClassLoader(), + ImageStoreOps.class.getName() + "_","ImageStoreOps"); + + } // end get + +} // end class ImageStoreOps diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps_mysql.java new file mode 100644 index 0000000..cfa1619 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps_mysql.java @@ -0,0 +1,363 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.io.*; +import java.sql.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +public class ImageStoreOps_mysql extends ImageStoreOps +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public ImageStoreOps_mysql(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class ImageStoreOps + *-------------------------------------------------------------------------------- + */ + + int imageTypeToIndex(PropertyKey pkey) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table while we work + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES imagetype WRITE;"); + + // first try to look the index up + stmt = conn.prepareStatement("SELECT typecode FROM imagetype WHERE nsid = ? AND name = ?;"); + stmt.setInt(1,pkey.getNamespaceID()); + stmt.setString(2,pkey.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + return rs.getInt(1); + + // then add it + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + stmt = conn.prepareStatement("INSERT INTO imagetype (nsid, name) VALUES (?, ?);"); + stmt.setInt(1,pkey.getNamespaceID()); + stmt.setString(2,pkey.getName()); + stmt.executeUpdate(); + return MySQLUtils.getLastInsertInt(conn); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end imageTypeToIndex + + DataItem getImage(int id) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // Start by getting the MIME type and image length. + stmt = conn.prepareStatement("SELECT mimetype, length FROM imagestore WHERE imageid = ?;"); + stmt.setInt(1,id); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; + String mime_type = rs.getString(1); + int length = rs.getInt(2); + + // Now get the actual data blob. + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + stmt = conn.prepareStatement("SELECT data FROM imagestore WHERE imageid = ?;"); + stmt.setInt(1,id); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; + + // We need to copy the data blob into a local buffer. We also mesh the whole thing into a DataItem. + return new StaticDataItem("image" + id,mime_type,length,IOUtils.load(rs.getBinaryStream(1))); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + catch (IOException e) + { // turn IOException into DatabaseException too + DatabaseException de = new DatabaseException(ImageStoreOps_mysql.class,"DatabaseMessages", + "img.loadFail",e); + de.setParameter(0,String.valueOf(id)); + throw de; + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end getImage + + int saveNewImage(int typecode, int owner_id, int owner_flag, DataItem image) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + try + { // get a connection + conn = getConnection(); + + // lock the table while we work + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES imagestore WRITE;"); + + // insert all the "base" information + stmt = conn.prepareStatement("INSERT INTO imagestore (typecode, ownerid, ownerflag, mimetype, length) " + + "VALUES (?, ?, ?, ?, ?);"); + stmt.setInt(1,typecode); + stmt.setInt(2,owner_id); + stmt.setInt(3,owner_flag); + stmt.setString(4,image.getMimeType()); + stmt.setInt(5,image.getSize()); + stmt.executeUpdate(); + int rc = MySQLUtils.getLastInsertInt(conn); + + // insert the file data itself + SQLUtils.shutdown(stmt); + stmt = conn.prepareStatement("UPDATE imagestore SET data = ? WHERE imageid = ?;"); + stmt.setBlob(1,image.getBlob()); + stmt.setInt(2,rc); + stmt.executeUpdate(); + + return rc; // all done! + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end saveNewImage + + boolean canReplaceImage(int uid, int image_id) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // get the owner ID and flag from the image records + stmt = conn.prepareStatement("SELECT ownerid, ownerflag FROM imagestore WHERE imageid = ?;"); + stmt.setInt(1,image_id); + rs = stmt.executeQuery(); + if (!(rs.next())) + return false; + int owner_id = rs.getInt(1); + if (rs.getInt(2)==0) // a user owns it + return (uid==owner_id); + + // Test group membership for ownership. + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + stmt = conn.prepareStatement("SELECT uid FROM groupmembers WHERE uid = ? AND gid = ?;"); + stmt.setInt(1,uid); + stmt.setInt(2,owner_id); + rs = stmt.executeQuery(); + return rs.next(); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end canReplaceImage + + void replaceImage(int image_id, DataItem image) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + try + { // get a connection + conn = getConnection(); + + // lock the table while we work + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES imagestore WRITE;"); + + // poke in the basic data items first + stmt = conn.prepareStatement("UPDATE imagestore SET mimetype = ?, length = ?, data = NULL " + + "WHERE imageid = ?;"); + stmt.setString(1,image.getMimeType()); + stmt.setInt(2,image.getSize()); + stmt.setInt(3,image_id); + stmt.executeUpdate(); + + // insert the new file data itself + SQLUtils.shutdown(stmt); + stmt = conn.prepareStatement("UPDATE imagestore SET data = ? WHERE imageid = ?;"); + stmt.setBlob(1,image.getBlob()); + stmt.setInt(2,image_id); + stmt.executeUpdate(); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end replaceImage + + int findImageID(int typecode, int owner_id, int owner_flag) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // create statement and run it + stmt = conn.prepareStatement("SELECT imageid FROM imagestore WHERE typecode = ? AND ownerid = ? " + + "AND ownerflag = ?;"); + stmt.setInt(1,typecode); + stmt.setInt(2,owner_id); + stmt.setInt(3,owner_flag); + rs = stmt.executeQuery(); + if (rs.next()) + return rs.getInt(1); + else + return -1; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end findImageID + + void deleteImage(int image_id) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + try + { // get a connection + conn = getConnection(); + + // lock the table while we work + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES imagestore WRITE;"); + + // delete it! + stmt = conn.prepareStatement("DELETE FROM imagestore WHERE imageid = ?;"); + stmt.setInt(1,image_id); + stmt.executeUpdate(); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end deleteImage + +} // end class ImageStoreOps_mysql diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCache.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCache.java new file mode 100644 index 0000000..9b1d375 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCache.java @@ -0,0 +1,28 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import com.silverwrist.dynamo.except.DatabaseException; + +public interface NamespaceCache +{ + public int namespaceNameToId(String name) throws DatabaseException; + + public String namespaceIdToName(int id) throws DatabaseException; + +} // end interface NamespaceCache diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheObject.java new file mode 100644 index 0000000..d157027 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheObject.java @@ -0,0 +1,143 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.Namespaces; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +public class NamespaceCacheObject + implements NamedObject, ComponentInitialize, ComponentShutdown, NamespaceCache +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_name; // object name + private NamespaceCacheOps m_ops; // low-level database operations + private HashMap m_cache = new HashMap(); // namespace cache object + private HashMap m_rev_cache = new HashMap(); // namespace reverse cache object + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public NamespaceCacheObject() + { + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamedObject + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentInitialize + *-------------------------------------------------------------------------------- + */ + + public void initialize(Element config_root, ServiceProvider services) throws ConfigException + { + String conn_name = null; + XMLLoader loader = XMLLoader.get(); + try + { // verify the right node name + loader.verifyNodeName(config_root,"object"); + + // get the object's name + m_name = loader.getAttribute(config_root,"name"); + + // get the database configuration connection + Element elt = loader.getSubElement(config_root,"database"); + conn_name = loader.getAttribute(elt,"connection"); + + } // end try + catch (XMLLoadException e) + { // error loading XML config data + throw new ConfigException(e); + + } // end catch + + // Get the database connection pool. + DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name); + + // Get the database operations class. + m_ops = NamespaceCacheOps.get(pool); + + } // end initialize + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentShutdown + *-------------------------------------------------------------------------------- + */ + + public void shutdown() + { + m_ops.dispose(); + m_ops = null; + + } // end shutdown + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamespaceCache + *-------------------------------------------------------------------------------- + */ + + public synchronized int namespaceNameToId(String name) throws DatabaseException + { + Integer rc = (Integer)(m_cache.get(name)); + if (rc!=null) + return rc.intValue(); + int real_id = m_ops.namespaceNameToId(name); + rc = new Integer(real_id); + name = name.intern(); + m_cache.put(name,rc); + m_rev_cache.put(rc,name); + return real_id; + + } // end namespaceNameToId + + public synchronized String namespaceIdToName(int id) throws DatabaseException + { + Integer key = new Integer(id); + String rc = (String)(m_rev_cache.get(key)); + if (rc!=null) + return rc; + rc = m_ops.namespaceIdToName(id); + if (rc==null) + throw new DatabaseException(NamespaceCacheObject.class,"DatabaseMessages","nsCache.notFound"); + rc = rc.intern(); + m_cache.put(rc,key); + m_rev_cache.put(key,rc); + return rc; + + } // end namespaceIdToName + +} // end class NamespaceCacheObject diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps.java new file mode 100644 index 0000000..ad5d0c8 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps.java @@ -0,0 +1,69 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.lang.reflect.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +abstract class NamespaceCacheOps extends OpsBase +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected NamespaceCacheOps(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class OpsBase + *-------------------------------------------------------------------------------- + */ + + public void dispose() + { + super.dispose(); + + } // end dispose + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + abstract int namespaceNameToId(String name) throws DatabaseException; + + abstract String namespaceIdToName(int id) throws DatabaseException; + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + static NamespaceCacheOps get(DBConnectionPool pool) throws ConfigException + { + return (NamespaceCacheOps)get(pool,NamespaceCacheOps.class.getClassLoader(), + NamespaceCacheOps.class.getName() + "_","NamespaceCacheOps"); + + } // end get + +} // end class NamespaceCacheOps diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps_mysql.java new file mode 100644 index 0000000..7b01d95 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps_mysql.java @@ -0,0 +1,132 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +public class NamespaceCacheOps_mysql extends NamespaceCacheOps +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public NamespaceCacheOps_mysql(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class NamespaceCacheOps + *-------------------------------------------------------------------------------- + */ + + int namespaceNameToId(String name) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table while we do this + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES namespaces WRITE;"); + + // try the initial SELECT to see if it works + stmt = conn.prepareStatement("SELECT nsid FROM namespaces WHERE namespace = ?;"); + stmt.setString(1,name); + rs = stmt.executeQuery(); + if (rs.next()) + return rs.getInt(1); + + // it wasn't present - try adding it + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + stmt = conn.prepareStatement("INSERT INTO namespaces (namespace) VALUES (?);"); + stmt.setString(1,name); + stmt.executeUpdate(); + return MySQLUtils.getLastInsertInt(conn); + + } // end try + catch (SQLException e) + { // translate this to a DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end namespaceNameToId + + String namespaceIdToName(int id) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table while we do this + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES namespaces READ;"); + + // try the SELECT to see if it works + stmt = conn.prepareStatement("SELECT namespace FROM namespaces WHERE nsid = ?;"); + stmt.setInt(1,id); + rs = stmt.executeQuery(); + if (rs.next()) + return rs.getString(1); + else + return null; + + } // end try + catch (SQLException e) + { // translate the exception and rethrow + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end namespaceIdToName + +} // end class NamespaceCacheOps_mysql diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/OpsBase.java b/src/dynamo-framework/com/silverwrist/dynamo/db/OpsBase.java new file mode 100644 index 0000000..bbc7a96 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/OpsBase.java @@ -0,0 +1,118 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.lang.reflect.*; +import java.sql.Connection; +import java.sql.SQLException; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +public class OpsBase +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final Class[] ARGS_CLASS = { DBConnectionPool.class }; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DBConnectionPool m_pool; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected OpsBase(DBConnectionPool pool) + { + m_pool = pool; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + protected final DBConnectionPool getPool() + { + return m_pool; + + } // end getPool + + protected final Connection getConnection() throws DatabaseException + { + return new WrappedConnection(m_pool,m_pool.getConnection()); + + } // end getConnection + + protected final DatabaseException generalException(SQLException e) + { + DatabaseException dbe = new DatabaseException(OpsBase.class,"DatabaseMessages","general",e); + dbe.setParameter(0,e.getMessage()); + return dbe; + + } // end generalException + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + public void dispose() + { + m_pool = null; + + } // end dispose + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + protected static Object get(DBConnectionPool pool, ClassLoader loader, String stem_name, String type) + throws ConfigException + { + try + { // load the specified ops class and return a new instance + String klassname = stem_name + pool.getDatabaseType().toLowerCase(); + Constructor c = loader.loadClass(klassname).getConstructor(ARGS_CLASS); + Object[] args = new Object[1]; + args[0] = pool; + return c.newInstance(args); + + } // end try + catch (Exception e) + { // error loading the ops class... + ConfigException ce = new ConfigException(OpsBase.class,"DatabaseMessages","load.opsClass",e); + ce.setParameter(0,e.getMessage()); + ce.setParameter(1,pool.getDatabaseType()); + ce.setParameter(2,type); + throw ce; + + } // end catch + + } // end get + +} // end class OpsBase diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagement.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagement.java new file mode 100644 index 0000000..52f420f --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagement.java @@ -0,0 +1,42 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.Collection; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +public interface UserManagement +{ + public DynamoUser getAnonymousUser() throws DatabaseException; + + public DynamoUser getUser(int id) throws DatabaseException; + + public DynamoUser getUser(String username) throws DatabaseException; + + public DynamoUser createUser(String username, String email) throws DatabaseException; + + public DynamoGroup getGroup(int id) throws DatabaseException; + + public DynamoGroup getGroup(String groupname) throws DatabaseException; + + public DynamoGroup createGroup(String groupname) throws DatabaseException; + + public void loadUserDefaults(DynamoUser user, Collection namespaces) throws DatabaseException; + +} // end interface UserManagement diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerObject.java new file mode 100644 index 0000000..6b84b3b --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerObject.java @@ -0,0 +1,987 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.lang.ref.*; +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.UserInfoNamespace; +import com.silverwrist.dynamo.event.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.security.SecurityReferenceMonitor; +import com.silverwrist.dynamo.util.*; + +public class UserManagerObject + implements NamedObject, ComponentInitialize, ComponentShutdown, UserManagement, UserProxyManagement, + AuthenticatorRegistration, UserInfoNamespace, UserPropertyTranslatorInstall +{ + /*-------------------------------------------------------------------------------- + * Internal class implementing user proxies + *-------------------------------------------------------------------------------- + */ + + private class MyUserProxy extends UserProxy + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private DynamoUser m_real_user = null; + + /*==================================================================== + * Constructors + *==================================================================== + */ + + MyUserProxy(int uid) + { + super(uid); + + } // end constructor + + MyUserProxy(int uid, String username) + { + super(uid,username); + + } // end constructor + + /*==================================================================== + * Abstract implementations from class UserProxy + *==================================================================== + */ + + protected synchronized DynamoUser getRealUser() + { + if (m_real_user==null) + { // need to retrieve the real user... + try + { // get the real user... + m_real_user = UserManagerObject.this.getUser(m_uid); + + } // end try + catch (DatabaseException e) + { // wrap it in a runtime exception type + throw new ProxyException(e); + + } // end catch + + } // end if + + return m_real_user; + + } // end getRealUser + + } // end class MyUserProxy + + /*-------------------------------------------------------------------------------- + * Internal class implementing group proxies + *-------------------------------------------------------------------------------- + */ + + private class MyGroupProxy extends GroupProxy + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private DynamoGroup m_real_group = null; + + /*==================================================================== + * Constructors + *==================================================================== + */ + + MyGroupProxy(int gid) + { + super(gid); + + } // end constructor + + MyGroupProxy(int gid, String groupname) + { + super(gid,groupname); + + } // end constructor + + /*==================================================================== + * Abstract implementations from class UserProxy + *==================================================================== + */ + + protected synchronized DynamoGroup getRealGroup() + { + if (m_real_group==null) + { // need to retrieve the real group... + try + { // get the real group... + m_real_group = UserManagerObject.this.getGroup(m_gid); + + } // end try + catch (DatabaseException e) + { // wrap it in a runtime exception type + throw new ProxyException(e); + + } // end catch + + } // end if + + return m_real_group; + + } // end getRealGroup + + } // end class MyGroupProxy + + /*-------------------------------------------------------------------------------- + * Internal event listener class + *-------------------------------------------------------------------------------- + */ + + private class UpdateListener implements DynamicUpdateListener + { + /*==================================================================== + * Constructor + *==================================================================== + */ + + UpdateListener() + { // do nothing + } // end constructor + + /*==================================================================== + * Implementations from interface DynamicUpdateListener + *==================================================================== + */ + + public void updateReceived(DynamicUpdateEvent evt) + { + if (evt instanceof UserUpdateEvent) + { // try to pass the event on to the user + int uid = ((UserUpdateEvent)evt).getUID(); + Integer key = new Integer(uid); + synchronized (m_users_sync) + { // try looking in the cache for a UserObject + IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the user value + UserObject target = (UserObject)(cobj.get()); + if (target==null) + { // the UserObject got kicked out! kick it out of the HashMaps + m_id_to_user.remove(key); + m_name_to_user.remove(cobj.getNameKey()); + cobj.clear(); + cobj = null; + + } // end if + else if (target!=evt.getSource()) + target.updated((UserUpdateEvent)evt); + + } // end if + + } // end synchronized block + + } // end if + + } // end updateReceived + + } // end class UpdateListener + + /*-------------------------------------------------------------------------------- + * Internal property serializer class + *-------------------------------------------------------------------------------- + */ + + private class UserGroupSerializer implements PropertySerializer + { + /*==================================================================== + * Constructor + *==================================================================== + */ + + UserGroupSerializer() + { // do nothing + } // end constructor + + /*==================================================================== + * Implementations from interface PropertySerializer + *==================================================================== + */ + + public String serializeProperty(Object value) + { + if (value instanceof DynamoUser) + return "User:" + String.valueOf(((DynamoUser)value).getUID()); + + if (value instanceof DynamoGroup) + return "Group:" + String.valueOf(((DynamoGroup)value).getGID()); + + return null; + + } // end serializeProperty + + public Object deserializeProperty(String value) + { + try + { // look for our known prefixes + if (value.startsWith("User:")) + return getUserProxy(Integer.parseInt(value.substring(5))); + + if (value.startsWith("Group:")) + return getGroupProxy(Integer.parseInt(value.substring(6))); + + return null; + + } // end try + catch (NumberFormatException e) + { // number parse blew up... + return null; + + } // end catch + + } // end deserializeProperty + + } // end UserGroupSerializer + + /*-------------------------------------------------------------------------------- + * Internal class implementing the adapter for UserPropertyTranslator + *-------------------------------------------------------------------------------- + */ + + class UserPropertyAdapter implements UserPropertyTranslator + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private UserPropertyTranslator m_upt = null; + + /*==================================================================== + * Constructor + *==================================================================== + */ + + UserPropertyAdapter() + { // do nothing + } // end constructor + + /*==================================================================== + * Implementations from interface UserPropertyTranslator + *==================================================================== + */ + + public String getUserFullName(DynamoUser user) + { + if (m_upt!=null) + return m_upt.getUserFullName(user); + else + return user.getName(); + + } // end getUserFullName + + /*==================================================================== + * External operations + *==================================================================== + */ + + void setTranslator(UserPropertyTranslator upt) + { + m_upt = upt; + + } // end setTranslator + + } // end class UserPropertyAdapter + + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final int MAX_USERNAME = 64; + private static final int MAX_GROUPNAME = 64; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private UserPropertyAdapter m_adapter; // user property adapter + private String m_name; // object name + private NamespaceCache m_ns_cache; // namespace cache object + private SecurityReferenceMonitor m_srm; // security reference monitor + private PostDynamicUpdate m_post; // dynamic update poster + private UserManagerOps m_ops; // database operations object + private UserObject m_anon_user = null; // permanent reference to anonymous user + private Object m_anon_user_sync = new Object(); // synchronization on the above field + private HashMap m_id_to_user = new HashMap(); // map from IDs (Integer) to objects + private HashMap m_name_to_user = new HashMap(); // map from names (DynamoIDKey) to objects + private ReferenceQueue m_rq = new ReferenceQueue(); // reference queue for old objects + private Object m_users_sync = new Object(); // synchronization for user HashMaps + private HashMap m_id_to_group = new HashMap(); // map from IDs (Integer) to groups + private HashMap m_name_to_group = new HashMap(); // map from names (DynamoIDKey) to groups + private ReferenceQueue m_group_rq = new ReferenceQueue(); // reference queue for group objects + private Object m_groups_sync = new Object(); // synchronization for group HashMaps + private Hashtable m_authenticators = new Hashtable(); // authenticators list + private ComponentShutdown m_hook_init; // hook for init service provider + private ComponentShutdown m_pszreg; // property serializer registration + private ComponentShutdown m_evt_user; // event registration + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public UserManagerObject() + { + m_adapter = new UserPropertyAdapter(); // create the adapter + + // Add some default authenticators. + m_authenticators.put(new QualifiedNameKey(NAMESPACE,AUTH_DEFAULT),new DefaultHashAuthenticator()); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamedObject + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentInitialize + *-------------------------------------------------------------------------------- + */ + + public void initialize(Element config_root, ServiceProvider services) throws ConfigException + { + String conn_name = null; + String nscache_name = null; + String srm_name = null; + String connect_name = null; + XMLLoader loader = XMLLoader.get(); + try + { // verify the right node name + loader.verifyNodeName(config_root,"object"); + + // get the object's name + m_name = loader.getAttribute(config_root,"name"); + + // get the database configuration connection + DOMElementHelper config_root_h = new DOMElementHelper(config_root); + Element elt = loader.getSubElement(config_root_h,"database"); + conn_name = loader.getAttribute(elt,"connection"); + nscache_name = loader.getAttribute(elt,"namespaces"); + + // get the security reference monitor reference + elt = loader.getSubElement(config_root_h,"security"); + srm_name = loader.getAttribute(elt,"object"); + + // get the name of the connection point to connect ourselves to + elt = config_root_h.getSubElement("connect-proxy-services"); + if (elt!=null) + connect_name = loader.getAttribute(elt,"cpoint"); + + } // end try + catch (XMLLoadException e) + { // error loading XML config data + throw new ConfigException(e); + + } // end catch + + // Get the database connection pool, namespace cache, and security reference monitor. + DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name); + m_ns_cache = + (NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name)); + m_srm = + (SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class, + srm_name)); + m_post = (PostDynamicUpdate)(services.queryService(PostDynamicUpdate.class)); + + // Get the operations object. + m_ops = UserManagerOps.get(pool); + + // Connect our proxy services to the connection point. + if (connect_name!=null) + { // get the ConnectionBackend service and use it to jack in + ConnectionBackEnd backend = (ConnectionBackEnd)(services.queryService(ConnectionBackEnd.class)); + backend.connectObject(connect_name,this); + + } // end if + + // Register event listeners that forward events to the right location. + EventListenerRegistration reg = + (EventListenerRegistration)(services.queryService(EventListenerRegistration.class)); + UpdateListener ul = new UpdateListener(); + m_evt_user = reg.registerDynamicUpdateListener(UserUpdateEvent.class,ul); + + // Register our property serializer to let User and Group objects be serialized. + PropertySerializerRegistration psreg = + (PropertySerializerRegistration)(services.queryService(PropertySerializerRegistration.class)); + m_pszreg = psreg.registerPropertySerializer(new UserGroupSerializer()); + + // Add us to the initialization services. + HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class)); + SingletonServiceProvider ssp = new SingletonServiceProvider("UserManagerObject", + AuthenticatorRegistration.class, + (AuthenticatorRegistration)this); + m_hook_init = hooker.hookInitServiceProvider(ssp); + + } // end initialize + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentShutdown + *-------------------------------------------------------------------------------- + */ + + public void shutdown() + { + m_evt_user.shutdown(); + m_evt_user = null; + m_pszreg.shutdown(); + m_pszreg = null; + m_hook_init.shutdown(); + m_hook_init = null; + m_authenticators.clear(); + m_id_to_user.clear(); + m_name_to_user.clear(); + m_anon_user = null; + m_ops.dispose(); + m_ops = null; + m_post = null; + m_srm = null; + m_ns_cache = null; + + } // end shutdown + + /*-------------------------------------------------------------------------------- + * Implementations from interface UserManagement + *-------------------------------------------------------------------------------- + */ + + public DynamoUser getAnonymousUser() throws DatabaseException + { + synchronized (m_anon_user_sync) + { // get the anonymous user, if it doesn't already exist + if (m_anon_user==null) + { // get the data for the anonymous user + Map data = m_ops.getAnonymousUserData(); + if (data==null) + throw new DatabaseException(UserManagerObject.class,"UserMessages","anon.notFound"); + m_anon_user = new UserObject(data,true,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,m_adapter); + + } // end if + + return m_anon_user; + + } // end synchronized block + + } // end getAnonymousUser + + public DynamoUser getUser(int id) throws DatabaseException + { + DynamoUser rc = getAnonymousUser(); + if (rc.getUID()==id) + return rc; + + rc = null; + Integer key = new Integer(id); + synchronized (m_users_sync) + { // try to retrieve the user + IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the user value + rc = (DynamoUser)(cobj.get()); + if (rc==null) + { // the UserObject got kicked out! kick it out of the HashMaps + m_id_to_user.remove(key); + m_name_to_user.remove(cobj.getNameKey()); + cobj.clear(); + cobj = null; + + } // end if + + } // end if + + if (rc==null) + { // OK, we have to go to the database to find the user + Map data = m_ops.getUserData(id); + if (data!=null) + { // create UserObject and add it to our cache maps + UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post, + m_adapter); + rc = uobj; + cobj = new IDNameCacheObject(key,uobj.getName(),uobj,m_rq); + m_id_to_user.put(cobj.getIDKey(),cobj); + m_name_to_user.put(cobj.getNameKey(),cobj); + + } // end if + // else user does not exist - return null + + } // end if + + } // end synchronized block + + return rc; + + } // end getUser + + public DynamoUser getUser(String username) throws DatabaseException + { + DynamoUser rc = getAnonymousUser(); + if (rc.getName().equalsIgnoreCase(username)) + return rc; + + rc = null; + DynamoIDKey key = new DynamoIDKey(username); + synchronized (m_users_sync) + { // try to retrieve the user + IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_user.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the user value + rc = (DynamoUser)(cobj.get()); + if (rc==null) + { // the UserObject got kicked out! kick it out of the HashMaps + m_id_to_user.remove(cobj.getIDKey()); + m_name_to_user.remove(key); + cobj.clear(); + cobj = null; + + } // end if + + } // end if + + if (rc==null) + { // OK, we have to go to the database to find the user + Map data = m_ops.getUserData(username); + if (data!=null) + { // create user object and add it to our cache maps + UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post, + m_adapter); + rc = uobj; + cobj = new IDNameCacheObject(uobj.getUID(),key,uobj,m_rq); + m_id_to_user.put(cobj.getIDKey(),cobj); + m_name_to_user.put(cobj.getNameKey(),cobj); + + } // end if + // else user does not exist - return null + + } // end if + + } // end synchronized block + + return rc; + + } // end getUser + + public DynamoUser createUser(String username, String email) throws DatabaseException + { + DynamoUser rc = getAnonymousUser(); + if (rc.getName().equalsIgnoreCase(username)) + { // this user already exists + DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.exists"); + de.setParameter(0,username); + throw de; + + } // end if + + DynamoIDKey key = new DynamoIDKey(username); + if (!(key.isValid(MAX_USERNAME))) + { // the user ID is invalid... + DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.badID"); + de.setParameter(0,username); + throw de; + + } // end if + + rc = null; + synchronized (m_users_sync) + { // see if the user is in our cache already + IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_user.get(key)); + if (cobj!=null) + { // it's in the cache - we're going to fail this operation. But while we're here, if the + // actual user object has been kicked out, expunge the reference. + if (cobj.get()==null) + { // the UserObject got kicked out! kick it out of the HashMaps + m_id_to_user.remove(cobj.getIDKey()); + m_name_to_user.remove(key); + cobj.clear(); + cobj = null; + + } // end if + + // throw the exception saying that we exist + DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.exists"); + de.setParameter(0,username); + throw de; + + } // end if + + // OK, at this point, we can't be any surer the user doesn't already exist without + // hitting the database. So create it. (createNewUser will throw a DatabaseException if the + // user already exists.) + Map data = m_ops.createNewUser(username,email); + UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,m_adapter); + rc = uobj; + cobj = new IDNameCacheObject(uobj.getUID(),key,uobj,m_rq); + m_id_to_user.put(cobj.getIDKey(),cobj); + m_name_to_user.put(cobj.getNameKey(),cobj); + + } // end synchronized block + + return rc; // new user created! + + } // end createUser + + public DynamoGroup getGroup(int id) throws DatabaseException + { + DynamoGroup rc = null; + Integer key = new Integer(id); + synchronized (m_groups_sync) + { // try to retrieve the group + IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the group value + rc = (DynamoGroup)(cobj.get()); + if (rc==null) + { // the GroupObject got kicked out! kick it out of the HashMaps + m_id_to_group.remove(key); + m_name_to_group.remove(cobj.getNameKey()); + cobj.clear(); + cobj = null; + + } // end if + + } // end if + + if (rc==null) + { // OK, we have to go to the database to find the group + Map data = m_ops.getGroupData(id); + if (data!=null) + { // create GroupObject and add it to our cache maps + GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this); + rc = gobj; + cobj = new IDNameCacheObject(key,gobj.getName(),gobj,m_group_rq); + m_id_to_group.put(cobj.getIDKey(),cobj); + m_name_to_group.put(cobj.getNameKey(),cobj); + + } // end if + // else group does not exist - return null + + } // end if + + } // end synchronized block + + return rc; + + } // end getGroup + + public DynamoGroup getGroup(String groupname) throws DatabaseException + { + DynamoGroup rc = null; + DynamoIDKey key = new DynamoIDKey(groupname); + synchronized (m_groups_sync) + { // try to retrieve the group + IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_group.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the group value + rc = (DynamoGroup)(cobj.get()); + if (rc==null) + { // the GroupObject got kicked out! kick it out of the HashMaps + m_id_to_group.remove(cobj.getIDKey()); + m_name_to_group.remove(key); + cobj.clear(); + cobj = null; + + } // end if + + } // end if + + if (rc==null) + { // OK, we have to go to the database to find the group + Map data = m_ops.getGroupData(groupname); + if (data!=null) + { // create group object and add it to our cache maps + GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this); + rc = gobj; + cobj = new IDNameCacheObject(gobj.getGID(),key,gobj,m_group_rq); + m_id_to_group.put(cobj.getIDKey(),cobj); + m_name_to_group.put(cobj.getNameKey(),cobj); + + } // end if + // else group does not exist - return null + + } // end if + + } // end synchronized block + + return rc; + + } // end getGroup + + public DynamoGroup createGroup(String groupname) throws DatabaseException + { + DynamoIDKey key = new DynamoIDKey(groupname); + if (!(key.isValid(MAX_GROUPNAME))) + { // the group ID is invalid... + DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","group.badID"); + de.setParameter(0,groupname); + throw de; + + } // end if + + DynamoGroup rc = null; + synchronized (m_groups_sync) + { // see if the group is in our cache already + IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_group.get(key)); + if (cobj!=null) + { // it's in the cache - we're going to fail this operation. But while we're here, if the + // actual group object has been kicked out, expunge the reference. + if (cobj.get()==null) + { // the GroupObject got kicked out! kick it out of the HashMaps + m_id_to_group.remove(cobj.getIDKey()); + m_name_to_group.remove(key); + cobj.clear(); + cobj = null; + + } // end if + + // throw the exception saying that we exist + DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","group.exists"); + de.setParameter(0,groupname); + throw de; + + } // end if + + // OK, at this point, we can't be any surer the group doesn't already exist without + // hitting the database. So create it. (createNewGroup will throw a DatabaseException if the + // group already exists.) + Map data = m_ops.createNewGroup(groupname); + GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this); + rc = gobj; + cobj = new IDNameCacheObject(gobj.getGID(),key,gobj,m_group_rq); + m_id_to_group.put(cobj.getIDKey(),cobj); + m_name_to_group.put(cobj.getNameKey(),cobj); + + } // end synchronized block + + return rc; // new group created! + + } // end createNewGroup + + public void loadUserDefaults(DynamoUser user, Collection namespaces) throws DatabaseException + { + // Start by translating all the namespaces to namespace IDs. + int[] nsids = new int[namespaces.size()]; + int i = 0; + Iterator it = namespaces.iterator(); + while (it.hasNext()) + nsids[i++] = m_ns_cache.namespaceNameToId(it.next().toString()); + + // Now feed it into the database operations. + m_ops.loadUserDefaults(user.getUID(),nsids); + + } // end loadUserDefaults + + /*-------------------------------------------------------------------------------- + * Implementations from interface UserProxyManagement + *-------------------------------------------------------------------------------- + */ + + public DynamoUser getUserProxy(int uid) + { + synchronized (m_anon_user_sync) + { // get the anonymous user, if it's there and matches + if ((m_anon_user!=null) && (m_anon_user.getUID()==uid)) + return m_anon_user; + + } // end synchronized block + + Integer key = new Integer(uid); + synchronized (m_users_sync) + { // try to retrieve the user + IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the user value + DynamoUser rc = (DynamoUser)(cobj.get()); + if (rc==null) + { // the UserObject got kicked out! kick it out of the HashMaps + m_id_to_user.remove(key); + m_name_to_user.remove(cobj.getNameKey()); + rc = new MyUserProxy(uid,cobj.getNameKey().toString()); + cobj.clear(); + cobj = null; + + } // end if + + return rc; + + } // end if + + return new MyUserProxy(uid); // just return a proxy object + + } // end synchronized block + + } // end getUserProxy + + public DynamoUser getUserProxy(int uid, String username) + { + synchronized (m_anon_user_sync) + { // get the anonymous user, if it's there and matches + if ((m_anon_user!=null) && (m_anon_user.getUID()==uid)) + return m_anon_user; + + } // end synchronized block + + Integer key = new Integer(uid); + synchronized (m_users_sync) + { // try to retrieve the user + IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the user value + DynamoUser rc = (DynamoUser)(cobj.get()); + if (rc==null) + { // the UserObject got kicked out! kick it out of the HashMaps + m_id_to_user.remove(key); + m_name_to_user.remove(cobj.getNameKey()); + rc = new MyUserProxy(uid,cobj.getNameKey().toString()); + cobj.clear(); + cobj = null; + + } // end if + + return rc; + + } // end if + + return new MyUserProxy(uid,username); // just return a proxy object + + } // end synchronized block + + } // end getUserProxy + + public DynamoGroup getGroupProxy(int gid) + { + Integer key = new Integer(gid); + synchronized (m_groups_sync) + { // try to retrieve the group + IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the group value + DynamoGroup rc = (DynamoGroup)(cobj.get()); + if (rc==null) + { // the GroupObject got kicked out! kick it out of the HashMaps + m_id_to_group.remove(key); + m_name_to_group.remove(cobj.getNameKey()); + rc = new MyGroupProxy(gid,cobj.getNameKey().toString()); + cobj.clear(); + cobj = null; + + } // end if + + return rc; + + } // end if + + return new MyGroupProxy(gid); // just return a proxy object + + } // end synchronized block + + } // end getGroupProxy + + public DynamoGroup getGroupProxy(int gid, String groupname) + { + Integer key = new Integer(gid); + synchronized (m_groups_sync) + { // try to retrieve the group + IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key)); + if (cobj!=null) + { // got a cache object - retrieve the group value + DynamoGroup rc = (DynamoGroup)(cobj.get()); + if (rc==null) + { // the GroupObject got kicked out! kick it out of the HashMaps + m_id_to_group.remove(key); + m_name_to_group.remove(cobj.getNameKey()); + rc = new MyGroupProxy(gid,cobj.getNameKey().toString()); + cobj.clear(); + cobj = null; + + } // end if + + return rc; + + } // end if + + return new MyGroupProxy(gid,groupname); // just return a proxy object + + } // end synchronized block + + } // end getGroupProxy + + /*-------------------------------------------------------------------------------- + * Implementations from interface AuthenticatorLookup + *-------------------------------------------------------------------------------- + */ + + public Authenticator findAuthenticator(String method_namespace, String method) + { + return (Authenticator)(m_authenticators.get(new QualifiedNameKey(method_namespace,method))); + + } // end findAuthenticator + + /*-------------------------------------------------------------------------------- + * Implementations from interface AuthenticatorRegistration + *-------------------------------------------------------------------------------- + */ + + public ComponentShutdown registerAuthenticator(String method_namespace, String method, Authenticator auth) + throws ConfigException + { + QualifiedNameKey key = new QualifiedNameKey(method_namespace,method); + if (m_authenticators.containsKey(key)) + { // dump out here + ConfigException ce = new ConfigException(UserManagerObject.class,"DatabaseMessages","auth.register"); + ce.setParameter(0,method_namespace); + ce.setParameter(1,method); + throw ce; + + } // end if + + m_authenticators.put(key,auth); + return new ShutdownHashtableRemove(m_authenticators,key); + + } // end registerAuthenticator + + /*-------------------------------------------------------------------------------- + * Implementations from interface UserPropertyTranslatorInstall + *-------------------------------------------------------------------------------- + */ + + public void installUserPropertyTranslator(UserPropertyTranslator upt) + { + m_adapter.setTranslator(upt); + + } // end installUserPropertyTranslator + +} // end class UserManagerObject diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps.java new file mode 100644 index 0000000..1abacb4 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps.java @@ -0,0 +1,102 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +abstract class UserManagerOps extends OpsBase +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + static final String HMKEY_UID = "uid"; + static final String HMKEY_USERNAME = "username"; + static final String HMKEY_EMAIL = "email"; + static final String HMKEY_LOCKED = "locked"; + static final String HMKEY_NOSPAM = "nospam"; + static final String HMKEY_CREATED = "created"; + static final String HMKEY_LAST_ACCESS = "last_accessed"; + + static final String HMKEY_GID = "gid"; + static final String HMKEY_GROUPNAME = "groupname"; + static final String HMKEY_GACLID = "gaclid"; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected UserManagerOps(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class OpsBase + *-------------------------------------------------------------------------------- + */ + + public void dispose() + { + super.dispose(); + + } // end dispose + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + abstract UserObjectOps getObjectOps(); + + abstract GroupObjectOps getGroupOps(); + + abstract Map getAnonymousUserData() throws DatabaseException; + + abstract Map getUserData(int id) throws DatabaseException; + + abstract Map getUserData(String username) throws DatabaseException; + + abstract Map createNewUser(String username, String email) throws DatabaseException; + + abstract Map getGroupData(int id) throws DatabaseException; + + abstract Map getGroupData(String groupname) throws DatabaseException; + + abstract Map createNewGroup(String groupname) throws DatabaseException; + + abstract void loadUserDefaults(int uid, int[] nsids) throws DatabaseException; + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + static UserManagerOps get(DBConnectionPool pool) throws ConfigException + { + return (UserManagerOps)get(pool,UserManagerOps.class.getClassLoader(), + UserManagerOps.class.getName() + "_","UserManagerOps"); + + } // end get + +} // end class UserManagerOps diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps_mysql.java new file mode 100644 index 0000000..2dbaed9 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps_mysql.java @@ -0,0 +1,463 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +public class UserManagerOps_mysql extends UserManagerOps +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final Integer GACLID_NONE = new Integer(-1); + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DBUtilities m_utils; // reference to utilities object + private UserObjectOps m_obj_ops = null; // object operations object + private GroupObjectOps m_group_ops = null; // group operations object + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public UserManagerOps_mysql(DBConnectionPool pool) + { + super(pool); + m_utils = (DBUtilities)(pool.queryService(DBUtilities.class)); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class UserManagerOps + *-------------------------------------------------------------------------------- + */ + + synchronized UserObjectOps getObjectOps() + { + if (m_obj_ops==null) + m_obj_ops = new UserObjectOps_mysql(getPool(),m_utils); + return m_obj_ops; + + } // end getObjectOps + + synchronized GroupObjectOps getGroupOps() + { + if (m_group_ops==null) + m_group_ops = new GroupObjectOps_mysql(getPool(),m_utils); + return m_group_ops; + + } // end getGroupOps + + Map getAnonymousUserData() throws DatabaseException + { + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + try + { // get a connection and statement + conn = getConnection(); + stmt = conn.createStatement(); + rs = stmt.executeQuery("SELECT uid, username, email, created, last_accessed FROM users " + + "WHERE is_anon = 1;"); + if (!(rs.next())) + return null; // no anonymous user info (will throw exception later) + + // Create and return the Map containing the user data. + HashMap rc = new HashMap(); + rc.put(HMKEY_UID,new Integer(rs.getInt(1))); + rc.put(HMKEY_USERNAME,rs.getString(2)); + rc.put(HMKEY_EMAIL,rs.getString(3)); + rc.put(HMKEY_LOCKED,Boolean.FALSE); + rc.put(HMKEY_NOSPAM,Boolean.TRUE); + rc.put(HMKEY_CREATED,m_utils.getDateTime(rs,4)); + java.util.Date lacc = m_utils.getDateTime(rs,5); + if (lacc!=null) + rc.put(HMKEY_LAST_ACCESS,lacc); + return rc; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end getAnonymousUserData + + Map getUserData(int id) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the statement to get the user data + stmt = conn.prepareStatement("SELECT username, email, locked, nospam, created, last_accessed FROM users " + + "WHERE uid = ? AND is_anon = 0;"); + stmt.setInt(1,id); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // no user info + + // Create and return the Map containing the user data. + HashMap rc = new HashMap(); + rc.put(HMKEY_UID,new Integer(id)); + rc.put(HMKEY_USERNAME,rs.getString(1)); + rc.put(HMKEY_EMAIL,rs.getString(2)); + rc.put(HMKEY_LOCKED,Boolean.valueOf(rs.getBoolean(3))); + rc.put(HMKEY_NOSPAM,Boolean.valueOf(rs.getBoolean(4))); + rc.put(HMKEY_CREATED,m_utils.getDateTime(rs,5)); + java.util.Date lacc = m_utils.getDateTime(rs,6); + if (lacc!=null) + rc.put(HMKEY_LAST_ACCESS,lacc); + return rc; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end getUserData + + Map getUserData(String username) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the statement to get the user data + stmt = conn.prepareStatement("SELECT uid, email, locked, nospam, created, last_accessed FROM users " + + "WHERE username = ? AND is_anon = 0;"); + stmt.setString(1,username); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // no user info + + // Create and return the Map containing the user data. + HashMap rc = new HashMap(); + rc.put(HMKEY_UID,new Integer(rs.getInt(1))); + rc.put(HMKEY_USERNAME,username); + rc.put(HMKEY_EMAIL,rs.getString(2)); + rc.put(HMKEY_LOCKED,Boolean.valueOf(rs.getBoolean(3))); + rc.put(HMKEY_NOSPAM,Boolean.valueOf(rs.getBoolean(4))); + rc.put(HMKEY_CREATED,m_utils.getDateTime(rs,5)); + java.util.Date lacc = m_utils.getDateTime(rs,6); + if (lacc!=null) + rc.put(HMKEY_LAST_ACCESS,lacc); + return rc; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end getUserData + + Map createNewUser(String username, String email) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the users table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES users WRITE;"); + + // see if the user already exists + stmt = conn.prepareStatement("SELECT uid FROM users WHERE username = ?;"); + stmt.setString(1,username); + rs = stmt.executeQuery(); + if (rs.next()) + { // user exists - our operation is blown + DatabaseException de = new DatabaseException(UserManagerOps_mysql.class,"UserMessages","user.exists"); + de.setParameter(0,username); + throw de; + + } // end if + + // close down previous statement in prep for next one + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + // insert the new user record! + stmt = conn.prepareStatement("INSERT INTO users (username, email, created) VALUES (?, ?, ?);"); + stmt.setString(1,username); + stmt.setString(2,email); + java.util.Date created = new java.util.Date(); + m_utils.setDateTime(stmt,3,created); + stmt.executeUpdate(); + + // Generate the return Map, suitable for creating a new object. + HashMap rc = new HashMap(); + rc.put(HMKEY_UID,new Integer(MySQLUtils.getLastInsertInt(conn))); + rc.put(HMKEY_USERNAME,username); + rc.put(HMKEY_EMAIL,email); + rc.put(HMKEY_LOCKED,Boolean.FALSE); + rc.put(HMKEY_NOSPAM,Boolean.FALSE); + rc.put(HMKEY_CREATED,created); + return rc; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end createNewUser + + Map getGroupData(int id) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the statement to get the group data + stmt = conn.prepareStatement("SELECT groupname, gaclid FROM groups WHERE gid = ?;"); + stmt.setInt(1,id); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // no group info + + // Create and return the Map containing the group data. + HashMap rc = new HashMap(); + rc.put(HMKEY_GID,new Integer(id)); + rc.put(HMKEY_GROUPNAME,rs.getString(1)); + rc.put(HMKEY_GACLID,new Integer(rs.getInt(2))); + return rc; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end getGroupData + + Map getGroupData(String groupname) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the statement to get the group data + stmt = conn.prepareStatement("SELECT gid, gaclid FROM groups WHERE groupname = ?;"); + stmt.setString(1,groupname); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // no group info + + // Create and return the Map containing the group data. + HashMap rc = new HashMap(); + rc.put(HMKEY_GID,new Integer(rs.getInt(1))); + rc.put(HMKEY_GROUPNAME,groupname); + rc.put(HMKEY_GACLID,new Integer(rs.getInt(2))); + return rc; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + } // end getGroupData + + Map createNewGroup(String groupname) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the groups table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES groups WRITE;"); + + // see if the group already exists + stmt = conn.prepareStatement("SELECT gid FROM groups WHERE groupname = ?;"); + stmt.setString(1,groupname); + rs = stmt.executeQuery(); + if (rs.next()) + { // group exists - our operation is blown + DatabaseException de = new DatabaseException(UserManagerOps_mysql.class,"UserMessages","group.exists"); + de.setParameter(0,groupname); + throw de; + + } // end if + + // close down previous statement in prep for next one + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + // insert the new group record! + stmt = conn.prepareStatement("INSERT INTO groups (groupname) VALUES (?);"); + stmt.setString(1,groupname); + stmt.executeUpdate(); + + // Generate the return Map, suitable for creating a new object. + HashMap rc = new HashMap(); + rc.put(HMKEY_GID,new Integer(MySQLUtils.getLastInsertInt(conn))); + rc.put(HMKEY_GROUPNAME,groupname); + rc.put(HMKEY_GACLID,GACLID_NONE); + return rc; + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + } // end createNewGroup + + void loadUserDefaults(int uid, int[] nsids) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt_insert = null; + Statement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the global and user properties tables + stmt = conn.createStatement(); + stmt.executeUpdate("LOCK TABLES userprop WRITE, globalprop READ;"); + + // prepare the fancy insert statement + stmt_insert = conn.prepareStatement("INSERT INTO userprop (uid, nsid, prop_name, prop_value) " + + "SELECT ?, globalprop.nsid, globalprop.prop_name, " + + "globalprop.prop_value FROM globalprop " + + "WHERE globalprop.nsid = ?;"); + for (int i=0; i. +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# --------------------------------------------------------------------------------- +# This file has been localized for the en_US locale +anon.notFound=Internal Error: Unable to load information for the anonymous user. +user.exists=User "{0}" already exists in the database. +user.badID=The user name "{0}" is not valid. +group.exists=Group "{0}" already exists in the database. +group.badID=The group name "{0}" is not valid. diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObject.java new file mode 100644 index 0000000..5e84e17 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObject.java @@ -0,0 +1,527 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import org.apache.commons.collections.*; +import com.silverwrist.dynamo.UserInfoNamespace; +import com.silverwrist.dynamo.event.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.security.SecurityReferenceMonitor; +import com.silverwrist.dynamo.util.*; + +class UserObject implements DynamoUser, UserInfoNamespace +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private UserObjectOps m_ops; // operations object + private NamespaceCache m_ns_cache; // namespace cache object + private SecurityReferenceMonitor m_srm; // security reference monitor + private AuthenticatorLookup m_auth_lookup; // authenticator lookup + private PostDynamicUpdate m_post; // where we post dynamic events + private UserPropertyTranslator m_upt; + private int m_uid; // user ID + private String m_username; // user name + private String m_email; // E-mail address + private java.util.Date m_created; // created date + private java.util.Date m_last_accessed; // last access date + private boolean m_anonymous; // is this the anonymous user? + private boolean m_locked; // is user locked? + private boolean m_nospam; // user "no-spam" flag + private ReferenceMap m_properties; // cached property values + private Object m_properties_sync = new Object(); // synchronization for above + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + UserObject(Map data, boolean anonymous, UserObjectOps ops, NamespaceCache ns_cache, + SecurityReferenceMonitor srm, AuthenticatorLookup auth_lookup, PostDynamicUpdate post, + UserPropertyTranslator upt) + { + m_ops = ops; + m_ns_cache = ns_cache; + m_srm = srm; + m_auth_lookup = auth_lookup; + m_post = post; + m_upt = upt; + m_uid = ((Integer)(data.get(UserManagerOps.HMKEY_UID))).intValue(); + m_username = (String)(data.get(UserManagerOps.HMKEY_USERNAME)); + m_email = (String)(data.get(UserManagerOps.HMKEY_EMAIL)); + m_created = (java.util.Date)(data.get(UserManagerOps.HMKEY_CREATED)); + m_last_accessed = (java.util.Date)(data.get(UserManagerOps.HMKEY_LAST_ACCESS)); + m_anonymous = anonymous; + m_locked = ((Boolean)(data.get(UserManagerOps.HMKEY_LOCKED))).booleanValue(); + m_nospam = ((Boolean)(data.get(UserManagerOps.HMKEY_NOSPAM))).booleanValue(); + m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final void testChangeOK(DynamoUser caller) throws DatabaseException, DynamoSecurityException + { + if (equals(caller)) + return; // a user can always change their OWN information + + if (caller.equals(m_srm.getAdminUser())) + return; // Administrator can do anything + + if (m_srm.getGlobalAcl().testPermission(caller,NAMESPACE,PERM_EDIT_ALL)) + return; // and so can anyone else with "edit all" permission on the global ACL + + // Presume the change is forbidden - throw the exception + DynamoSecurityException dse = new DynamoSecurityException(UserObject.class,"DatabaseMessages", + "sec.changeUser"); + dse.setParameter(0,m_username); + throw dse; + + } // end testChangeOK + + /*-------------------------------------------------------------------------------- + * Implementations from interface Principal + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object another) + { + if (another==null) + return false; + if (another instanceof DynamoUser) + return (m_uid==((DynamoUser)another).getUID()); + return false; + + } // end equals + + public String toString() + { + return "user " + m_username; + + } // end toString + + public int hashCode() + { + return m_uid; + + } // end hashCode + + public String getName() + { + return m_username; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface ObjectProvider + *-------------------------------------------------------------------------------- + */ + + /** + * Retrieves an object from this ObjectProvider. + * + * @param namespace The namespace to interpret the name relative to. + * @param name The name of the object to be retrieved. + * @return The object reference specified. + */ + public Object getObject(String namespace, String name) + { + if (NAMESPACE.equals(namespace)) + { // handle user info namespace specially + if (ATTR_FULLNAME.equals(name)) + return m_upt.getUserFullName(this); + else if (ATTR_EMAIL_ADDRESS.equals(name)) + return m_email; + else if (ATTR_ID.equals(name)) + return new Integer(m_uid); + else if (ATTR_USERNAME.equals(name)) + return m_username; + else + throw new NoSuchObjectException(this.toString(),namespace,name); + + } // end if + + try + { // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + Object rc = null; + synchronized (m_properties_sync) + { // start by looking in the properties map + rc = m_properties.get(key); + if (rc==null) + { // no use - need to try the database + rc = m_ops.getProperty(m_uid,key); + if (rc!=null) + m_properties.put(key,rc); + + } // end if + + } // end synchronized block + + if (rc==null) + throw new NoSuchObjectException(this.toString(),namespace,name); + return rc; + + } // end try + catch (DatabaseException e) + { // translate into our NoSuchObjectException but retain the DatabaseException + throw new NoSuchObjectException(this.toString(),namespace,name,e); + + } // end catch + + } // end getObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface SecureObjectStore + *-------------------------------------------------------------------------------- + */ + + public Object setObject(DynamoUser caller, String namespace, String name, Object value) + throws DatabaseException, DynamoSecurityException + { + if (NAMESPACE.equals(namespace)) + { // can't set more data in restricted namespace + ObjectStoreException ose = new ObjectStoreException(UserObject.class,"DatabaseMessages", + "ose.setProperty"); + ose.setParameter(0,namespace); + ose.setParameter(1,name); + throw ose; + + } // end if + + testChangeOK(caller); + Object rc = null; + + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (m_properties_sync) + { // start by setting the database value + rc = m_ops.setProperty(m_uid,key,value); + + // and cache it, too + m_properties.put(key,value); + + } // end synchronized block + + m_post.postUpdate(new UserPropertyUpdateEvent(this,m_uid,namespace,name)); + return rc; + + } // end setObject + + public Object removeObject(DynamoUser caller, String namespace, String name) + throws DatabaseException, DynamoSecurityException + { + if (NAMESPACE.equals(namespace)) + { // can't set more data in restricted namespace + ObjectStoreException ose = new ObjectStoreException(UserObject.class,"DatabaseMessages", + "ose.removeProperty"); + ose.setParameter(0,namespace); + ose.setParameter(1,name); + throw ose; + + } // end if + + testChangeOK(caller); + Object rc = null; + // convert the namespace name to an ID here + PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name); + synchronized (m_properties_sync) + { // start by killing the database value + rc = m_ops.removeProperty(m_uid,key); + + // and remove the cached value, too + m_properties.remove(key); + + } // end synchronized block + + m_post.postUpdate(new UserPropertyUpdateEvent(this,m_uid,namespace,name)); + return rc; + + } // end removeObject + + public Collection getNamespaces() throws DatabaseException + { + // call through to the database to get the list of namespace IDs + int[] ids = m_ops.getPropertyNamespaceIDs(m_uid); + + ArrayList rc = new ArrayList(ids.length); + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.util.*; + +abstract class UserObjectOps extends OpsBase +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected UserObjectOps(DBConnectionPool pool) + { + super(pool); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + abstract Object getProperty(int uid, PropertyKey key) throws DatabaseException; + + abstract Object setProperty(int uid, PropertyKey key, Object value) throws DatabaseException; + + abstract Object removeProperty(int uid, PropertyKey key) throws DatabaseException; + + abstract int[] getPropertyNamespaceIDs(int uid) throws DatabaseException; + + abstract Map getAllProperties(int uid, int namespace) throws DatabaseException; + + abstract void setLocked(int uid, boolean locked) throws DatabaseException; + + abstract void setNoSpam(int uid, boolean locked) throws DatabaseException; + + abstract void setEMailAddress(int uid, String addr) throws DatabaseException; + + abstract void setLastAccessed(int uid, java.util.Date date) throws DatabaseException; + + abstract String[] getAuthenticationData(int uid, int nsid, String method, String source_data) + throws DatabaseException; + + abstract void putAuthenticationData(int uid, int nsid, String method, String source_data, String auth_data) + throws DatabaseException; + + abstract void clearAuthenticationData(int uid, int nsid, String method, String source_data) + throws DatabaseException; + +} // end class UserObjectOps diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps_mysql.java new file mode 100644 index 0000000..7abf77b --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps_mysql.java @@ -0,0 +1,635 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import java.util.*; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +class UserObjectOps_mysql extends UserObjectOps +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final String[] STRING_TEMPLATE = new String[0]; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DBUtilities m_utils; + private PropertySerializer m_psz; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + UserObjectOps_mysql(DBConnectionPool pool, DBUtilities utils) + { + super(pool); + m_utils = utils; + m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class)); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class UserObjectOps + *-------------------------------------------------------------------------------- + */ + + Object getProperty(int uid, PropertyKey key) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + String rc_str = null; + try + { // get a connection + conn = getConnection(); + + // look up the property + stmt = conn.prepareStatement("SELECT prop_value FROM userprop WHERE uid = ? AND nsid = ? " + + "AND prop_name = ?;"); + stmt.setInt(1,uid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + rs = stmt.executeQuery(); + if (!(rs.next())) + return null; // property not found + + rc_str = rs.getString(1); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(conn); + + } // end finally + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(rc_str); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end getProperty + + Object setProperty(int uid, PropertyKey key, Object value) throws DatabaseException + { + String serialized_value = m_psz.serializeProperty(value); + if (serialized_value==null) + { // serialization exception - throw it + DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages", + "property.serialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end if + + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES userprop WRITE;"); + + // look to see if the property value is already there + stmt = conn.prepareStatement("SELECT prop_value FROM userprop WHERE uid = ? AND nsid = ? " + + "AND prop_name = ?;"); + stmt.setInt(1,uid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + if (old_value!=null) + { // prepare the statement to update the existing record + stmt = conn.prepareStatement("UPDATE userprop SET prop_value = ? WHERE uid = ? " + + "AND nsid = ? AND prop_name = ?;"); + stmt.setString(1,serialized_value); + stmt.setInt(2,uid); + stmt.setInt(3,key.getNamespaceID()); + stmt.setString(4,key.getName()); + + } // end if + else + { // prepare the statement to insert a new record + stmt = conn.prepareStatement("INSERT INTO userprop (uid, nsid, prop_name, prop_value) " + + "VALUES (?, ?, ?, ?);"); + stmt.setInt(1,uid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + stmt.setString(4,serialized_value); + + } // end else + + stmt.executeUpdate(); // execute it! + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + if (old_value==null) + return null; // no previous value + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(old_value); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end setProperty + + Object removeProperty(int uid, PropertyKey key) throws DatabaseException + { + String old_value = null; + Connection conn = null; + PreparedStatement stmt = null; + Statement stmt2 = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // lock the table + stmt2 = conn.createStatement(); + stmt2.executeUpdate("LOCK TABLES userprop WRITE;"); + + // look to see if the property value is already there + stmt = conn.prepareStatement("SELECT prop_value FROM userprop WHERE uid = ? AND nsid = ? " + + "AND prop_name = ?;"); + stmt.setInt(1,uid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + rs = stmt.executeQuery(); + if (rs.next()) + old_value = rs.getString(1); + else + return null; // no need to remove anything + SQLUtils.shutdown(rs); + rs = null; + SQLUtils.shutdown(stmt); + + // delete the database row + stmt = conn.prepareStatement("DELETE FROM userprop WHERE uid = ? AND nsid = ? AND prop_name = ?;"); + stmt.setInt(1,uid); + stmt.setInt(2,key.getNamespaceID()); + stmt.setString(3,key.getName()); + stmt.executeUpdate(); + + } // end try + catch (SQLException e) + { // translate to a general DatabaseException + throw generalException(e); + + } // end catch + finally + { // shut everything down + MySQLUtils.unlockTables(conn); + SQLUtils.shutdown(rs); + SQLUtils.shutdown(stmt); + SQLUtils.shutdown(stmt2); + SQLUtils.shutdown(conn); + + } // end finally + + // Deserialize the property value. + Object rc = m_psz.deserializeProperty(old_value); + if (rc!=null) + return rc; + + // deserialization exception - throw it + DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages", + "property.deserialize"); + de.setParameter(0,key.getName()); + throw de; + + } // end removeProperty + + int[] getPropertyNamespaceIDs(int uid) throws DatabaseException + { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try + { // get a connection + conn = getConnection(); + + // execute the query! + stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM userprop WHERE uid = ?;"); + stmt.setInt(1,uid); + rs = stmt.executeQuery(); + + // read out a list of the namespace IDs + ArrayList tmp = new ArrayList(); + while (rs.next()) + tmp.add(new Integer(rs.getInt(1))); + + // create and return the array + int[] rc = new int[tmp.size()]; + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import com.silverwrist.dynamo.iface.DynamoUser; + +public interface UserPropertyTranslator +{ + public String getUserFullName(DynamoUser user); + +} // end interface UserPropertyTranslator diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslatorInstall.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslatorInstall.java new file mode 100644 index 0000000..d7bdd2d --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslatorInstall.java @@ -0,0 +1,24 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +public interface UserPropertyTranslatorInstall +{ + public void installUserPropertyTranslator(UserPropertyTranslator upt); + +} // end interface UserPropertyTranslatorInstall diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxy.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxy.java new file mode 100644 index 0000000..63136a9 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxy.java @@ -0,0 +1,260 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.util.*; +import com.silverwrist.dynamo.UserInfoNamespace; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +abstract class UserProxy implements DynamoUser, UserInfoNamespace, DynamicWrapper +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + protected int m_uid; + protected String m_username; + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + protected UserProxy(int uid) + { + m_uid = uid; + m_username = null; + + } // end constructor + + protected UserProxy(int uid, String username) + { + m_uid = uid; + m_username = username; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + protected abstract DynamoUser getRealUser(); + + /*-------------------------------------------------------------------------------- + * Implementations from interface Principal + *-------------------------------------------------------------------------------- + */ + + public boolean equals(Object another) + { + if (another==null) + return false; + if (another instanceof DynamoUser) + return (m_uid==((DynamoUser)another).getUID()); + return false; + + } // end equals + + public String toString() + { + if (m_username!=null) + return "user " + m_username; + return getRealUser().toString(); + + } // end toString + + public int hashCode() + { + return m_uid; + + } // end hashCode + + public String getName() + { + if (m_username!=null) + return m_username; + return getRealUser().getName(); + + } // end getName + + /*-------------------------------------------------------------------------------- + * Implementations from interface ObjectProvider + *-------------------------------------------------------------------------------- + */ + + /** + * Retrieves an object from this ObjectProvider. + * + * @param namespace The namespace to interpret the name relative to. + * @param name The name of the object to be retrieved. + * @return The object reference specified. + */ + public Object getObject(String namespace, String name) + { + return getRealUser().getObject(namespace,name); + + } // end getObject + + /*-------------------------------------------------------------------------------- + * Implementations from interface SecureObjectStore + *-------------------------------------------------------------------------------- + */ + + public Object setObject(DynamoUser caller, String namespace, String name, Object value) + throws DatabaseException, DynamoSecurityException + { + return getRealUser().setObject(caller,namespace,name,value); + + } // end setObject + + public Object removeObject(DynamoUser caller, String namespace, String name) + throws DatabaseException, DynamoSecurityException + { + return getRealUser().removeObject(caller,namespace,name); + + } // end removeObject + + public Collection getNamespaces() throws DatabaseException + { + return getRealUser().getNamespaces(); + + } // end getNamespaces + + public Collection getNamesForNamespace(String namespace) throws DatabaseException + { + return getRealUser().getNamesForNamespace(namespace); + + } // end getNamesForNamespace + + /*-------------------------------------------------------------------------------- + * Implementations from interface DynamoUser + *-------------------------------------------------------------------------------- + */ + + public int getUID() + { + return m_uid; + + } // end getUID + + public boolean isAnonymous() + { + return getRealUser().isAnonymous(); + + } // end isAnonymous + + public boolean isLocked() + { + return getRealUser().isLocked(); + + } // end isLocked + + public void setLocked(DynamoUser caller, boolean locked) throws DatabaseException, DynamoSecurityException + { + getRealUser().setLocked(caller,locked); + + } // end setLocked + + public boolean isNoSpam() + { + return getRealUser().isNoSpam(); + + } // end isNoSpam + + public void setNoSpam(DynamoUser caller, boolean nospam) throws DatabaseException, DynamoSecurityException + { + getRealUser().setNoSpam(caller,nospam); + + } // end setNoSpam + + public String getEMailAddress() + { + return getRealUser().getEMailAddress(); + + } // end getEMailAddress + + public boolean setEMailAddress(DynamoUser caller, String addr) + throws DatabaseException, DynamoSecurityException + { + return getRealUser().setEMailAddress(caller,addr); + + } // end setEMailAddress + + public boolean authenticate(String method_namespace, String method, String source_data, String auth_data) + throws DatabaseException, AuthenticationException + { + return getRealUser().authenticate(method_namespace,method,source_data,auth_data); + + } // end authenticate + + public void setAuthenticationData(DynamoUser caller, String method_namespace, String method, + String source_data, String auth_data) + throws DatabaseException, AuthenticationException, DynamoSecurityException + { + getRealUser().setAuthenticationData(caller,method_namespace,method,source_data,auth_data); + + } // end setAuthenticationData + + public void clearAuthenticationData(DynamoUser caller, String method_namespace, String method, + String source_data) throws DatabaseException, DynamoSecurityException + { + getRealUser().clearAuthenticationData(caller,method_namespace,method,source_data); + + } // end clearAuthenticationData + + public void clearAuthenticationData(DynamoUser caller, String method_namespace, String method) + throws DatabaseException, DynamoSecurityException + { + getRealUser().clearAuthenticationData(caller,method_namespace,method); + + } // end clearAuthenticationData + + public java.util.Date getCreationDate() + { + return getRealUser().getCreationDate(); + + } // end getCreationDate + + public java.util.Date getLastAccessDate() + { + return getRealUser().getLastAccessDate(); + + } // end getLastAccessDate + + public synchronized void setLastAccessDate(DynamoUser caller, java.util.Date date) + throws DatabaseException, DynamoSecurityException + { + getRealUser().setLastAccessDate(caller,date); + + } // end setLastAccessDate + + /*-------------------------------------------------------------------------------- + * Implementations from interface DynamicWrapper + *-------------------------------------------------------------------------------- + */ + + public Object unwrap() + { + return getRealUser(); + + } // end unwrap + +} // end class UserProxy diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxyManagement.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxyManagement.java new file mode 100644 index 0000000..7d5f97a --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxyManagement.java @@ -0,0 +1,32 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import com.silverwrist.dynamo.iface.*; + +public interface UserProxyManagement +{ + public DynamoUser getUserProxy(int uid); + + public DynamoUser getUserProxy(int uid, String username); + + public DynamoGroup getGroupProxy(int gid); + + public DynamoGroup getGroupProxy(int gid, String groupname); + +} // end interface UserProxyManagement diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/WrappedConnection.java b/src/dynamo-framework/com/silverwrist/dynamo/db/WrappedConnection.java new file mode 100644 index 0000000..d00f0ca --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/db/WrappedConnection.java @@ -0,0 +1,498 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.db; + +import java.sql.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +class WrappedConnection implements Connection +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DBConnectionPool m_datapool; + private Connection m_conn; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + WrappedConnection(DBConnectionPool datapool, Connection conn) + { + m_datapool = datapool; + m_conn = conn; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class Object + *-------------------------------------------------------------------------------- + */ + + protected void finalize() throws Throwable + { + if (m_conn!=null) + this.close(); + super.finalize(); + + } // end finalize + + /*-------------------------------------------------------------------------------- + * Implementations from interface Connection + *-------------------------------------------------------------------------------- + */ + + /** + * Creates a Statement object for sending + * SQL statements to the database. + * + * @return a new Statement object + * @exception SQLException if a database access error occurs + */ + public Statement createStatement() throws SQLException + { + return m_conn.createStatement(); + + } // end createStatement + + /** + * Creates a PreparedStatement object for sending + * parameterized SQL statements to the database. + * + * @param sql a SQL statement that may contain one or more '?' IN parameter placeholders + * @return a new PreparedStatement object containing the pre-compiled statement + * @exception SQLException if a database access error occurs + */ + public PreparedStatement prepareStatement(String sql) throws SQLException + { + return m_conn.prepareStatement(sql); + + } // end prepareStatement + + /** + * Creates a CallableStatement object for calling + * database stored procedures. + * + * @param sql a SQL statement that may contain one or more '?' parameter placeholders. + * Typically this statement is a JDBC function call escape string. + * @return a new CallableStatement object containing the pre-compiled SQL statement + * @exception SQLException if a database access error occurs + */ + public CallableStatement prepareCall(String sql) throws SQLException + { + return m_conn.prepareCall(sql); + + } // end prepareCall + + /** + * Converts the given SQL statement into the system's native SQL grammar. + * + * @param sql a SQL statement that may contain one or more '?' parameter placeholders + * @return the native form of this statement + * @exception SQLException if a database access error occurs + */ + public String nativeSQL(String sql) throws SQLException + { + return m_conn.nativeSQL(sql); + + } // end nativeSQL + + /** + * Sets this connection's auto-commit mode. + * + * @param autoCommit true enables auto-commit; false disables auto-commit. + * @exception SQLException if a database access error occurs + */ + public void setAutoCommit(boolean autoCommit) throws SQLException + { + m_conn.setAutoCommit(autoCommit); + + } // end setAutoCommit + + /** + * Gets the current auto-commit state. + * + * @return the current state of auto-commit mode + * @exception SQLException if a database access error occurs + * @see #setAutoCommit + */ + public boolean getAutoCommit() throws SQLException + { + return m_conn.getAutoCommit(); + + } // end getAutoCommit + + /** + * Makes all changes made since the previous + * commit/rollback permanent and releases any database locks + * currently held by the Connection. This method should be + * used only when auto-commit mode has been disabled. + * + * @exception SQLException if a database access error occurs + * @see #setAutoCommit + */ + public void commit() throws SQLException + { + m_conn.commit(); + + } // end commit + + /** + * Drops all changes made since the previous + * commit/rollback and releases any database locks currently held + * by this Connection. This method should be used only when auto- + * commit has been disabled. + * + * @exception SQLException if a database access error occurs + * @see #setAutoCommit + */ + public void rollback() throws SQLException + { + m_conn.rollback(); + + } // end rollback + + /** + * Releases a Connection's database and JDBC resources + * immediately instead of waiting for them to be automatically released. + * + * @exception SQLException if a database access error occurs + */ + public synchronized void close() throws SQLException + { + try + { // blow away the connection + if (!(m_conn.getAutoCommit())) + m_conn.rollback(); + m_datapool.releaseConnection(m_conn); + m_conn = null; + + } // end try + catch (DatabaseException e) + { // database exception becomes SQLException + SQLException sqle = new SQLException(e.getMessage()); + sqle.initCause(e); + throw sqle; + + } // end catch + + } // end close + + /** + * Tests to see if a Connection is closed. + * + * @return true if the connection is closed; false if it's still open + * @exception SQLException if a database access error occurs + */ + public boolean isClosed() throws SQLException + { + return (m_conn==null) ? true : m_conn.isClosed(); + + } // end isClosed + + /** + * Gets the metadata regarding this connection's database. + * + * @return a DatabaseMetaData object for this Connection + * @exception SQLException if a database access error occurs + */ + public DatabaseMetaData getMetaData() throws SQLException + { + return m_conn.getMetaData(); + + } // end getMetaData + + /** + * Puts this connection in read-only mode as a hint to enable + * database optimizations. + * + * @param readOnly true enables read-only mode; false disables read-only mode. + * @exception SQLException if a database access error occurs + */ + public void setReadOnly(boolean readOnly) + { // do nothing + } // end setReadOnly + + /** + * Tests to see if the connection is in read-only mode. + * + * @return true if connection is read-only and false otherwise + * @exception SQLException if a database access error occurs + */ + public boolean isReadOnly() + { + return false; + + } // end isReadOnly + + /** + * Sets a catalog name in order to select + * a subspace of this Connection's database in which to work. + * If the driver does not support catalogs, it will + * silently ignore this request. + * + * @exception SQLException if a database access error occurs + */ + public void setCatalog(String catalog) + { // do nothing + } // end setCatalog + + /** + * Returns the Connection's current catalog name. + * + * @return the current catalog name or null + * @exception SQLException if a database access error occurs + */ + public String getCatalog() throws SQLException + { + return m_conn.getCatalog(); + + } // end getCatalog + + /** + * Attempts to change the transaction + * isolation level to the one given. + * The constants defined in the interface Connection + * are the possible transaction isolation levels. + * + * @param level one of the TRANSACTION_* isolation values with the exception of TRANSACTION_NONE; + * some databases may not support other values + * @exception SQLException if a database access error occurs + * @see DatabaseMetaData#supportsTransactionIsolationLevel + */ + public void setTransactionIsolation(int level) + { // do nothing + } // end setTransactionIsolation + + /** + * Gets this Connection's current transaction isolation level. + * + * @return the current TRANSACTION_* mode value + * @exception SQLException if a database access error occurs + */ + public int getTransactionIsolation() throws SQLException + { + return m_conn.getTransactionIsolation(); + + } // end getTransactionIsolation + + /** + * Returns the first warning reported by calls on this Connection. + * + * @return the first SQLWarning or null + * @exception SQLException if a database access error occurs + */ + public SQLWarning getWarnings() throws SQLException + { + return m_conn.getWarnings(); + + } // end getWarnings + + /** + * Clears all warnings reported for this Connection object. + * After a call to this method, the method getWarnings + * returns null until a new warning is reported for this Connection. + * + * @exception SQLException if a database access error occurs + */ + public void clearWarnings() throws SQLException + { + m_conn.clearWarnings(); + + } // end clearWarnings + + /** + * Creates a Statement object that will generate + * ResultSet objects with the given type and concurrency. + * + * @param resultSetType a result set type; see ResultSet.TYPE_XXX + * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX + * @return a new Statement object + * @exception SQLException if a database access error occurs + * @since 1.2 + * @see What Is in the JDBC 2.0 API + */ + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException + { + return m_conn.createStatement(resultSetType,resultSetConcurrency); + + } // end createStatement + + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) + throws SQLException + { + return m_conn.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability); + + } // end createStatement + + /** + * Creates a PreparedStatement object that will generate + * ResultSet objects with the given type and concurrency. + * This method is the same as the prepareStatement method + * above, but it allows the default result set + * type and result set concurrency type to be overridden. + * + * @param resultSetType a result set type; see ResultSet.TYPE_XXX + * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX + * @return a new PreparedStatement object containing the pre-compiled SQL statement + * @exception SQLException if a database access error occurs + * @since 1.2 + * @see What Is in the JDBC 2.0 API + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException + { + return m_conn.prepareStatement(sql,resultSetType,resultSetConcurrency); + + } // end prepareStatement + + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException + { + return m_conn.prepareStatement(sql,resultSetType,resultSetConcurrency,resultSetHoldability); + + } // end prepareStatement + + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException + { + return m_conn.prepareStatement(sql,autoGeneratedKeys); + + } // end prepareStatement + + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException + { + return m_conn.prepareStatement(sql,columnIndexes); + + } // end prepareStatement + + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException + { + return m_conn.prepareStatement(sql,columnNames); + + } // end prepareStatement + + /** + * Creates a CallableStatement object that will generate + * ResultSet objects with the given type and concurrency. + * This method is the same as the prepareCall method + * above, but it allows the default result set + * type and result set concurrency type to be overridden. + * + * @param resultSetType a result set type; see ResultSet.TYPE_XXX + * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX + * @return a new CallableStatement object containing the pre-compiled SQL statement + * @exception SQLException if a database access error occurs + * @since 1.2 + * @see What Is in the JDBC 2.0 API + */ + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException + { + return m_conn.prepareCall(sql,resultSetType,resultSetConcurrency); + + } // end prepareCall + + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException + { + return m_conn.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability); + + } // end prepareCall + + /** + * Gets the type map object associated with this connection. + * Unless the application has added an entry to the type map, + * the map returned will be empty. + * + * @return the java.util.Map object associated with this Connection object + * @since 1.2 + * @see What Is in the JDBC 2.0 API + */ + public java.util.Map getTypeMap() throws SQLException + { + return m_conn.getTypeMap(); + + } // end getTypeMap + + /** + * Installs the given type map as the type map for + * this connection. The type map will be used for the + * custom mapping of SQL structured types and distinct types. + * + * @param the java.util.Map object to install + * as the replacement for this Connection + * object's default type map + * @since 1.2 + * @see What Is in the JDBC 2.0 API + */ + public void setTypeMap(java.util.Map map) throws SQLException + { + m_conn.setTypeMap(map); + + } // end setTypeMap + + public int getHoldability() throws SQLException + { + return m_conn.getHoldability(); + + } // end getHoldability + + public void setHoldability(int holdability) throws SQLException + { // do nothing + } // end setHoldability + + public Savepoint setSavepoint() throws SQLException + { + return m_conn.setSavepoint(); + + } // end setSavepont + + public Savepoint setSavepoint(String name) throws SQLException + { + return m_conn.setSavepoint(name); + + } // end setSavepoint + + public void rollback(Savepoint savepoint) throws SQLException + { + m_conn.rollback(savepoint); + + } // end rollback + + public void releaseSavepoint(Savepoint savepoint) throws SQLException + { + m_conn.releaseSavepoint(savepoint); + + } // end releaseSavepoint + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + Connection getRealConnection() + { + return m_conn; + + } // end getRealConnection + +} // end class WrappedConnection diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/BaseDialogField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/BaseDialogField.java new file mode 100644 index 0000000..270b0bc --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/BaseDialogField.java @@ -0,0 +1,229 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.dialog; + +import java.io.*; +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; + +public abstract class BaseDialogField implements DialogField +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private boolean m_reverse; // if true, field is on left, false = right + private String m_name; // field name (parameter name) + private String m_caption; // primary caption + private String m_caption2; // secondary caption + private boolean m_required; // is this field required? + private boolean m_default_enabled; // are we enabled by default? + private boolean m_enabled; // are we currently enabled? + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + protected BaseDialogField(boolean reverse, Element element) throws DialogException + { + m_reverse = reverse; + XMLLoader loader = XMLLoader.get(); + try + { // get the base class stuff + m_name = loader.getAttribute(element,"name"); + m_caption = loader.getAttribute(element,"caption"); + m_caption2 = element.getAttribute("caption2"); + m_required = loader.getAttributeBoolean(element,"required",false); + m_default_enabled = loader.getAttributeBoolean(element,"enabled",true); + + } // end try + catch (XMLLoadException e) + { // translate the exception and return it + throw new DialogException(e); + + } // end catch + + m_enabled = m_default_enabled; + + } // end constructor + + protected BaseDialogField(BaseDialogField other) + { + m_reverse = other.m_reverse; + m_name = other.m_name; + m_caption = other.m_caption; + m_caption2 = other.m_caption2; + m_required = other.m_required; + m_default_enabled = other.m_default_enabled; + m_enabled = m_default_enabled; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final void renderCaption(TextRenderControl control, Map render_params) + throws IOException, RenderingException + { + PrintWriter wr = control.getWriter(); + if (!m_enabled) + wr.write(""); + wr.write(StringUtils.encodeHTML(StringUtils.replaceAllVariables(m_caption,render_params))); + if (StringUtils.isNotEmpty(m_caption2)) + wr.write(" " + StringUtils.encodeHTML(StringUtils.replaceAllVariables(m_caption2,render_params))); + if (!m_reverse) + wr.write(":"); + if (!m_enabled) + wr.write(""); + if (m_required) + wr.write("*"); + + } // end renderCaption + + protected final String getCaption() + { + return m_caption; + + } // end getCaption + + protected final void setCaption2(String s) + { + m_caption2 = s; + + } // end setCaption2 + + protected boolean isNull(Object value) + { + return (value==null); + + } // end isNull + + /*-------------------------------------------------------------------------------- + * Abstract operations + *-------------------------------------------------------------------------------- + */ + + protected abstract void renderField(TextRenderControl control, Map render_params) + throws IOException, RenderingException; + + protected abstract void validateContents(Request r, Object data) throws ValidationException; + + /*-------------------------------------------------------------------------------- + * Implementations from interface NamedObject + *-------------------------------------------------------------------------------- + */ + + public String getName() + { + return m_name; + + } // end getName + + /*-------------------------------------------------------------------------------- + * Abstract methods from interface DialogItem + *-------------------------------------------------------------------------------- + */ + + public abstract Object clone(); + + /*-------------------------------------------------------------------------------- + * Implementations from interface DialogItem + *-------------------------------------------------------------------------------- + */ + + public void render(TextRenderControl control, Map render_params) throws IOException, RenderingException + { + PrintWriter wr = control.getWriter(); + wr.write("\n"); + if (m_reverse) + renderField(control,render_params); + else + renderCaption(control,render_params); + wr.write("\n"); + if (m_reverse) + renderCaption(control,render_params); + else + renderField(control,render_params); + wr.write("\n\n"); + + } // end render + + public boolean isEnabled() + { + return m_enabled; + + } // end isEnabled + + public void setEnabled(boolean flag) + { + m_enabled = flag; + + } // end setEnabled + + /*-------------------------------------------------------------------------------- + * Abstract methods from interface DialogField + *-------------------------------------------------------------------------------- + */ + + public abstract Object getValue(); + + public abstract boolean containsValue(); + + public abstract void setValue(Object obj); + + public abstract void setValueFrom(Request r); + + public abstract void reset(); + + /*-------------------------------------------------------------------------------- + * Implementations from interface DialogField + *-------------------------------------------------------------------------------- + */ + + public void validate(Request r) throws ValidationException + { + Object val = getValue(); + if (m_required && m_enabled && isNull(val)) + { // null field value - we need to bail out + ValidationException ve = new ValidationException(BaseDialogField.class,"DialogMessages", + "required.field"); + ve.setParameter(0,m_caption); + throw ve; + + } // end if + + if (m_enabled) + validateContents(r,val); + + } // end validate + + public int getFlags() + { + return (m_required ? FLAG_REQUIRED : 0); + + } // end getFlags + +} // end class BaseDialogField diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/ButtonCaptions.properties b/src/dynamo-framework/com/silverwrist/dynamo/dialog/ButtonCaptions.properties new file mode 100644 index 0000000..bcbb1c0 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/ButtonCaptions.properties @@ -0,0 +1,21 @@ +# The contents of this file are subject to the Mozilla Public License Version 1.1 +# (the "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at . +# +# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT +# WARRANTY OF ANY KIND, either express or implied. See the License for the specific +# language governing rights and limitations under the License. +# +# The Original Code is the Venice Web Communities System. +# +# The Initial Developer of the Original Code is Eric J. Bowersox , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# --------------------------------------------------------------------------------- +# This file has been localized for the en_US locale +cancel=Cancel +login=Log In +ok=OK +reminder=Reminder diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/CheckBoxField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CheckBoxField.java new file mode 100644 index 0000000..776871e --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CheckBoxField.java @@ -0,0 +1,187 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.dialog; + +import java.io.*; +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +class CheckBoxField extends BaseDialogField +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final String YES = "Y"; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_value; + private boolean m_default_checked; + private boolean m_checked; + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + CheckBoxField(Element elt) throws DialogException + { + super(true,elt); + XMLLoader loader = XMLLoader.get(); + try + { // get the checkbox value + m_value = loader.getAttribute(elt,"value",YES); + m_default_checked = loader.getAttributeBoolean(elt,"checked",false); + + } // end try + catch (XMLLoadException e) + { // translate into DialogException + throw new DialogException(e); + + } // end catch + + m_checked = m_default_checked; + + } // end constructor + + protected CheckBoxField(CheckBoxField other) + { + super(other); + m_value = other.m_value; + m_default_checked = other.m_default_checked; + m_checked = m_default_checked; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class BaseDialogField + *-------------------------------------------------------------------------------- + */ + + protected boolean isNull(Object value) + { + return false; + + } // end isNull + + public int getFlags() + { + return 0; + + } // end getFlags + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class BaseDialogField + *-------------------------------------------------------------------------------- + */ + + protected void renderField(TextRenderControl control, Map render_params) + throws IOException, RenderingException + { + PrintWriter wr = control.getWriter(); + wr.write(""); + + } // end renderField + + protected void validateContents(Request r, Object data) throws ValidationException + { // do nothing + } // end validateContents + + public Object clone() + { + return new CheckBoxField(this); + + } // end clone + + public Object getValue() + { + return Boolean.valueOf(m_checked); + + } // end getValue + + public boolean containsValue() + { + return true; + + } // end containsValue + + public void setValue(Object obj) + { + if (obj==null) + m_checked = m_default_checked; + else if (obj instanceof Boolean) + m_checked = ((Boolean)obj).booleanValue(); + else if (obj instanceof Number) + m_checked = (((Number)obj).intValue()!=0); + else + { // look at the string equivalent + String s = obj.toString(); + if (StringUtils.isBooleanTrue(s)) + m_checked = true; + else if (StringUtils.isBooleanFalse(s)) + m_checked = false; + + } // end else + + } // end setValue + + public void setValueFrom(Request r) + { + RequestHelper rh = new RequestHelper(r); + String[] vals = rh.getStringParameterValues(getName()); + if (vals!=null) + { // if no values are set, we're definitely NOT checked + for (int i=0; i. + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.dialog; + +import java.io.*; +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.except.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.util.*; + +abstract class CommonTextField extends BaseDialogField +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final int MINSIZE = 2; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String m_tagname; + private String m_value = null; + private int m_size; + private int m_maxlength; + private int m_real_maxlength; + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + protected CommonTextField(String tagname, Element elt) throws DialogException + { + super(false,elt); + m_tagname = tagname; + XMLLoader loader = XMLLoader.get(); + try + { // load the "size" attributes for the text field + int my_size = loader.getAttributeInt(elt,"size"); + DOMElementHelper h = new DOMElementHelper(elt); + if (h.hasAttribute("maxlength")) + { // get the maxlength and figure it in... + m_real_maxlength = loader.getAttributeInt(elt,"maxlength"); + m_maxlength = Math.max(m_real_maxlength,MINSIZE); + m_size = Math.max(my_size,MINSIZE); + + } // end if + else + { // "size" is all we got - maxlength is equal to it + m_real_maxlength = my_size; + m_maxlength = m_size = Math.max(my_size,MINSIZE); + + } // end else + + } // end try + catch (XMLLoadException e) + { // translate exception here + throw new DialogException(e); + + } // end catch + + } // end constructor + + protected CommonTextField(String tagname, int width, Element elt) throws DialogException + { + super(false,elt); + m_tagname = tagname; + m_real_maxlength = width; + m_maxlength = m_size = Math.max(width,MINSIZE); + + } // end constructor + + protected CommonTextField(CommonTextField other) + { + super(other); + m_tagname = other.m_tagname; + m_size = other.m_size; + m_maxlength = other.m_maxlength; + m_real_maxlength = other.m_real_maxlength; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class BaseDialogField + *-------------------------------------------------------------------------------- + */ + + protected boolean isNull(Object value) + { + return StringUtils.isEmpty((String)value); + + } // end isNull + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class BaseDialogField + *-------------------------------------------------------------------------------- + */ + + protected void renderField(TextRenderControl control, Map render_params) + throws IOException, RenderingException + { + PrintWriter wr = control.getWriter(); + wr.write(""); + + } // end renderField + + protected void validateContents(Request r, Object data) throws ValidationException + { + if ((data!=null) && (data.toString().length()>m_real_maxlength)) + { // this value is too long + ValidationException ve = new ValidationException(CommonTextField.class,"DialogMessages","text.tooLong"); + ve.setParameter(0,getCaption()); + ve.setParameter(1,String.valueOf(m_real_maxlength)); + throw ve; + + } // end if + + } // end validateContents + + public Object getValue() + { + return m_value; + + } // end getValue + + public boolean containsValue() + { + return StringUtils.isNotEmpty(m_value); + + } // end containsValue + + public void setValue(Object obj) + { + if (obj==null) + m_value = null; + else + m_value = obj.toString(); + if ((m_value!=null) && StringUtils.isEmpty(m_value)) + m_value = null; + + } // end setValue + + public void setValueFrom(Request r) + { + RequestHelper rh = new RequestHelper(r); + m_value = rh.getParameterString(getName()); + if ((m_value!=null) && StringUtils.isEmpty(m_value)) + m_value = null; + + } // end setValueFrom + + public void reset() + { + m_value = null; + + } // end reset + +} // end class CommonTextField diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/CountryListField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CountryListField.java new file mode 100644 index 0000000..a892fd3 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CountryListField.java @@ -0,0 +1,123 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.dialog; + +import java.util.*; +import org.w3c.dom.Element; +import com.silverwrist.util.*; +import com.silverwrist.dynamo.except.DialogException; + +class CountryListField extends PickListField +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Country UNKNOWN_COUNTRY = International.get().getCountryForCode("XX"); + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + CountryListField(Element elt) throws DialogException + { + super(elt); + + } // end constructor + + protected CountryListField(CountryListField other) + { + super(other); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class BaseDialogField + *-------------------------------------------------------------------------------- + */ + + public Object clone() + { + return new CountryListField(this); + + } // end clone + + /*-------------------------------------------------------------------------------- + * Overrides from class BaseDialogField + *-------------------------------------------------------------------------------- + */ + + protected boolean isNull(Object value) + { + return ((value==null) || UNKNOWN_COUNTRY.equals(value)); + + } // end isNull + + /*-------------------------------------------------------------------------------- + * Abstract implementations from class PickListField + *-------------------------------------------------------------------------------- + */ + + protected Iterator getChoices() + { + return International.get().getCountryList().iterator(); + + } // end getChoices + + protected String getChoiceName(Object choice) + { + return ((Country)choice).getCode(); + + } // end getChoiceName + + protected String getChoiceDisplay(Object choice) + { + return ((Country)choice).getName(); + + } // end getChoiceDisplay + + protected Object getChoiceForName(String name) + { + return International.get().getCountryForCode(name); + + } // end getChoiceForName + + protected boolean isValidChoice(Object choice) + { + if (!(choice instanceof Country)) + return false; + Country x = International.get().getCountryForCode(((Country)choice).getCode()); + return x.equals(choice); + + } // end isValidChoice + + /*-------------------------------------------------------------------------------- + * Overrides from class PickListField + *-------------------------------------------------------------------------------- + */ + + public boolean containsValue() + { + Object v = getValue(); + return ((v!=null) && !UNKNOWN_COUNTRY.equals(v)); + + } // end containsValue + +} // end class CountryListField diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/DefaultDialogLAF.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DefaultDialogLAF.java new file mode 100644 index 0000000..b32947a --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DefaultDialogLAF.java @@ -0,0 +1,85 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.dialog; + +import java.util.*; +import com.silverwrist.dynamo.iface.*; + +class DefaultDialogLAF implements DialogPLAF +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private ResourceBundle m_captions; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + DefaultDialogLAF() + { + m_captions = ResourceBundle.getBundle("com.silverwrist.dynamo.dialog.ButtonCaptions",Locale.getDefault()); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface DialogPLAF + *-------------------------------------------------------------------------------- + */ + + public Object getButtonRendering(String button_name) + { + String caption; + try + { // get the default caption + caption = m_captions.getString(button_name); + + } // end try + catch (MissingResourceException e) + { // default to just using the button name + caption = button_name; + + } // end catch + + StringBuffer buf = new StringBuffer(""); + return buf.toString(); + + } // end getButtonRendering + + public boolean isButtonClicked(Request r, String button_name) + { + return r.getParameters().containsKey(button_name); + + } // end isButtonClicked + + public Object getContentHeader(String title, String subtitle) + { + StringBuffer buf = new StringBuffer(""); + buf.append(title).append("\n"); + if (subtitle!=null) + buf.append("  ").append(subtitle).append("\n"); + buf.append("


\n"); + return buf.toString(); + + } // end getContentHeader + +} // end class DefaultDialogLAF diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java new file mode 100644 index 0000000..0a70ec2 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java @@ -0,0 +1,643 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.dynamo.dialog; + +import java.io.*; +import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.util.xml.*; +import com.silverwrist.dynamo.iface.*; +import com.silverwrist.dynamo.except.*; + +class DialogImpl implements Dialog +{ + /*-------------------------------------------------------------------------------- + * Internal class to "peel off" certain dialog items that are tags + *-------------------------------------------------------------------------------- + */ + + private class InternalFilter implements DialogItemFactory + { + /*==================================================================== + * Attributes + *==================================================================== + */ + + private DialogItemFactory m_inner; + private HashMap m_rp = new HashMap(); + + /*==================================================================== + * Constructor + *==================================================================== + */ + + InternalFilter(DialogItemFactory inner) + { + m_inner = inner; + + } // end constructor + + /*==================================================================== + * Implementations from interface DialogItemFactory + *==================================================================== + */ + + public DialogItem createDialogItem(Element elt, DialogPLAF plaf) throws DialogException + { + try + { // strip out certain items we need from the element stream + XMLLoader loader = XMLLoader.get(); + String tagname = elt.getTagName(); + if (tagname.equals("title")) + { // get title + m_default_title = loader.getText(elt); + if (m_default_title!=null) + m_default_title = m_default_title.trim(); + + } // end if + else if (tagname.equals("subtitle")) + { // get subtitle (not required) + DOMElementHelper h = new DOMElementHelper(elt); + m_default_subtitle = h.getElementText(); + if (m_default_subtitle!=null) + m_default_subtitle = m_default_subtitle.trim(); + + } // end else if + else if (tagname.equals("action")) + { // get action and action type + m_action = loader.getText(elt); + if (m_action!=null) + m_action = m_action.trim(); + m_action_type = loader.getAttribute(elt,"type","SERVLET"); + + } // end else if + else if (tagname.equals("render-param")) + { // get a rendering parameter + String name = loader.getAttribute(elt,"name"); + DOMElementHelper h = new DOMElementHelper(elt); + String value = h.getElementText(); + if (value!=null) + value = value.trim(); + else + value = ""; + m_rp.put(name,value); + + } // end else if + else if (tagname.equals("instructions")) + { // get instructions (not required) + DOMElementHelper h = new DOMElementHelper(elt); + m_default_instructions = h.getElementText(); + if (m_default_instructions!=null) + m_default_instructions = m_default_instructions.trim(); + + } // end else if + else // go create a dialog item + return m_inner.createDialogItem(elt,plaf); + + } // end try + catch (XMLLoadException e) + { // translate XML Load exception to dialog exception + throw new DialogException(e); + + } // end catch + + return null; + + } // end createDialogItem + + /*==================================================================== + * External operations + *==================================================================== + */ + + Map renderParams() + { + if (m_rp.isEmpty()) + return Collections.EMPTY_MAP; + else + return Collections.unmodifiableMap(m_rp); + + } // end renderParams + + } // end class InternalFilter + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private DialogPLAF m_plaf; + private String m_name; + private String m_default_button = null; + private String m_default_title = null; + private String m_default_subtitle = null; + private String m_action = null; + private String m_action_type = null; + private String m_default_instructions = null; + private boolean m_any_required; + private boolean m_need_multipart; + private List m_field_order; + private Map m_field_map; + private List m_button_order; + private Map m_button_map; + private List m_hidden_order; + private Map m_hidden_map; + private String m_title = null; + private String m_subtitle = null; + private String m_instructions = null; + private String m_error_message = null; + private Map m_default_render_params; + private HashMap m_render_params; + + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + DialogImpl(Element dialog_element, DialogItemFactory item_factory, DialogPLAF plaf) throws DialogException + { + // Copy the look-and-feel object reference. + m_plaf = plaf; + + // Get the basic stuff from the root tag itself. + XMLLoader loader = XMLLoader.get(); + try + { // get the dialog name + m_name = loader.getAttribute(dialog_element,"name"); + m_default_button = dialog_element.getAttribute("defaultbutton"); + + } // end try + catch (XMLLoadException e) + { // translate to DialogException + throw new DialogException(e); + + } // end catch + + // Load the fields. + ArrayList field_order = new ArrayList(); + HashMap field_map = new HashMap(); + ArrayList button_order = new ArrayList(); + HashMap button_map = new HashMap(); + ArrayList hidden_order = new ArrayList(); + HashMap hidden_map = new HashMap(); + int global_flags = 0; + InternalFilter factory = new InternalFilter(item_factory); + NodeList nl = dialog_element.getChildNodes(); + for (int i=0; i