Massive Argeo APIs refactoring
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 5 Jan 2022 11:36:42 +0000 (12:36 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 5 Jan 2022 11:36:42 +0000 (12:36 +0100)
254 files changed:
org.argeo.api/bnd.bnd
org.argeo.api/src/org/apache/commons/logging/Log.java [deleted file]
org.argeo.api/src/org/apache/commons/logging/LogFactory.java [deleted file]
org.argeo.api/src/org/argeo/api/ArgeoLogListener.java [deleted file]
org.argeo.api/src/org/argeo/api/ArgeoLogger.java [deleted file]
org.argeo.api/src/org/argeo/api/DataAdminLoginModule.java [deleted file]
org.argeo.api/src/org/argeo/api/NodeConstants.java [deleted file]
org.argeo.api/src/org/argeo/api/NodeDeployment.java [deleted file]
org.argeo.api/src/org/argeo/api/NodeInstance.java [deleted file]
org.argeo.api/src/org/argeo/api/NodeOID.java [deleted file]
org.argeo.api/src/org/argeo/api/NodeState.java [deleted file]
org.argeo.api/src/org/argeo/api/cms/AnonymousPrincipal.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/cms/CmsAuth.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/cms/CmsConstants.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/cms/CmsData.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/cms/CmsDeployment.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/cms/CmsLog.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/cms/CmsState.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/cms/DataAdminPrincipal.java [new file with mode: 0644]
org.argeo.api/src/org/argeo/api/package-info.java [deleted file]
org.argeo.api/src/org/argeo/api/security/AnonymousPrincipal.java [deleted file]
org.argeo.api/src/org/argeo/api/security/CryptoKeyring.java [deleted file]
org.argeo.api/src/org/argeo/api/security/DataAdminPrincipal.java [deleted file]
org.argeo.api/src/org/argeo/api/security/Keyring.java [deleted file]
org.argeo.api/src/org/argeo/api/security/NodeSecurityUtils.java [deleted file]
org.argeo.api/src/org/argeo/api/security/PBEKeySpecCallback.java [deleted file]
org.argeo.api/src/org/argeo/api/security/package-info.java [deleted file]
org.argeo.api/src/org/argeo/api/tabular/ArrayTabularRow.java [deleted file]
org.argeo.api/src/org/argeo/api/tabular/TabularColumn.java [deleted file]
org.argeo.api/src/org/argeo/api/tabular/TabularContent.java [deleted file]
org.argeo.api/src/org/argeo/api/tabular/TabularRow.java [deleted file]
org.argeo.api/src/org/argeo/api/tabular/TabularRowIterator.java [deleted file]
org.argeo.api/src/org/argeo/api/tabular/TabularWriter.java [deleted file]
org.argeo.api/src/org/argeo/api/tabular/package-info.java [deleted file]
org.argeo.cms.e4/src/org/argeo/cms/e4/addons/AuthAddon.java
org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java
org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java
org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java
org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java
org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java
org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java
org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java
org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java
org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java
org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsFsProvider.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrDeployment.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeRepositoryFactory.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryServiceFactory.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java [new file with mode: 0644]
org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java [new file with mode: 0644]
org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java [new file with mode: 0644]
org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java [new file with mode: 0644]
org.argeo.cms.jcr/src/org/argeo/cms/tabular/CsvTabularWriter.java [deleted file]
org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularRowIterator.java [deleted file]
org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularWriter.java [deleted file]
org.argeo.cms.jcr/src/org/argeo/cms/tabular/package-info.java [deleted file]
org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java
org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java
org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java
org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java
org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java
org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java
org.argeo.cms.jcr/src/org/argeo/jcr/unit/AbstractJcrTestCase.java
org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java
org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java
org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java
org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java
org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java
org.argeo.cms.servlet/bnd.bnd
org.argeo.cms.servlet/src/org/argeo/cms/servlet/CmsServletContext.java
org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/HttpUtils.java
org.argeo.cms.swt/src/org/argeo/cms/swt/auth/CmsLogin.java
org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java
org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsFeedback.java
org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/LightweightDialog.java
org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java
org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/UserLP.java
org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java
org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java
org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java
org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/AdvancedFsBrowser.java
org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsBrowser.java
org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsTreeBrowser.java
org.argeo.cms.tp/bnd.bnd
org.argeo.cms.tp/src/org/apache/commons/logging/Log.java [new file with mode: 0644]
org.argeo.cms.tp/src/org/apache/commons/logging/LogFactory.java [new file with mode: 0644]
org.argeo.cms.tp/src/org/slf4j/impl/ArgeoLogger.java
org.argeo.cms.tp/src/org/slf4j/impl/StaticLoggerBinder.java
org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiConstants.java [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java
org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormUtils.java
org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FileDrop.java
org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java
org.argeo.cms.ui/src/org/argeo/cms/ui/internal/Activator.java
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java
org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsLink.java
org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java
org.argeo.cms.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java
org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java
org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/EditableImage.java
org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/StyledControl.java
org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java
org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java
org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/LocaleUtils.java
org.argeo.cms/src/org/argeo/cms/auth/AnonymousLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java
org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java
org.argeo.cms/src/org/argeo/cms/auth/DataAdminLoginModule.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/auth/IdentLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/KeyringLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/RemoteSessionLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/SingleUserLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java
org.argeo.cms/src/org/argeo/cms/auth/ident/IdentClient.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/auth/ident/OpenSslDecryptor.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/auth/ident/package-info.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java
org.argeo.cms/src/org/argeo/cms/internal/auth/CmsUserManagerImpl.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDataImpl.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeploymentImpl.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsInstance.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsShutdown.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsStateImpl.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeLogger.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas-ipa.cfg
org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg
org.argeo.cms/src/org/argeo/cms/security/AbstractKeyring.java
org.argeo.cms/src/org/argeo/cms/security/CryptoKeyring.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/security/Keyring.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/security/NodeSecurityUtils.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/security/PBEKeySpecCallback.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/tabular/ArrayTabularRow.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/tabular/TabularColumn.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/tabular/TabularContent.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/tabular/TabularRow.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/tabular/TabularRowIterator.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/tabular/TabularWriter.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/tabular/package-info.java [new file with mode: 0644]
org.argeo.init/bnd.bnd
org.argeo.util/src/org/argeo/ident/IdentClient.java [deleted file]
org.argeo.util/src/org/argeo/ident/OpenSslDecryptor.java [deleted file]
org.argeo.util/src/org/argeo/ident/package-info.java [deleted file]
org.argeo.util/src/org/argeo/naming/AttributesDictionary.java [deleted file]
org.argeo.util/src/org/argeo/naming/AuthPassword.java [deleted file]
org.argeo.util/src/org/argeo/naming/Distinguished.java [deleted file]
org.argeo.util/src/org/argeo/naming/DnsBrowser.java [deleted file]
org.argeo.util/src/org/argeo/naming/LdapAttrs.csv [deleted file]
org.argeo.util/src/org/argeo/naming/LdapAttrs.java [deleted file]
org.argeo.util/src/org/argeo/naming/LdapObjs.csv [deleted file]
org.argeo.util/src/org/argeo/naming/LdapObjs.java [deleted file]
org.argeo.util/src/org/argeo/naming/LdifParser.java [deleted file]
org.argeo.util/src/org/argeo/naming/LdifWriter.java [deleted file]
org.argeo.util/src/org/argeo/naming/NamingUtils.java [deleted file]
org.argeo.util/src/org/argeo/naming/SharedSecret.java [deleted file]
org.argeo.util/src/org/argeo/naming/SpecifiedName.java [deleted file]
org.argeo.util/src/org/argeo/naming/SrvRecord.java [deleted file]
org.argeo.util/src/org/argeo/naming/package-info.java [deleted file]
org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java
org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java
org.argeo.util/src/org/argeo/osgi/useradmin/IpaUtils.java
org.argeo.util/src/org/argeo/osgi/useradmin/LdapConnection.java
org.argeo.util/src/org/argeo/osgi/useradmin/LdapUserAdmin.java
org.argeo.util/src/org/argeo/osgi/useradmin/LdifAuthorization.java
org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java
org.argeo.util/src/org/argeo/osgi/useradmin/LdifUserAdmin.java
org.argeo.util/src/org/argeo/osgi/useradmin/OsUserDirectory.java
org.argeo.util/src/org/argeo/osgi/useradmin/TokenUtils.java
org.argeo.util/src/org/argeo/osgi/useradmin/UserAdminConf.java
org.argeo.util/src/org/argeo/util/naming/AttributesDictionary.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/AuthPassword.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/Distinguished.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/DnsBrowser.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/LdapAttrs.csv [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/LdapAttrs.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/LdapObjs.csv [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/LdapObjs.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/LdifParser.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/LdifWriter.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/NamingUtils.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/NodeOID.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/SharedSecret.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/SpecifiedName.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/SrvRecord.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/naming/package-info.java [new file with mode: 0644]
rap/org.argeo.cms.e4.rap/bnd.bnd
rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/SimpleRapE4App.java
rap/org.argeo.cms.ui.rap/bnd.bnd
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/AppUi.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptApp.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptAppActivator.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptUi.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/AbstractCmsEntryPoint.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebApp.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleApp.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleErgonomics.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/WebThemeUtils.java
rcp/org.argeo.cms.e4.rcp/bnd.bnd
rcp/org.argeo.cms.e4.rcp/src/org/argeo/cms/e4/rcp/CmsE4Application.java
rcp/org.argeo.cms.ui.rcp/bnd.bnd
rcp/org.argeo.cms.ui.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java

index 0dfe096633c39b785a2a8dff5db6e05134ee0c3b..a8a1e4f6a53fda3c7c5995a3043163d16832d9af 100644 (file)
@@ -1,5 +1,4 @@
 Import-Package: javax.naming.*,\
 javax.security.*
 
-Export-Package: org.argeo.api.*,\
-org.apache.commons.logging;version=1.2.666
\ No newline at end of file
+Export-Package: org.argeo.api.*
\ No newline at end of file
diff --git a/org.argeo.api/src/org/apache/commons/logging/Log.java b/org.argeo.api/src/org/apache/commons/logging/Log.java
deleted file mode 100644 (file)
index 4c4f8b4..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-package org.apache.commons.logging;
-
-import java.lang.System.Logger;
-import java.lang.System.Logger.Level;
-import java.util.Objects;
-
-/** A pseudo implementation of Apache Commons Logging. */
-public interface Log {
-       Logger getLogger();
-
-       default boolean isDebugEnabled() {
-               return getLogger().isLoggable(Level.DEBUG);
-       }
-
-       default boolean isErrorEnabled() {
-               return getLogger().isLoggable(Level.ERROR);
-       }
-
-       default boolean isInfoEnabled() {
-               return getLogger().isLoggable(Level.INFO);
-       }
-
-       default boolean isTraceEnabled() {
-               return getLogger().isLoggable(Level.TRACE);
-       }
-
-       default boolean isWarnEnabled() {
-               return getLogger().isLoggable(Level.WARNING);
-       }
-
-       /*
-        * TRACE
-        */
-
-       default void trace(String message) {
-               getLogger().log(Level.TRACE, message);
-       }
-
-       default void trace(Object message) {
-               getLogger().log(Level.TRACE, Objects.requireNonNull(message));
-       }
-
-       default void trace(String message, Throwable t) {
-               getLogger().log(Level.TRACE, message, t);
-       }
-
-       default void trace(Object message, Throwable t) {
-               trace(Objects.requireNonNull(message).toString(), t);
-       }
-
-       default void trace(String format, Object... arguments) {
-               getLogger().log(Level.TRACE, format, arguments);
-       }
-
-       /*
-        * DEBUG
-        */
-
-       default void debug(String message) {
-               getLogger().log(Level.DEBUG, message);
-       }
-
-       default void debug(Object message) {
-               getLogger().log(Level.DEBUG, message);
-       }
-
-       default void debug(String message, Throwable t) {
-               getLogger().log(Level.DEBUG, message, t);
-       }
-
-       default void debug(Object message, Throwable t) {
-               debug(Objects.requireNonNull(message).toString(), t);
-       }
-
-       default void debug(String format, Object... arguments) {
-               getLogger().log(Level.DEBUG, format, arguments);
-       }
-
-       /*
-        * INFO
-        */
-
-       default void info(String message) {
-               getLogger().log(Level.INFO, message);
-       }
-
-       default void info(Object message) {
-               getLogger().log(Level.INFO, message);
-       }
-
-       default void info(String message, Throwable t) {
-               getLogger().log(Level.INFO, message, t);
-       }
-
-       default void info(Object message, Throwable t) {
-               info(Objects.requireNonNull(message).toString(), t);
-       }
-
-       default void info(String format, Object... arguments) {
-               getLogger().log(Level.INFO, format, arguments);
-       }
-
-       /*
-        * WARN
-        */
-
-       default void warn(String message) {
-               getLogger().log(Level.WARNING, message);
-       }
-
-       default void warn(Object message) {
-               getLogger().log(Level.WARNING, message);
-       }
-
-       default void warn(String message, Throwable t) {
-               getLogger().log(Level.WARNING, message, t);
-       }
-
-       default void warn(Object message, Throwable t) {
-               warn(Objects.requireNonNull(message).toString(), t);
-       }
-
-       default void warn(String format, Object... arguments) {
-               getLogger().log(Level.WARNING, format, arguments);
-       }
-
-       /*
-        * ERROR
-        */
-
-       default void error(String message) {
-               getLogger().log(Level.ERROR, message);
-       }
-
-       default void error(Object message) {
-               getLogger().log(Level.ERROR, message);
-       }
-
-       default void error(String message, Throwable t) {
-               getLogger().log(Level.ERROR, message, t);
-       }
-
-       default void error(Object message, Throwable t) {
-               error(Objects.requireNonNull(message).toString(), t);
-       }
-
-       default void error(String format, Object... arguments) {
-               getLogger().log(Level.ERROR, format, arguments);
-       }
-
-}
diff --git a/org.argeo.api/src/org/apache/commons/logging/LogFactory.java b/org.argeo.api/src/org/apache/commons/logging/LogFactory.java
deleted file mode 100644 (file)
index e95b792..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.apache.commons.logging;
-
-import java.lang.System.Logger;
-import java.util.Objects;
-
-/** A pseudo implementation of Apache Commons Logging. */
-public abstract class LogFactory {
-       public static Log getLog(Class<?> clss) {
-               return getLog(Objects.requireNonNull(clss).getName());
-       }
-
-       public static Log getLog(String name) {
-               Logger logger = System.getLogger(Objects.requireNonNull(name));
-               return new LoggerWrapper(logger);
-       }
-
-       static class LoggerWrapper implements Log {
-               private final Logger logger;
-
-               LoggerWrapper(Logger logger) {
-                       super();
-                       this.logger = logger;
-               }
-
-               @Override
-               public Logger getLogger() {
-                       return logger;
-               }
-
-       }
-}
diff --git a/org.argeo.api/src/org/argeo/api/ArgeoLogListener.java b/org.argeo.api/src/org/argeo/api/ArgeoLogListener.java
deleted file mode 100644 (file)
index 51861fd..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.argeo.api;
-
-/** Framework agnostic interface for log notifications */
-public interface ArgeoLogListener {
-       /**
-        * Appends a log
-        * 
-        * @param username
-        *            authentified user, null for anonymous
-        * @param level
-        *            INFO, DEBUG, WARN, etc. (logging framework specific)
-        * @param category
-        *            hierarchy (logging framework specific)
-        * @param thread
-        *            name of the thread which logged this message
-        * @param msg
-        *            any object as long as its toString() method returns the
-        *            message
-        * @param exception
-        *            exception in log4j ThrowableStrRep format
-        */
-       public void appendLog(String username, Long timestamp, String level,
-                       String category, String thread, Object msg, String[] exception);
-}
diff --git a/org.argeo.api/src/org/argeo/api/ArgeoLogger.java b/org.argeo.api/src/org/argeo/api/ArgeoLogger.java
deleted file mode 100644 (file)
index dbcd7d7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.argeo.api;
-
-/**
- * Logging framework agnostic identifying a logging service, to which one can
- * register
- */
-public interface ArgeoLogger {
-       /**
-        * Register for events by threads with the same authentication (or all
-        * threads if admin)
-        */
-       public void register(ArgeoLogListener listener,
-                       Integer numberOfPreviousEvents);
-
-       /**
-        * For admin use only: register for all users
-        * 
-        * @param listener
-        *            the log listener
-        * @param numberOfPreviousEvents
-        *            the number of previous events to notify
-        * @param everything
-        *            if true even anonymous is logged
-        */
-       public void registerForAll(ArgeoLogListener listener,
-                       Integer numberOfPreviousEvents, boolean everything);
-
-       public void unregister(ArgeoLogListener listener);
-
-       public void unregisterForAll(ArgeoLogListener listener);
-}
diff --git a/org.argeo.api/src/org/argeo/api/DataAdminLoginModule.java b/org.argeo.api/src/org/argeo/api/DataAdminLoginModule.java
deleted file mode 100644 (file)
index 295196a..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.argeo.api;
-
-import java.util.Map;
-
-import javax.security.auth.AuthPermission;
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-
-import org.argeo.api.security.DataAdminPrincipal;
-
-/**
- * Log-in a system process as data admin. Protection is via
- * {@link AuthPermission} on this login module, so if it can be accessed it will
- * always succeed.
- */
-public class DataAdminLoginModule implements LoginModule {
-       private Subject subject;
-
-       @Override
-       public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
-                       Map<String, ?> options) {
-               this.subject = subject;
-       }
-
-       @Override
-       public boolean login() throws LoginException {
-               return true;
-       }
-
-       @Override
-       public boolean commit() throws LoginException {
-               subject.getPrincipals().add(new DataAdminPrincipal());
-               return true;
-       }
-
-       @Override
-       public boolean abort() throws LoginException {
-               return true;
-       }
-
-       @Override
-       public boolean logout() throws LoginException {
-               subject.getPrincipals().removeAll(subject.getPrincipals(DataAdminPrincipal.class));
-               return true;
-       }
-}
diff --git a/org.argeo.api/src/org/argeo/api/NodeConstants.java b/org.argeo.api/src/org/argeo/api/NodeConstants.java
deleted file mode 100644 (file)
index e53730e..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-package org.argeo.api;
-
-public interface NodeConstants {
-       /*
-        * DN ATTRIBUTES (RFC 4514)
-        */
-       String CN = "cn";
-       String L = "l";
-       String ST = "st";
-       String O = "o";
-       String OU = "ou";
-       String C = "c";
-       String STREET = "street";
-       String DC = "dc";
-       String UID = "uid";
-
-       /*
-        * STANDARD ATTRIBUTES
-        */
-       String LABELED_URI = "labeledUri";
-
-       /*
-        * COMMON NAMES
-        */
-       String NODE = "node";
-
-       /*
-        * JCR CONVENTIONS
-        */
-       String NODE_REPOSITORY = NODE;
-       String EGO_REPOSITORY = "ego";
-       String SYS_WORKSPACE = "sys";
-       String HOME_WORKSPACE = "home";
-       String SRV_WORKSPACE = "srv";
-       String GUESTS_WORKSPACE = "guests";
-       String PUBLIC_WORKSPACE = "public";
-       String SECURITY_WORKSPACE = "security";
-
-       /*
-        * BASE DNs
-        */
-       String DEPLOY_BASEDN = "ou=deploy,ou=node";
-
-       /*
-        * STANDARD VALUES
-        */
-       String DEFAULT = "default";
-
-       /*
-        * RESERVED ROLES
-        */
-       String ROLES_BASEDN = "ou=roles,ou=node";
-       String TOKENS_BASEDN = "ou=tokens,ou=node";
-       String ROLE_ADMIN = "cn=admin," + ROLES_BASEDN;
-       String ROLE_USER_ADMIN = "cn=userAdmin," + ROLES_BASEDN;
-       String ROLE_DATA_ADMIN = "cn=dataAdmin," + ROLES_BASEDN;
-       // Special system groups that cannot be edited:
-       // user U anonymous = everyone
-       String ROLE_USER = "cn=user," + ROLES_BASEDN;
-       String ROLE_ANONYMOUS = "cn=anonymous," + ROLES_BASEDN;
-       // Account lifecycle
-       String ROLE_REGISTERING = "cn=registering," + ROLES_BASEDN;
-
-       /*
-        * LOGIN CONTEXTS
-        */
-       String LOGIN_CONTEXT_NODE = "NODE";
-       String LOGIN_CONTEXT_USER = "USER";
-       String LOGIN_CONTEXT_ANONYMOUS = "ANONYMOUS";
-       String LOGIN_CONTEXT_DATA_ADMIN = "DATA_ADMIN";
-       String LOGIN_CONTEXT_SINGLE_USER = "SINGLE_USER";
-       String LOGIN_CONTEXT_KEYRING = "KEYRING";
-
-       /*
-        * PATHS
-        */
-       String PATH_DATA = "/data";
-       String PATH_JCR = "/jcr";
-       String PATH_FILES = "/files";
-       // String PATH_JCR_PUB = "/pub";
-
-       /*
-        * FILE SYSTEMS
-        */
-       String SCHEME_NODE = NODE;
-
-       /*
-        * KERBEROS
-        */
-       String NODE_SERVICE = NODE;
-
-       /*
-        * INIT FRAMEWORK PROPERTIES
-        */
-       String NODE_INIT = "argeo.node.init";
-       String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale";
-       String I18N_LOCALES = "argeo.i18n.locales";
-       // Node Security
-       String ROLES_URI = "argeo.node.roles.uri";
-       String TOKENS_URI = "argeo.node.tokens.uri";
-       /** URI to an LDIF file or LDAP server used as initialization or backend */
-       String USERADMIN_URIS = "argeo.node.useradmin.uris";
-       // Transaction manager
-       String TRANSACTION_MANAGER = "argeo.node.transaction.manager";
-       String TRANSACTION_MANAGER_SIMPLE = "simple";
-       String TRANSACTION_MANAGER_BITRONIX = "bitronix";
-       // Node
-       /** Properties configuring the node repository */
-       String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
-       /** Additional standalone repositories, related to data models. */
-       String NODE_REPOS_PROP_PREFIX = "argeo.node.repos.";
-       // HTTP
-       String HTTP_PORT = "org.osgi.service.http.port";
-       String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure";
-       /**
-        * The HTTP header used to convey the DN of a client verified by a reverse
-        * proxy. Typically SSL_CLIENT_S_DN for Apache.
-        */
-       String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn";
-
-       /*
-        * PIDs
-        */
-       String NODE_STATE_PID = "org.argeo.api.state";
-       String NODE_DEPLOYMENT_PID = "org.argeo.api.deployment";
-       String NODE_INSTANCE_PID = "org.argeo.api.instance";
-
-       String NODE_KEYRING_PID = "org.argeo.api.keyring";
-       String NODE_FS_PROVIDER_PID = "org.argeo.api.fsProvider";
-
-       /*
-        * FACTORY PIDs
-        */
-       String NODE_REPOS_FACTORY_PID = "org.argeo.api.repos";
-       String NODE_USER_ADMIN_PID = "org.argeo.api.userAdmin";
-}
diff --git a/org.argeo.api/src/org/argeo/api/NodeDeployment.java b/org.argeo.api/src/org/argeo/api/NodeDeployment.java
deleted file mode 100644 (file)
index 35436a8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.argeo.api;
-
-import java.util.Dictionary;
-
-/** A configured node deployment. */
-public interface NodeDeployment {
-       Long getAvailableSince();
-       
-       void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props);
-       Dictionary<String, Object> getProps(String factoryPid, String cn);
-
-}
diff --git a/org.argeo.api/src/org/argeo/api/NodeInstance.java b/org.argeo.api/src/org/argeo/api/NodeInstance.java
deleted file mode 100644 (file)
index 167ba81..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.argeo.api;
-
-import javax.naming.ldap.LdapName;
-
-/** The structured data */
-public interface NodeInstance {
-       /**
-        * To be used as an identifier of a workgroup, typically as a value for the
-        * 'businessCategory' attribute in LDAP.
-        */
-       public final static String WORKGROUP = "workgroup";
-
-       /** Mark this group as a workgroup */
-       void createWorkgroup(LdapName groupDn);
-}
diff --git a/org.argeo.api/src/org/argeo/api/NodeOID.java b/org.argeo.api/src/org/argeo/api/NodeOID.java
deleted file mode 100644 (file)
index ade1163..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.argeo.api;
-
-interface NodeOID {
-       String BASE = "1.3.6.1.4.1" + ".48308" + ".1";
-
-       // ATTRIBUTE TYPES
-       String ATTRIBUTE_TYPES = BASE + ".4";
-
-       // OBJECT CLASSES
-       String OBJECT_CLASSES = BASE + ".6";
-}
diff --git a/org.argeo.api/src/org/argeo/api/NodeState.java b/org.argeo.api/src/org/argeo/api/NodeState.java
deleted file mode 100644 (file)
index a824ac2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.argeo.api;
-
-import java.util.List;
-import java.util.Locale;
-
-/** A running node process. */
-public interface NodeState {
-       Locale getDefaultLocale();
-
-       List<Locale> getLocales();
-
-       String getHostname();
-
-       Long getAvailableSince();
-
-}
diff --git a/org.argeo.api/src/org/argeo/api/cms/AnonymousPrincipal.java b/org.argeo.api/src/org/argeo/api/cms/AnonymousPrincipal.java
new file mode 100644 (file)
index 0000000..63ee348
--- /dev/null
@@ -0,0 +1,28 @@
+package org.argeo.api.cms;
+
+import java.security.Principal;
+
+/** Marker for anonymous users. */
+public final class AnonymousPrincipal implements Principal {
+       private final String name = CmsConstants.ROLE_ANONYMOUS;
+
+       @Override
+       public String getName() {
+               return name;
+       }
+
+       @Override
+       public int hashCode() {
+               return name.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               return this == obj;
+       }
+
+       @Override
+       public String toString() {
+               return name.toString();
+       }
+}
diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsAuth.java b/org.argeo.api/src/org/argeo/api/cms/CmsAuth.java
new file mode 100644 (file)
index 0000000..decea35
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.api.cms;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/** The type of login context to use. */
+public enum CmsAuth {
+       NODE, USER, ANONYMOUS, DATA_ADMIN, SINGLE_USER, KEYRING;
+
+       public String getLoginContextName() {
+               return name();
+       }
+
+       @Override
+       public String toString() {
+               return getLoginContextName();
+       }
+
+       public LoginContext newLoginContext(CallbackHandler callbackHandler) throws LoginException {
+               return new LoginContext(getLoginContextName(), callbackHandler);
+       }
+
+       /*
+        * LOGIN CONTEXTS
+        */
+       /** @deprecated Use enum instead. */
+       @Deprecated
+       public static final String LOGIN_CONTEXT_NODE = NODE.getLoginContextName();
+       /** @deprecated Use enum instead. */
+       @Deprecated
+       public static final String LOGIN_CONTEXT_USER = USER.getLoginContextName();
+       /** @deprecated Use enum instead. */
+       @Deprecated
+       public static final String LOGIN_CONTEXT_ANONYMOUS = ANONYMOUS.getLoginContextName();
+       /** @deprecated Use enum instead. */
+       @Deprecated
+       public static final String LOGIN_CONTEXT_DATA_ADMIN = DATA_ADMIN.getLoginContextName();
+       /** @deprecated Use enum instead. */
+       @Deprecated
+       public static final String LOGIN_CONTEXT_SINGLE_USER = SINGLE_USER.getLoginContextName();
+       /** @deprecated Use enum instead. */
+       @Deprecated
+       public static final String LOGIN_CONTEXT_KEYRING = KEYRING.getLoginContextName();
+
+}
diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsConstants.java b/org.argeo.api/src/org/argeo/api/cms/CmsConstants.java
new file mode 100644 (file)
index 0000000..8fe9846
--- /dev/null
@@ -0,0 +1,126 @@
+package org.argeo.api.cms;
+
+public interface CmsConstants {
+       /*
+        * DN ATTRIBUTES (RFC 4514)
+        */
+       String CN = "cn";
+       String L = "l";
+       String ST = "st";
+       String O = "o";
+       String OU = "ou";
+       String C = "c";
+       String STREET = "street";
+       String DC = "dc";
+       String UID = "uid";
+
+       /*
+        * STANDARD ATTRIBUTES
+        */
+       String LABELED_URI = "labeledUri";
+
+       /*
+        * COMMON NAMES
+        */
+       String NODE = "node";
+
+       /*
+        * JCR CONVENTIONS
+        */
+       String NODE_REPOSITORY = NODE;
+       String EGO_REPOSITORY = "ego";
+       String SYS_WORKSPACE = "sys";
+       String HOME_WORKSPACE = "home";
+       String SRV_WORKSPACE = "srv";
+       String GUESTS_WORKSPACE = "guests";
+       String PUBLIC_WORKSPACE = "public";
+       String SECURITY_WORKSPACE = "security";
+
+       /*
+        * BASE DNs
+        */
+       String DEPLOY_BASEDN = "ou=deploy,ou=node";
+
+       /*
+        * STANDARD VALUES
+        */
+       String DEFAULT = "default";
+
+       /*
+        * RESERVED ROLES
+        */
+       String ROLES_BASEDN = "ou=roles,ou=node";
+       String TOKENS_BASEDN = "ou=tokens,ou=node";
+       String ROLE_ADMIN = "cn=admin," + ROLES_BASEDN;
+       String ROLE_USER_ADMIN = "cn=userAdmin," + ROLES_BASEDN;
+       String ROLE_DATA_ADMIN = "cn=dataAdmin," + ROLES_BASEDN;
+       // Special system groups that cannot be edited:
+       // user U anonymous = everyone
+       String ROLE_USER = "cn=user," + ROLES_BASEDN;
+       String ROLE_ANONYMOUS = "cn=anonymous," + ROLES_BASEDN;
+       // Account lifecycle
+       String ROLE_REGISTERING = "cn=registering," + ROLES_BASEDN;
+
+       /*
+        * PATHS
+        */
+       String PATH_DATA = "/data";
+       String PATH_JCR = "/jcr";
+       String PATH_FILES = "/files";
+       // String PATH_JCR_PUB = "/pub";
+
+       /*
+        * FILE SYSTEMS
+        */
+       String SCHEME_NODE = NODE;
+
+       /*
+        * KERBEROS
+        */
+       String NODE_SERVICE = NODE;
+
+       /*
+        * INIT FRAMEWORK PROPERTIES
+        */
+       String NODE_INIT = "argeo.node.init";
+       String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale";
+       String I18N_LOCALES = "argeo.i18n.locales";
+       // Node Security
+       String ROLES_URI = "argeo.node.roles.uri";
+       String TOKENS_URI = "argeo.node.tokens.uri";
+       /** URI to an LDIF file or LDAP server used as initialization or backend */
+       String USERADMIN_URIS = "argeo.node.useradmin.uris";
+       // Transaction manager
+       String TRANSACTION_MANAGER = "argeo.node.transaction.manager";
+       String TRANSACTION_MANAGER_SIMPLE = "simple";
+       String TRANSACTION_MANAGER_BITRONIX = "bitronix";
+       // Node
+       /** Properties configuring the node repository */
+       String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
+       /** Additional standalone repositories, related to data models. */
+       String NODE_REPOS_PROP_PREFIX = "argeo.node.repos.";
+       // HTTP
+       String HTTP_PORT = "org.osgi.service.http.port";
+       String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure";
+       /**
+        * The HTTP header used to convey the DN of a client verified by a reverse
+        * proxy. Typically SSL_CLIENT_S_DN for Apache.
+        */
+       String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn";
+
+       /*
+        * PIDs
+        */
+       String NODE_STATE_PID = "org.argeo.api.state";
+       String NODE_DEPLOYMENT_PID = "org.argeo.api.deployment";
+       String NODE_INSTANCE_PID = "org.argeo.api.instance";
+
+       String NODE_KEYRING_PID = "org.argeo.api.keyring";
+       String NODE_FS_PROVIDER_PID = "org.argeo.api.fsProvider";
+
+       /*
+        * FACTORY PIDs
+        */
+       String NODE_REPOS_FACTORY_PID = "org.argeo.api.repos";
+       String NODE_USER_ADMIN_PID = "org.argeo.api.userAdmin";
+}
diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsData.java b/org.argeo.api/src/org/argeo/api/cms/CmsData.java
new file mode 100644 (file)
index 0000000..a12a3ce
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.api.cms;
+
+import javax.naming.ldap.LdapName;
+
+/** The structured data */
+public interface CmsData {
+       /**
+        * To be used as an identifier of a workgroup, typically as a value for the
+        * 'businessCategory' attribute in LDAP.
+        */
+       public final static String WORKGROUP = "workgroup";
+
+       /** Mark this group as a workgroup */
+       void createWorkgroup(LdapName groupDn);
+}
diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsDeployment.java b/org.argeo.api/src/org/argeo/api/cms/CmsDeployment.java
new file mode 100644 (file)
index 0000000..9498f96
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.api.cms;
+
+import java.util.Dictionary;
+
+/** A configured node deployment. */
+public interface CmsDeployment {
+       Long getAvailableSince();
+       
+       void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props);
+       Dictionary<String, Object> getProps(String factoryPid, String cn);
+
+}
diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsLog.java b/org.argeo.api/src/org/argeo/api/cms/CmsLog.java
new file mode 100644 (file)
index 0000000..206cfd6
--- /dev/null
@@ -0,0 +1,182 @@
+package org.argeo.api.cms;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.util.Objects;
+
+/**
+ * A Commons Logging / SLF4J style logging utilities wrapping a standard Java
+ * platform {@link Logger}.
+ */
+public interface CmsLog {
+       Logger getLogger();
+
+       default boolean isDebugEnabled() {
+               return getLogger().isLoggable(Level.DEBUG);
+       }
+
+       default boolean isErrorEnabled() {
+               return getLogger().isLoggable(Level.ERROR);
+       }
+
+       default boolean isInfoEnabled() {
+               return getLogger().isLoggable(Level.INFO);
+       }
+
+       default boolean isTraceEnabled() {
+               return getLogger().isLoggable(Level.TRACE);
+       }
+
+       default boolean isWarnEnabled() {
+               return getLogger().isLoggable(Level.WARNING);
+       }
+
+       /*
+        * TRACE
+        */
+
+       default void trace(String message) {
+               getLogger().log(Level.TRACE, message);
+       }
+
+       default void trace(Object message) {
+               getLogger().log(Level.TRACE, Objects.requireNonNull(message));
+       }
+
+       default void trace(String message, Throwable t) {
+               getLogger().log(Level.TRACE, message, t);
+       }
+
+       default void trace(Object message, Throwable t) {
+               trace(Objects.requireNonNull(message).toString(), t);
+       }
+
+       default void trace(String format, Object... arguments) {
+               getLogger().log(Level.TRACE, format, arguments);
+       }
+
+       /*
+        * DEBUG
+        */
+
+       default void debug(String message) {
+               getLogger().log(Level.DEBUG, message);
+       }
+
+       default void debug(Object message) {
+               getLogger().log(Level.DEBUG, message);
+       }
+
+       default void debug(String message, Throwable t) {
+               getLogger().log(Level.DEBUG, message, t);
+       }
+
+       default void debug(Object message, Throwable t) {
+               debug(Objects.requireNonNull(message).toString(), t);
+       }
+
+       default void debug(String format, Object... arguments) {
+               getLogger().log(Level.DEBUG, format, arguments);
+       }
+
+       /*
+        * INFO
+        */
+
+       default void info(String message) {
+               getLogger().log(Level.INFO, message);
+       }
+
+       default void info(Object message) {
+               getLogger().log(Level.INFO, message);
+       }
+
+       default void info(String message, Throwable t) {
+               getLogger().log(Level.INFO, message, t);
+       }
+
+       default void info(Object message, Throwable t) {
+               info(Objects.requireNonNull(message).toString(), t);
+       }
+
+       default void info(String format, Object... arguments) {
+               getLogger().log(Level.INFO, format, arguments);
+       }
+
+       /*
+        * WARN
+        */
+
+       default void warn(String message) {
+               getLogger().log(Level.WARNING, message);
+       }
+
+       default void warn(Object message) {
+               getLogger().log(Level.WARNING, message);
+       }
+
+       default void warn(String message, Throwable t) {
+               getLogger().log(Level.WARNING, message, t);
+       }
+
+       default void warn(Object message, Throwable t) {
+               warn(Objects.requireNonNull(message).toString(), t);
+       }
+
+       default void warn(String format, Object... arguments) {
+               getLogger().log(Level.WARNING, format, arguments);
+       }
+
+       /*
+        * ERROR
+        */
+
+       default void error(String message) {
+               getLogger().log(Level.ERROR, message);
+       }
+
+       default void error(Object message) {
+               getLogger().log(Level.ERROR, message);
+       }
+
+       default void error(String message, Throwable t) {
+               getLogger().log(Level.ERROR, message, t);
+       }
+
+       default void error(Object message, Throwable t) {
+               error(Objects.requireNonNull(message).toString(), t);
+       }
+
+       default void error(String format, Object... arguments) {
+               getLogger().log(Level.ERROR, format, arguments);
+       }
+
+       /*
+        * STATIC UTILITIES
+        */
+
+       static CmsLog getLog(Class<?> clss) {
+               return getLog(Objects.requireNonNull(clss).getName());
+       }
+
+       static CmsLog getLog(String name) {
+               Logger logger = System.getLogger(Objects.requireNonNull(name));
+               return new LoggerWrapper(logger);
+       }
+
+       /** A trivial implementation wrapping a platform logger. */
+       static class LoggerWrapper implements CmsLog {
+               private final Logger logger;
+
+               LoggerWrapper(Logger logger) {
+                       this.logger = logger;
+               }
+
+               @Override
+               public Logger getLogger() {
+                       return logger;
+               }
+
+       }
+
+}
diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsState.java b/org.argeo.api/src/org/argeo/api/cms/CmsState.java
new file mode 100644 (file)
index 0000000..2642700
--- /dev/null
@@ -0,0 +1,16 @@
+package org.argeo.api.cms;
+
+import java.util.List;
+import java.util.Locale;
+
+/** A running node process. */
+public interface CmsState {
+       Locale getDefaultLocale();
+
+       List<Locale> getLocales();
+
+       String getHostname();
+
+       Long getAvailableSince();
+
+}
diff --git a/org.argeo.api/src/org/argeo/api/cms/DataAdminPrincipal.java b/org.argeo.api/src/org/argeo/api/cms/DataAdminPrincipal.java
new file mode 100644 (file)
index 0000000..bc12bcb
--- /dev/null
@@ -0,0 +1,29 @@
+package org.argeo.api.cms;
+
+import java.security.Principal;
+
+/** Allows to modify any data. */
+public final class DataAdminPrincipal implements Principal {
+       private final String name = CmsConstants.ROLE_DATA_ADMIN;
+
+       @Override
+       public String getName() {
+               return name;
+       }
+
+       @Override
+       public int hashCode() {
+               return name.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               return obj instanceof DataAdminPrincipal;
+       }
+
+       @Override
+       public String toString() {
+               return name.toString();
+       }
+
+}
diff --git a/org.argeo.api/src/org/argeo/api/package-info.java b/org.argeo.api/src/org/argeo/api/package-info.java
deleted file mode 100644 (file)
index 1ea483a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Abstractions or constants related to an Argeo Node, an active repository of
- * linked data.
- */
-package org.argeo.api;
\ No newline at end of file
diff --git a/org.argeo.api/src/org/argeo/api/security/AnonymousPrincipal.java b/org.argeo.api/src/org/argeo/api/security/AnonymousPrincipal.java
deleted file mode 100644 (file)
index d07b055..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.argeo.api.security;
-
-import java.security.Principal;
-
-import javax.naming.ldap.LdapName;
-
-import org.argeo.api.NodeConstants;
-
-/** Marker for anonymous users. */
-public final class AnonymousPrincipal implements Principal {
-       private final String name = NodeConstants.ROLE_ANONYMOUS;
-
-       @Override
-       public String getName() {
-               return name;
-       }
-
-       @Override
-       public int hashCode() {
-               return name.hashCode();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               return this == obj;
-       }
-
-       @Override
-       public String toString() {
-               return name.toString();
-       }
-
-       public LdapName getLdapName(){
-               return NodeSecurityUtils.ROLE_ANONYMOUS_NAME;
-       }
-}
diff --git a/org.argeo.api/src/org/argeo/api/security/CryptoKeyring.java b/org.argeo.api/src/org/argeo/api/security/CryptoKeyring.java
deleted file mode 100644 (file)
index 5ac73c6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.argeo.api.security;
-
-/**
- * Marker interface for an advanced keyring based on cryptography.
- */
-public interface CryptoKeyring extends Keyring {
-       public void changePassword(char[] oldPassword, char[] newPassword);
-
-       public void unlock(char[] password);
-}
diff --git a/org.argeo.api/src/org/argeo/api/security/DataAdminPrincipal.java b/org.argeo.api/src/org/argeo/api/security/DataAdminPrincipal.java
deleted file mode 100644 (file)
index 7581d8d..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.argeo.api.security;
-
-import java.security.Principal;
-
-import org.argeo.api.NodeConstants;
-
-/** Allows to modify any data. */
-public final class DataAdminPrincipal implements Principal {
-       private final String name = NodeConstants.ROLE_DATA_ADMIN;
-
-       @Override
-       public String getName() {
-               return name;
-       }
-
-       @Override
-       public int hashCode() {
-               return name.hashCode();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               return obj instanceof DataAdminPrincipal;
-       }
-
-       @Override
-       public String toString() {
-               return name.toString();
-       }
-
-}
diff --git a/org.argeo.api/src/org/argeo/api/security/Keyring.java b/org.argeo.api/src/org/argeo/api/security/Keyring.java
deleted file mode 100644 (file)
index e0aa854..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.argeo.api.security;
-
-import java.io.InputStream;
-
-/**
- * Access to private (typically encrypted) data. The keyring is responsible for
- * retrieving the necessary credentials. <b>Experimental. This API may
- * change.</b>
- */
-public interface Keyring {
-       /**
-        * Returns the confidential information as chars. Must ask for it if it is
-        * not stored.
-        */
-       public char[] getAsChars(String path);
-
-       /**
-        * Returns the confidential information as a stream. Must ask for it if it
-        * is not stored.
-        */
-       public InputStream getAsStream(String path);
-
-       public void set(String path, char[] arr);
-
-       public void set(String path, InputStream in);
-}
diff --git a/org.argeo.api/src/org/argeo/api/security/NodeSecurityUtils.java b/org.argeo.api/src/org/argeo/api/security/NodeSecurityUtils.java
deleted file mode 100644 (file)
index 2458512..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.argeo.api.security;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-
-import org.argeo.api.NodeConstants;
-
-public class NodeSecurityUtils {
-       public final static LdapName ROLE_ADMIN_NAME, ROLE_DATA_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME,
-                       ROLE_USER_ADMIN_NAME;
-       public final static List<LdapName> RESERVED_ROLES;
-       static {
-               try {
-                       ROLE_ADMIN_NAME = new LdapName(NodeConstants.ROLE_ADMIN);
-                       ROLE_DATA_ADMIN_NAME = new LdapName(NodeConstants.ROLE_DATA_ADMIN);
-                       ROLE_USER_NAME = new LdapName(NodeConstants.ROLE_USER);
-                       ROLE_USER_ADMIN_NAME = new LdapName(NodeConstants.ROLE_USER_ADMIN);
-                       ROLE_ANONYMOUS_NAME = new LdapName(NodeConstants.ROLE_ANONYMOUS);
-                       RESERVED_ROLES = Collections.unmodifiableList(Arrays.asList(
-                                       new LdapName[] { ROLE_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, ROLE_USER_ADMIN_NAME }));
-               } catch (InvalidNameException e) {
-                       throw new Error("Cannot initialize login module class", e);
-               }
-       }
-
-       public static void checkUserName(LdapName name) throws IllegalArgumentException {
-               if (RESERVED_ROLES.contains(name))
-                       throw new IllegalArgumentException(name + " is a reserved name");
-       }
-
-       public static void checkImpliedPrincipalName(LdapName roleName) throws IllegalArgumentException {
-//             if (ROLE_USER_NAME.equals(roleName) || ROLE_ANONYMOUS_NAME.equals(roleName))
-//                     throw new IllegalArgumentException(roleName + " cannot be listed as role");
-       }
-
-}
diff --git a/org.argeo.api/src/org/argeo/api/security/PBEKeySpecCallback.java b/org.argeo.api/src/org/argeo/api/security/PBEKeySpecCallback.java
deleted file mode 100644 (file)
index 81fc724..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.argeo.api.security;
-
-import javax.crypto.spec.PBEKeySpec;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.PasswordCallback;
-
-/**
- * All information required to set up a {@link PBEKeySpec} bar the password
- * itself (use a {@link PasswordCallback})
- */
-public class PBEKeySpecCallback implements Callback {
-       private String secretKeyFactory;
-       private byte[] salt;
-       private Integer iterationCount;
-       /** Can be null for some algorithms */
-       private Integer keyLength;
-       /** Can be null, will trigger secret key encryption if not */
-       private String secretKeyEncryption;
-
-       private String encryptedPasswordHashCipher;
-       private byte[] encryptedPasswordHash;
-
-       public void set(String secretKeyFactory, byte[] salt,
-                       Integer iterationCount, Integer keyLength,
-                       String secretKeyEncryption) {
-               this.secretKeyFactory = secretKeyFactory;
-               this.salt = salt;
-               this.iterationCount = iterationCount;
-               this.keyLength = keyLength;
-               this.secretKeyEncryption = secretKeyEncryption;
-//             this.encryptedPasswordHashCipher = encryptedPasswordHashCipher;
-//             this.encryptedPasswordHash = encryptedPasswordHash;
-       }
-
-       public String getSecretKeyFactory() {
-               return secretKeyFactory;
-       }
-
-       public byte[] getSalt() {
-               return salt;
-       }
-
-       public Integer getIterationCount() {
-               return iterationCount;
-       }
-
-       public Integer getKeyLength() {
-               return keyLength;
-       }
-
-       public String getSecretKeyEncryption() {
-               return secretKeyEncryption;
-       }
-
-       public String getEncryptedPasswordHashCipher() {
-               return encryptedPasswordHashCipher;
-       }
-
-       public byte[] getEncryptedPasswordHash() {
-               return encryptedPasswordHash;
-       }
-
-}
diff --git a/org.argeo.api/src/org/argeo/api/security/package-info.java b/org.argeo.api/src/org/argeo/api/security/package-info.java
deleted file mode 100644 (file)
index 4af6169..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Security related API. */
-package org.argeo.api.security;
\ No newline at end of file
diff --git a/org.argeo.api/src/org/argeo/api/tabular/ArrayTabularRow.java b/org.argeo.api/src/org/argeo/api/tabular/ArrayTabularRow.java
deleted file mode 100644 (file)
index 3a14151..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.argeo.api.tabular;
-
-import java.util.List;
-
-/** Minimal tabular row wrapping an {@link Object} array */
-public class ArrayTabularRow implements TabularRow {
-       private final Object[] arr;
-
-       public ArrayTabularRow(List<?> objs) {
-               this.arr = objs.toArray();
-       }
-
-       public Object get(Integer col) {
-               return arr[col];
-       }
-
-       public int size() {
-               return arr.length;
-       }
-
-       public Object[] toArray() {
-               return arr;
-       }
-
-}
diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularColumn.java b/org.argeo.api/src/org/argeo/api/tabular/TabularColumn.java
deleted file mode 100644 (file)
index 772ca59..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.argeo.api.tabular;
-
-/** The column in a tabular content */
-public class TabularColumn {
-       private String name;
-       /**
-        * JCR types, see
-        * http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/index.html
-        * ?javax/jcr/PropertyType.html
-        */
-       private Integer type;
-
-       /** column with default type */
-       public TabularColumn(String name) {
-               super();
-               this.name = name;
-       }
-
-       public TabularColumn(String name, Integer type) {
-               super();
-               this.name = name;
-               this.type = type;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public Integer getType() {
-               return type;
-       }
-
-       public void setType(Integer type) {
-               this.type = type;
-       }
-
-}
diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularContent.java b/org.argeo.api/src/org/argeo/api/tabular/TabularContent.java
deleted file mode 100644 (file)
index 3c9d049..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.argeo.api.tabular;
-
-import java.util.List;
-
-/**
- * Content organized as a table, possibly with headers. Only JCR types are
- * supported even though there is not direct dependency on JCR.
- */
-public interface TabularContent {
-       /** The headers of this table or <code>null</code> is none available. */
-       public List<TabularColumn> getColumns();
-
-       public TabularRowIterator read();
-}
diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularRow.java b/org.argeo.api/src/org/argeo/api/tabular/TabularRow.java
deleted file mode 100644 (file)
index a79b072..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.argeo.api.tabular;
-
-/** A row of tabular data */
-public interface TabularRow {
-       /** The value at this column index */
-       public Object get(Integer col);
-
-       /** The raw objects (direct references) */
-       public Object[] toArray();
-
-       /** Number of columns */
-       public int size();
-}
diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularRowIterator.java b/org.argeo.api/src/org/argeo/api/tabular/TabularRowIterator.java
deleted file mode 100644 (file)
index 27a9c6f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.argeo.api.tabular;
-
-import java.util.Iterator;
-
-/** Navigation of rows */
-public interface TabularRowIterator extends Iterator<TabularRow> {
-       /**
-        * Current row number, has to be incremented by each call to next() ; starts at 0, will
-        * therefore be 1 for the first row returned.
-        */
-       public Long getCurrentRowNumber();
-}
diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularWriter.java b/org.argeo.api/src/org/argeo/api/tabular/TabularWriter.java
deleted file mode 100644 (file)
index c434ffa..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.argeo.api.tabular;
-
-
-/** Write to a tabular content */
-public interface TabularWriter {
-       /** Append a new row of data */
-       public void appendRow(Object[] row);
-
-       /** Finish persisting data and release resources */
-       public void close();
-}
diff --git a/org.argeo.api/src/org/argeo/api/tabular/package-info.java b/org.argeo.api/src/org/argeo/api/tabular/package-info.java
deleted file mode 100644 (file)
index 738281f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Tabular format API. */
-package org.argeo.api.tabular;
\ No newline at end of file
index 326a67e10d2c884124d29d775ae2109aa63b5928..3d57e1659934ca429e35b602f3b69860e4e21ca9 100644 (file)
@@ -7,8 +7,7 @@ import javax.annotation.PostConstruct;
 import javax.security.auth.Subject;
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.eclipse.e4.ui.model.application.MApplication;
@@ -19,7 +18,7 @@ import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow;
 import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
 
 public class AuthAddon {
-       private final static Log log = LogFactory.getLog(AuthAddon.class);
+       private final static CmsLog log = CmsLog.getLog(AuthAddon.class);
 
        public final static String AUTH = "auth.";
 
index 1d3bab9f81e7a2dfb8112171512c64f919abdc8d..0ecd0a155dbe4051de15c0814c9c0d893a887f84 100644 (file)
@@ -12,9 +12,9 @@ import javax.inject.Inject;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.api.security.CryptoKeyring;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.security.CryptoKeyring;
 import org.argeo.cms.swt.dialogs.CmsMessageDialog;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.osgi.transaction.WorkTransaction;
index f352f91aaac9028ab59a8939b916df707ccfa1ca..98e80936da362693bf1844582fd470a52521177b 100644 (file)
@@ -16,10 +16,10 @@ import javax.jcr.observation.Event;
 import javax.jcr.observation.EventListener;
 import javax.jcr.observation.ObservationManager;
 
-import org.argeo.api.NodeConstants;
-import org.argeo.api.security.CryptoKeyring;
-import org.argeo.api.security.Keyring;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.CmsException;
+import org.argeo.cms.security.CryptoKeyring;
+import org.argeo.cms.security.Keyring;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.ui.jcr.JcrBrowserUtils;
 import org.argeo.cms.ui.jcr.NodeContentProvider;
@@ -100,7 +100,7 @@ public class JcrBrowserView {
                top.setLayout(CmsSwtUtils.noSpaceGridLayout());
 
                try {
-                       this.userSession = this.nodeRepository.login(NodeConstants.HOME_WORKSPACE);
+                       this.userSession = this.nodeRepository.login(CmsConstants.HOME_WORKSPACE);
                } catch (RepositoryException e) {
                        throw new CmsException("Cannot open user session", e);
                }
index cf7aac86a0fe0b05d432382f19a4eb5d7d520f3c..dc47f6edfc12e6f836bf3843bae13c9d94062d0d 100644 (file)
@@ -11,12 +11,12 @@ import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
 
-import org.argeo.api.NodeConstants;
-import org.argeo.api.security.Keyring;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.ArgeoTypes;
 import org.argeo.cms.e4.jcr.JcrBrowserView;
 import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.security.Keyring;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.jcr.JcrUtils;
@@ -130,11 +130,11 @@ public class AddRemoteRepository {
                                String checkedUriStr = checkedUri.toString();
 
                                Hashtable<String, String> params = new Hashtable<String, String>();
-                               params.put(NodeConstants.LABELED_URI, checkedUriStr);
+                               params.put(CmsConstants.LABELED_URI, checkedUriStr);
                                Repository repository = repositoryFactory.getRepository(params);
                                if (username.getText().trim().equals("")) {// anonymous
                                        // FIXME make it more generic
-                                       session = repository.login(NodeConstants.SYS_WORKSPACE);
+                                       session = repository.login(CmsConstants.SYS_WORKSPACE);
                                } else {
                                        // FIXME use getTextChars() when upgrading to 3.7
                                        // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412
index c9c18e9df7af9cdd4305691257599d8483c29bf4..4fd1d68dc5498dc6bf893f5a603935210898bb72 100644 (file)
@@ -2,8 +2,7 @@ package org.argeo.cms.e4.maintenance;
 
 import java.util.Collection;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
@@ -16,7 +15,7 @@ import org.osgi.framework.ServiceReference;
 abstract class AbstractOsgiComposite extends Composite {
        private static final long serialVersionUID = -4097415973477517137L;
        protected final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-       protected final Log log = LogFactory.getLog(getClass());
+       protected final CmsLog log = CmsLog.getLog(getClass());
 
        public AbstractOsgiComposite(Composite parent, int style) {
                super(parent, style);
index 22e80069d61e2218b3bca163fd71582ce93e6d3d..ef95bde64aaa344edd702fc6ba73df39580fd22b 100644 (file)
@@ -9,7 +9,7 @@ import java.util.Collection;
 
 import org.apache.jackrabbit.core.RepositoryContext;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
@@ -82,12 +82,12 @@ class DataDeploymentUi extends AbstractOsgiComposite {
        private void initCurrentUi(Composite parent) {
                parent.setLayout(new GridLayout());
                Collection<ServiceReference<RepositoryContext>> contexts = getServiceReferences(RepositoryContext.class,
-                               "(" + NodeConstants.CN + "=*)");
+                               "(" + CmsConstants.CN + "=*)");
                StringBuffer text = new StringBuffer();
                text.append("<span style='font-variant: small-caps;'>Jackrabbit Repositories</span><br/>");
                for (ServiceReference<RepositoryContext> sr : contexts) {
                        RepositoryContext repositoryContext = bc.getService(sr);
-                       String alias = sr.getProperty(NodeConstants.CN).toString();
+                       String alias = sr.getProperty(CmsConstants.CN).toString();
                        String rootNodeId = repositoryContext.getRootNodeId().toString();
                        RepositoryConfig repositoryConfig = repositoryContext.getRepositoryConfig();
                        Path repoHomePath = new File(repositoryConfig.getHomeDir()).toPath().toAbsolutePath();
index 505f67d8157b8f787364301ba96ca9abff56c5e9..6aaa1692f35c637d14d3c4f05dcfe26b412bcc96 100644 (file)
@@ -3,9 +3,9 @@ package org.argeo.cms.e4.maintenance;
 import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeDeployment;
-import org.argeo.api.NodeState;
+import org.argeo.api.cms.CmsState;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsDeployment;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FillLayout;
@@ -62,18 +62,18 @@ class DeploymentEntryPoint {
                composite.setLayoutData(gridData);
                composite.setLayout(new FillLayout());
 
-               ServiceReference<NodeState> nodeStateRef = bc.getServiceReference(NodeState.class);
+               ServiceReference<CmsState> nodeStateRef = bc.getServiceReference(CmsState.class);
                if (nodeStateRef == null)
                        throw new IllegalStateException("No CMS state available");
-               NodeState nodeState = bc.getService(nodeStateRef);
-               ServiceReference<NodeDeployment> nodeDeploymentRef = bc.getServiceReference(NodeDeployment.class);
+               CmsState nodeState = bc.getService(nodeStateRef);
+               ServiceReference<CmsDeployment> nodeDeploymentRef = bc.getServiceReference(CmsDeployment.class);
                Label label = new Label(composite, SWT.WRAP);
                CmsSwtUtils.markup(label);
                if (nodeDeploymentRef == null) {
                        label.setText("Not yet deployed on <br>" + nodeState.getHostname() + "</br>, please configure below.");
                } else {
-                       Object stateUuid = nodeStateRef.getProperty(NodeConstants.CN);
-                       NodeDeployment nodeDeployment = bc.getService(nodeDeploymentRef);
+                       Object stateUuid = nodeStateRef.getProperty(CmsConstants.CN);
+                       CmsDeployment nodeDeployment = bc.getService(nodeDeploymentRef);
                        GregorianCalendar calendar = new GregorianCalendar();
                        calendar.setTimeInMillis(nodeDeployment.getAvailableSince());
                        calendar.setTimeZone(TimeZone.getDefault());
index 31f2d1c8d557ae7b4e26e7a9acb553e4aa3e02ca..137f76242629ad7fbf321ad72ddf8bc0dc9d0af9 100644 (file)
@@ -12,7 +12,7 @@ import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
 import org.argeo.cms.ui.eclipse.forms.IManagedForm;
 import org.argeo.cms.ui.eclipse.forms.ManagedForm;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.e4.ui.di.Persist;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
index 2521612c765dcf16b7f1a6f434269b0fafccb5d0..239bb3156e9b537e52cd1b058454598a40c99ac6 100644 (file)
@@ -1,9 +1,9 @@
 package org.argeo.cms.e4.users;
 
-import static org.argeo.api.NodeInstance.WORKGROUP;
+import static org.argeo.api.cms.CmsData.WORKGROUP;
 import static org.argeo.cms.auth.UserAdminUtils.setProperty;
-import static org.argeo.naming.LdapAttrs.businessCategory;
-import static org.argeo.naming.LdapAttrs.description;
+import static org.argeo.util.naming.LdapAttrs.businessCategory;
+import static org.argeo.util.naming.LdapAttrs.description;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -18,8 +18,8 @@ import javax.jcr.Session;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeInstance;
+import org.argeo.api.cms.CmsData;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.UserAdminUtils;
 import org.argeo.cms.e4.users.providers.CommonNameLP;
@@ -34,8 +34,8 @@ import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.jcr.JcrUtils;
-import org.argeo.naming.LdapAttrs;
 import org.argeo.osgi.transaction.WorkTransaction;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.ToolBarManager;
@@ -87,7 +87,7 @@ public class GroupEditor extends AbstractRoleEditor {
        @Inject
        private Repository repository;
        @Inject
-       private NodeInstance nodeInstance;
+       private CmsData nodeInstance;
        // private final UserAdminWrapper userAdminWrapper;
        private Session groupsSession;
 
@@ -119,7 +119,7 @@ public class GroupEditor extends AbstractRoleEditor {
        @Override
        protected void createUi(Composite parent) {
                try {
-                       groupsSession = repository.login(NodeConstants.SRV_WORKSPACE);
+                       groupsSession = repository.login(CmsConstants.SRV_WORKSPACE);
                } catch (RepositoryException e) {
                        throw new CmsException("Cannot retrieve session", e);
                }
index 9104a6a611e79548fa6b53fb2179f0cc2f5828e4..ddad34fd1e59b2bad78a96618d109ab29b0e2837 100644 (file)
@@ -7,9 +7,8 @@ import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.e4.users.providers.CommonNameLP;
@@ -27,8 +26,8 @@ import org.argeo.cms.e4.users.providers.UserDragListener;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.LdapObjs;
+import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.LdapObjs;
 import org.eclipse.e4.ui.di.Focus;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
@@ -56,7 +55,7 @@ import org.osgi.service.useradmin.UserAdminListener;
 
 /** List all groups with filter */
 public class GroupsView {
-       private final static Log log = LogFactory.getLog(GroupsView.class);
+       private final static CmsLog log = CmsLog.getLog(GroupsView.class);
        // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".groupsView";
 
        @Inject
@@ -155,14 +154,14 @@ public class GroupsView {
 
                public MyUserTableViewer(Composite parent, int style) {
                        super(parent, style);
-                       showSystemRoles = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN);
+                       showSystemRoles = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN);
                }
 
                protected void populateStaticFilters(Composite staticFilterCmp) {
                        staticFilterCmp.setLayout(new GridLayout());
                        final Button showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK);
                        showSystemRoleBtn.setText("Show system roles");
-                       showSystemRoles = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN);
+                       showSystemRoles = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN);
                        showSystemRoleBtn.setSelection(showSystemRoles);
 
                        showSystemRoleBtn.addSelectionListener(new SelectionAdapter() {
@@ -195,11 +194,11 @@ public class GroupsView {
                                        builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
                                                        .append(LdapObjs.groupOfNames.name()).append(")");
                                        // hide tokens
-                                       builder.append("(!(").append(LdapAttrs.DN).append("=*").append(NodeConstants.TOKENS_BASEDN)
+                                       builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.TOKENS_BASEDN)
                                                        .append("))");
 
                                        if (!showSystemRoles)
-                                               builder.append("(!(").append(LdapAttrs.DN).append("=*").append(NodeConstants.ROLES_BASEDN)
+                                               builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.ROLES_BASEDN)
                                                                .append("))");
                                        builder.append("(|");
                                        builder.append(tmpBuilder.toString());
@@ -208,12 +207,12 @@ public class GroupsView {
                                        if (!showSystemRoles)
                                                builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
                                                                .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*")
-                                                               .append(NodeConstants.ROLES_BASEDN).append("))(!(").append(LdapAttrs.DN).append("=*")
-                                                               .append(NodeConstants.TOKENS_BASEDN).append(")))");
+                                                               .append(CmsConstants.ROLES_BASEDN).append("))(!(").append(LdapAttrs.DN).append("=*")
+                                                               .append(CmsConstants.TOKENS_BASEDN).append(")))");
                                        else
                                                builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
                                                                .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*")
-                                                               .append(NodeConstants.TOKENS_BASEDN).append(")))");
+                                                               .append(CmsConstants.TOKENS_BASEDN).append(")))");
 
                                }
                                roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString());
index d1bdd775aa77c413403b15760e197faed0795159..16aa78316142a1a37f2340293c7ee15b4437ff9d 100644 (file)
@@ -8,7 +8,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.CmsException;
 import org.argeo.osgi.transaction.WorkTransaction;
 import org.argeo.osgi.useradmin.UserAdminConf;
@@ -95,9 +95,9 @@ public class UserAdminWrapper {
 
                        if (onlyWritable && readOnly)
                                continue;
-                       if (baseDn.equalsIgnoreCase(NodeConstants.ROLES_BASEDN))
+                       if (baseDn.equalsIgnoreCase(CmsConstants.ROLES_BASEDN))
                                continue;
-                       if (baseDn.equalsIgnoreCase(NodeConstants.TOKENS_BASEDN))
+                       if (baseDn.equalsIgnoreCase(CmsConstants.TOKENS_BASEDN))
                                continue;
                        dns.put(baseDn, UserAdminConf.propertiesAsUri(userDirectories.get(userDirectory)).toString());
 
index 4073a209b25c3b7582820731c12da0b5064beae9..a38d171ef70f67b86d7d6e0dff8eab13abc8bad4 100644 (file)
@@ -5,9 +5,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.UserAdminUtils;
@@ -18,9 +17,9 @@ import org.argeo.cms.e4.users.providers.UserNameLP;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.LdapObjs;
 import org.argeo.osgi.transaction.WorkTransaction;
+import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.LdapObjs;
 import org.eclipse.jface.dialogs.IPageChangeProvider;
 import org.eclipse.jface.dialogs.IPageChangedListener;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -47,7 +46,7 @@ import org.osgi.service.useradmin.UserAdminEvent;
 /** Wizard to update users */
 public class UserBatchUpdateWizard extends Wizard {
 
-       private final static Log log = LogFactory.getLog(UserBatchUpdateWizard.class);
+       private final static CmsLog log = CmsLog.getLog(UserBatchUpdateWizard.class);
        private UserAdminWrapper userAdminWrapper;
 
        // pages
@@ -463,7 +462,7 @@ public class UserBatchUpdateWizard extends Wizard {
                        columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200));
 
                        // Only show technical DN to admin
-                       if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN))
+                       if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN))
                                columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300));
 
                        userTableCmp = new ChooseUserTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
@@ -562,7 +561,7 @@ public class UserBatchUpdateWizard extends Wizard {
                        columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150));
                        columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200));
                        // Only show technical DN to admin
-                       if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN))
+                       if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN))
                                columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300));
                        userTableCmp = new ChosenUsersTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
                        userTableCmp.setLayoutData(EclipseUiUtils.fillAll());
index a931001204b1399cbe3d0730f995ddf0e1b09dde..66f442082191a10f1161ea9cce546810d87700e5 100644 (file)
@@ -1,11 +1,11 @@
 package org.argeo.cms.e4.users;
 
 import static org.argeo.cms.auth.UserAdminUtils.getProperty;
-import static org.argeo.naming.LdapAttrs.cn;
-import static org.argeo.naming.LdapAttrs.givenName;
-import static org.argeo.naming.LdapAttrs.mail;
-import static org.argeo.naming.LdapAttrs.sn;
-import static org.argeo.naming.LdapAttrs.uid;
+import static org.argeo.util.naming.LdapAttrs.cn;
+import static org.argeo.util.naming.LdapAttrs.givenName;
+import static org.argeo.util.naming.LdapAttrs.mail;
+import static org.argeo.util.naming.LdapAttrs.sn;
+import static org.argeo.util.naming.LdapAttrs.uid;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -13,7 +13,7 @@ import java.util.List;
 
 import javax.inject.Inject;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.UserAdminUtils;
 import org.argeo.cms.e4.users.providers.CommonNameLP;
@@ -27,7 +27,7 @@ import org.argeo.cms.ui.eclipse.forms.IManagedForm;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.ToolBarManager;
@@ -370,7 +370,7 @@ public class UserEditor extends AbstractRoleEditor {
                        staticFilterCmp.setLayout(new GridLayout());
                        showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK);
                        showSystemRoleBtn.setText("Show system roles");
-                       boolean showSysRole = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN);
+                       boolean showSysRole = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN);
                        showSystemRoleBtn.setSelection(showSysRole);
                        userFilter.setShowSystemRole(showSysRole);
                        showSystemRoleBtn.addSelectionListener(new SelectionAdapter() {
index a9a4ede0af17e6a3a9af3106348c7e9c06abc1e7..c6d024ebc9c81ef2b3d9231f62754eea1cef488b 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.cms.e4.users;
 
 import org.argeo.cms.e4.CmsE4Utils;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
index 4b94f5cc84f2f4e603cb5642e8989a2ffc3efd1a..877a925c6d4371d7396cc1de8737a7e34c26e74d 100644 (file)
@@ -7,7 +7,7 @@ import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.e4.users.providers.CommonNameLP;
@@ -18,8 +18,8 @@ import org.argeo.cms.e4.users.providers.UserNameLP;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.LdapObjs;
+import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.LdapObjs;
 import org.eclipse.e4.ui.di.Focus;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
@@ -66,7 +66,7 @@ public class UsersView {
                columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150));
                columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200));
                // Only show technical DN to admin
-               if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN))
+               if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN))
                        columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300));
 
                // Create and configure the table
index e49b11074d5feead31b1e85dcd77f1c5af927f12..d2ffa791b18d3751fb56012b3603c4c5ee2793ff 100644 (file)
@@ -9,8 +9,8 @@ import org.argeo.cms.CmsException;
 import org.argeo.cms.e4.users.UserAdminWrapper;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.argeo.naming.LdapAttrs;
 import org.argeo.osgi.useradmin.UserAdminConf;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.jface.wizard.Wizard;
 import org.eclipse.jface.wizard.WizardDialog;
index 1faa90de2cdedc221a180fb265f41f113c745e6b..07d82c749ca320adeda6a5e9289d915858c9e6fc 100644 (file)
@@ -15,8 +15,8 @@ import org.argeo.cms.e4.users.UiAdminUtils;
 import org.argeo.cms.e4.users.UserAdminWrapper;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.argeo.naming.LdapAttrs;
 import org.argeo.osgi.useradmin.UserAdminConf;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.jface.wizard.Wizard;
 import org.eclipse.jface.wizard.WizardDialog;
index eb8819425c101a7991eaabe63ceb8d52803c9c53..2d8db67d73edf956f247bfb96395af0161211ddb 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.cms.e4.users.providers;
 
 import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.service.useradmin.User;
 
 /** Simply declare a label provider that returns the common name of a user */
index a312c0dfc7323a3a1f5cd9f856c85960020d3093..52d3b858f2fabf41fd4865960565bf71ba99063d 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.cms.e4.users.providers;
 
 import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.service.useradmin.User;
 
 /** Simply declare a label provider that returns the Primary Mail of a user */
index d9a75b89e4e0d8780a5910c314e9b375809493db..49a2026c974b9fe4086a40e481e9c9cdd5475dd0 100644 (file)
@@ -1,10 +1,10 @@
 package org.argeo.cms.e4.users.providers;
 
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeInstance;
+import org.argeo.api.cms.CmsData;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.auth.UserAdminUtils;
 import org.argeo.cms.e4.users.SecurityAdminImages;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.swt.graphics.Image;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
@@ -22,11 +22,11 @@ public class RoleIconLP extends UserAdminAbstractLP {
        public Image getImage(Object element) {
                User user = (User) element;
                String dn = user.getName();
-               if (dn.endsWith(NodeConstants.ROLES_BASEDN))
+               if (dn.endsWith(CmsConstants.ROLES_BASEDN))
                        return SecurityAdminImages.ICON_ROLE;
                else if (user.getType() == Role.GROUP) {
                        String businessCategory = UserAdminUtils.getProperty(user, LdapAttrs.businessCategory);
-                       if (businessCategory != null && businessCategory.equals(NodeInstance.WORKGROUP))
+                       if (businessCategory != null && businessCategory.equals(CmsData.WORKGROUP))
                                return SecurityAdminImages.ICON_WORKGROUP;
                        return SecurityAdminImages.ICON_GROUP;
                } else
index e090fe251e7839b9405da7b0892f69eb38e3f606..154b04725574e6523fd93446c9f6553b7837bf8c 100644 (file)
@@ -2,9 +2,9 @@ package org.argeo.cms.e4.users.providers;
 
 import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerFilter;
 import org.osgi.service.useradmin.User;
@@ -37,7 +37,7 @@ public class UserFilter extends ViewerFilter {
        @Override
        public boolean select(Viewer viewer, Object parentElement, Object element) {
                User user = (User) element;
-               if (!showSystemRole && user.getName().matches(".*(" + NodeConstants.ROLES_BASEDN + ")"))
+               if (!showSystemRole && user.getName().matches(".*(" + CmsConstants.ROLES_BASEDN + ")"))
                        // UserAdminUtils.getProperty(user, LdifName.dn.name())
                        // .toLowerCase().endsWith(AuthConstants.ROLES_BASEDN))
                        return false;
index e152c002ec36605adefc596f45306b70dc9063d6..40d38eec2bc522f90eda3c12fbe85e2a457f681a 100644 (file)
@@ -16,13 +16,13 @@ import javax.jcr.Session;
 import javax.jcr.query.Query;
 import javax.jcr.query.QueryManager;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.jcr.Jcr;
 
 /** Utilities around documents. */
 public class CmsFsUtils {
        // TODO make it more robust and configurable
-       private static String baseWorkspaceName = NodeConstants.SYS_WORKSPACE;
+       private static String baseWorkspaceName = CmsConstants.SYS_WORKSPACE;
 
        public static Node getNode(Repository repository, Path path) {
                String workspaceName = path.getNameCount() == 0 ? baseWorkspaceName : path.getName(0).toString();
@@ -75,7 +75,7 @@ public class CmsFsUtils {
                                : '/' + workspaceName + Jcr.getPath(node);
                URI uri;
                try {
-                       uri = new URI(NodeConstants.SCHEME_NODE, null, fullPath, null);
+                       uri = new URI(CmsConstants.SCHEME_NODE, null, fullPath, null);
                } catch (URISyntaxException e) {
                        throw new IllegalArgumentException("Cannot interpret " + fullPath + " as an URI", e);
                }
index 27f011b13ca87b0fbf5cf0ddb49fb6e67df2b33e..0536fb6455bb06704868833151c3658bc12781fa 100644 (file)
@@ -11,30 +11,29 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeDeployment;
+import org.argeo.api.cms.CmsDeployment;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
 import org.argeo.jcr.JcrException;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.FrameworkUtil;
 
 /** JCR specific init utilities. */
 public class JcrInitUtils {
-       private final static Log log = LogFactory.getLog(JcrInitUtils.class);
+       private final static CmsLog log = CmsLog.getLog(JcrInitUtils.class);
        private final static BundleContext bundleContext = FrameworkUtil.getBundle(JcrInitUtils.class).getBundleContext();
 
-       public static void addToDeployment(NodeDeployment nodeDeployment) {
+       public static void addToDeployment(CmsDeployment nodeDeployment) {
                // node repository
 //             Dictionary<String, Object> provided = null;
-               Dictionary<String, Object> provided = nodeDeployment.getProps(NodeConstants.NODE_REPOS_FACTORY_PID,
-                               NodeConstants.NODE);
+               Dictionary<String, Object> provided = nodeDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID,
+                               CmsConstants.NODE);
                Dictionary<String, Object> nodeConfig = JcrInitUtils.getNodeRepositoryConfig(provided);
                // node repository is mandatory
-               nodeDeployment.addFactoryDeployConfig(NodeConstants.NODE_REPOS_FACTORY_PID, nodeConfig);
+               nodeDeployment.addFactoryDeployConfig(CmsConstants.NODE_REPOS_FACTORY_PID, nodeConfig);
 
                // additional repositories
 //             dataModels: for (DataModels.DataModel dataModel : dataModels.getNonAbstractDataModels()) {
@@ -52,25 +51,25 @@ public class JcrInitUtils {
        public static Dictionary<String, Object> getNodeRepositoryConfig(Dictionary<String, Object> provided) {
                Dictionary<String, Object> props = provided != null ? provided : new Hashtable<String, Object>();
                for (RepoConf repoConf : RepoConf.values()) {
-                       Object value = getFrameworkProp(NodeConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
+                       Object value = getFrameworkProp(CmsConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
                        if (value != null) {
                                props.put(repoConf.name(), value);
                                if (log.isDebugEnabled())
                                        log.debug("Set node repo configuration " + repoConf.name() + " to " + value);
                        }
                }
-               props.put(NodeConstants.CN, NodeConstants.NODE_REPOSITORY);
+               props.put(CmsConstants.CN, CmsConstants.NODE_REPOSITORY);
                return props;
        }
 
        public static Dictionary<String, Object> getRepositoryConfig(String dataModelName,
                        Dictionary<String, Object> provided) {
-               if (dataModelName.equals(NodeConstants.NODE_REPOSITORY) || dataModelName.equals(NodeConstants.EGO_REPOSITORY))
+               if (dataModelName.equals(CmsConstants.NODE_REPOSITORY) || dataModelName.equals(CmsConstants.EGO_REPOSITORY))
                        throw new IllegalArgumentException("Data model '" + dataModelName + "' is reserved.");
                Dictionary<String, Object> props = provided != null ? provided : new Hashtable<String, Object>();
                for (RepoConf repoConf : RepoConf.values()) {
                        Object value = getFrameworkProp(
-                                       NodeConstants.NODE_REPOS_PROP_PREFIX + dataModelName + '.' + repoConf.name());
+                                       CmsConstants.NODE_REPOS_PROP_PREFIX + dataModelName + '.' + repoConf.name());
                        if (value != null) {
                                props.put(repoConf.name(), value);
                                if (log.isDebugEnabled())
@@ -78,7 +77,7 @@ public class JcrInitUtils {
                        }
                }
                if (props.size() != 0)
-                       props.put(NodeConstants.CN, dataModelName);
+                       props.put(CmsConstants.CN, dataModelName);
                return props;
        }
 
@@ -86,7 +85,7 @@ public class JcrInitUtils {
                try {
                        Repository repository = createRemoteRepository(new URI(uri));
                        Hashtable<String, Object> properties = new Hashtable<>();
-                       properties.put(NodeConstants.CN, NodeConstants.NODE_INIT);
+                       properties.put(CmsConstants.CN, CmsConstants.NODE_INIT);
                        properties.put(LdapAttrs.labeledURI.name(), uri);
                        properties.put(Constants.SERVICE_RANKING, -1000);
                        bundleContext.registerService(Repository.class, repository, properties);
@@ -102,7 +101,7 @@ public class JcrInitUtils {
                Map<String, String> params = new HashMap<String, String>();
                params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString());
                // TODO make it configurable
-               params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, NodeConstants.SYS_WORKSPACE);
+               params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, CmsConstants.SYS_WORKSPACE);
                return repositoryFactory.getRepository(params);
        }
 
index a48adccab0b1dcc5e1db759404534ea6c407d02d..a45656cf567bda2e83e405f5080e5d5a42ca0dd5 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.internal.jcr;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.osgi.metatype.EnumAD;
 import org.argeo.osgi.metatype.EnumOCD;
 
@@ -9,7 +9,7 @@ public enum RepoConf implements EnumAD {
        /** Repository type */
        type("h2"),
        /** Default workspace */
-       defaultWorkspace(NodeConstants.SYS_WORKSPACE),
+       defaultWorkspace(CmsConstants.SYS_WORKSPACE),
        /** Database URL */
        dburl(null),
        /** Database user */
index 22d763a79e86258c74b5739afdba243e0cee854e..3db97167c3dae6947996372d818f8d74004f4f1c 100644 (file)
@@ -14,20 +14,19 @@ import java.util.UUID;
 
 import javax.jcr.RepositoryException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.core.RepositoryContext;
 import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.cache.CacheManager;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
 import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.jcr.internal.CmsPaths;
 import org.xml.sax.InputSource;
 
 /** Can interpret properties in order to create an actual JCR repository. */
 public class RepositoryBuilder {
-       private final static Log log = LogFactory.getLog(RepositoryBuilder.class);
+       private final static CmsLog log = CmsLog.getLog(RepositoryBuilder.class);
 
        public RepositoryContext createRepositoryContext(Dictionary<String, ?> properties)
                        throws RepositoryException, IOException {
@@ -99,7 +98,7 @@ public class RepositoryBuilder {
                String homeUri = props.getProperty(RepoConf.labeledUri.name());
                Path homePath;
                if (homeUri == null) {
-                       String cn = props.getProperty(NodeConstants.CN);
+                       String cn = props.getProperty(CmsConstants.CN);
                        assert cn != null;
                        if (clusterId != null) {
                                homePath = CmsPaths.getRepoDirPath(cn + '/' + clusterId);
index ff128a29de4e13a242d95877a81b6e122b900351..b5d9adfcaedbef28390945b1458c191a922b9588 100644 (file)
@@ -18,19 +18,20 @@ import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsConstants;
 
 /** Utilities related to Argeo model in JCR */
 public class CmsJcrUtils {
        /**
         * Wraps the call to the repository factory based on parameter
-        * {@link NodeConstants#CN} in order to simplify it and protect against future
+        * {@link CmsConstants#CN} in order to simplify it and protect against future
         * API changes.
         */
        public static Repository getRepositoryByAlias(RepositoryFactory repositoryFactory, String alias) {
                try {
                        Map<String, String> parameters = new HashMap<String, String>();
-                       parameters.put(NodeConstants.CN, alias);
+                       parameters.put(CmsConstants.CN, alias);
                        return repositoryFactory.getRepository(parameters);
                } catch (RepositoryException e) {
                        throw new RuntimeException("Unexpected exception when trying to retrieve repository with alias " + alias,
@@ -40,7 +41,7 @@ public class CmsJcrUtils {
 
        /**
         * Wraps the call to the repository factory based on parameter
-        * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
+        * {@link CmsConstants#LABELED_URI} in order to simplify it and protect against
         * future API changes.
         */
        public static Repository getRepositoryByUri(RepositoryFactory repositoryFactory, String uri) {
@@ -49,15 +50,15 @@ public class CmsJcrUtils {
 
        /**
         * Wraps the call to the repository factory based on parameter
-        * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
+        * {@link CmsConstants#LABELED_URI} in order to simplify it and protect against
         * future API changes.
         */
        public static Repository getRepositoryByUri(RepositoryFactory repositoryFactory, String uri, String alias) {
                try {
                        Map<String, String> parameters = new HashMap<String, String>();
-                       parameters.put(NodeConstants.LABELED_URI, uri);
+                       parameters.put(CmsConstants.LABELED_URI, uri);
                        if (alias != null)
-                               parameters.put(NodeConstants.CN, alias);
+                               parameters.put(CmsConstants.CN, alias);
                        return repositoryFactory.getRepository(parameters);
                } catch (RepositoryException e) {
                        throw new RuntimeException("Unexpected exception when trying to retrieve repository with uri " + uri, e);
@@ -113,7 +114,7 @@ public class CmsJcrUtils {
 
        private static void checkUserWorkspace(Session session, String username) {
                String workspaceName = session.getWorkspace().getName();
-               if (!NodeConstants.HOME_WORKSPACE.equals(workspaceName))
+               if (!CmsConstants.HOME_WORKSPACE.equals(workspaceName))
                        throw new IllegalArgumentException(workspaceName + " is not the home workspace for user " + username);
        }
 
@@ -167,7 +168,7 @@ public class CmsJcrUtils {
 
        private static void checkGroupWorkspace(Session session, String groupname) {
                String workspaceName = session.getWorkspace().getName();
-               if (!NodeConstants.SRV_WORKSPACE.equals(workspaceName))
+               if (!CmsConstants.SRV_WORKSPACE.equals(workspaceName))
                        throw new IllegalArgumentException(workspaceName + " is not the group workspace for group " + groupname);
        }
 
@@ -218,7 +219,7 @@ public class CmsJcrUtils {
         */
        public static String getDataPath(String cn, Node node) {
                assert node != null;
-               StringBuilder buf = new StringBuilder(NodeConstants.PATH_DATA);
+               StringBuilder buf = new StringBuilder(CmsConstants.PATH_DATA);
                try {
                        return buf.append('/').append(cn).append('/').append(node.getSession().getWorkspace().getName())
                                        .append(node.getPath()).toString();
@@ -232,20 +233,20 @@ public class CmsJcrUtils {
         * repository and the name of the workspace.
         */
        public static String getDataPath(Node node) {
-               return getDataPath(NodeConstants.NODE, node);
+               return getDataPath(CmsConstants.NODE, node);
        }
 
        /**
         * Open a JCR session with full read/write rights on the data, as
-        * {@link NodeConstants#ROLE_USER_ADMIN}, using the
-        * {@link NodeConstants#LOGIN_CONTEXT_DATA_ADMIN} login context. For security
+        * {@link CmsConstants#ROLE_USER_ADMIN}, using the
+        * {@link CmsAuth#LOGIN_CONTEXT_DATA_ADMIN} login context. For security
         * hardened deployement, use {@link AuthPermission} on this login context.
         */
        public static Session openDataAdminSession(Repository repository, String workspaceName) {
                ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
                LoginContext loginContext;
                try {
-                       loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
+                       loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_DATA_ADMIN);
                        loginContext.login();
                } catch (LoginException e1) {
                        throw new RuntimeException("Could not login as data admin", e1);
index bfbca733ef653b9751e746568158b6e34aa8e91b..50ef25e9a6726a4c4c4148081aaab856e12b20b9 100644 (file)
@@ -18,7 +18,7 @@ import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider;
@@ -35,7 +35,7 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider {
 
        @Override
        public String getScheme() {
-               return NodeConstants.SCHEME_NODE;
+               return CmsConstants.SCHEME_NODE;
        }
 
        @Override
@@ -60,7 +60,7 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider {
                                return fileSystem;
                        } else {
                                Repository repository = bc.getService(
-                                               bc.getServiceReferences(Repository.class, "(cn=" + NodeConstants.EGO_REPOSITORY + ")")
+                                               bc.getServiceReferences(Repository.class, "(cn=" + CmsConstants.EGO_REPOSITORY + ")")
                                                                .iterator().next());
 //                             Session session = repository.login();
                                CmsFileSystem fileSystem = new CmsFileSystem(this, repository);
@@ -97,7 +97,7 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider {
 
        public Node getUserHome(Repository repository) {
                try {
-                       Session session = repository.login(NodeConstants.HOME_WORKSPACE);
+                       Session session = repository.login(CmsConstants.HOME_WORKSPACE);
                        return CmsJcrUtils.getUserHome(session);
                } catch (RepositoryException e) {
                        throw new IllegalStateException("Cannot get user home", e);
index 7afa1d8d2bbc0dbd80579dfc664cad9a16a1d49d..69b98dc3a932a4457f07679b53bfec2e74c2bd57 100644 (file)
@@ -16,15 +16,14 @@ import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.EventListener;
 import javax.jcr.version.VersionManager;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.api.JackrabbitValue;
 import org.apache.jackrabbit.core.RepositoryImpl;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.jcr.JcrUtils;
 
 /** Ensure consistency of files, folder and last modified nodes. */
 class CmsWorkspaceIndexer implements EventListener {
-       private final static Log log = LogFactory.getLog(CmsWorkspaceIndexer.class);
+       private final static CmsLog log = CmsLog.getLog(CmsWorkspaceIndexer.class);
 
 //     private final static String MIX_ETAG = "mix:etag";
        private final static String JCR_ETAG = "jcr:etag";
index 3d0f3a1670bfec4542b6586c9fa27d1216e70bc5..5a790f2ea648e52f49b628be916579954472769f 100644 (file)
@@ -8,8 +8,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.osgi.DataModelNamespace;
 import org.osgi.framework.Bundle;
@@ -21,7 +20,7 @@ import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
 
 class DataModels implements BundleListener {
-       private final static Log log = LogFactory.getLog(DataModels.class);
+       private final static CmsLog log = CmsLog.getLog(DataModels.class);
 
        private Map<String, DataModel> dataModels = new TreeMap<>();
 
index 368c3ba52c84d6de37605c17a0106986f13138a1..29802509617bcc0545f4db86596dee380c491046 100644 (file)
@@ -17,7 +17,8 @@ import javax.naming.ldap.LdapName;
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jcr.JcrException;
@@ -38,19 +39,19 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
 
        private SimpleDateFormat usersDatePath = new SimpleDateFormat("YYYY/MM");
 
-       private String defaultHomeWorkspace = NodeConstants.HOME_WORKSPACE;
-       private String defaultGroupsWorkspace = NodeConstants.SRV_WORKSPACE;
+       private String defaultHomeWorkspace = CmsConstants.HOME_WORKSPACE;
+       private String defaultGroupsWorkspace = CmsConstants.SRV_WORKSPACE;
 //     private String defaultGuestsWorkspace = NodeConstants.GUESTS_WORKSPACE;
        private final boolean remote;
 
        public EgoRepository(Repository repository, boolean remote) {
                super(repository);
                this.remote = remote;
-               putDescriptor(NodeConstants.CN, NodeConstants.EGO_REPOSITORY);
+               putDescriptor(CmsConstants.CN, CmsConstants.EGO_REPOSITORY);
                if (!remote) {
                        LoginContext lc;
                        try {
-                               lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
+                               lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_DATA_ADMIN);
                                lc.login();
                        } catch (javax.security.auth.login.LoginException e1) {
                                throw new IllegalStateException("Cannot login as system", e1);
@@ -112,7 +113,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
                String username = session.getUserID();
                if (username == null || username.toString().equals(""))
                        return;
-               if (session.getUserID().equals(NodeConstants.ROLE_ANONYMOUS))
+               if (session.getUserID().equals(CmsConstants.ROLE_ANONYMOUS))
                        return;
 
                String userHomeWorkspace = getUserHomeWorkspace();
@@ -155,7 +156,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
 //             if (workspaceName != null)
 //                     return;
                // skip system users
-               if (username.endsWith(NodeConstants.ROLES_BASEDN))
+               if (username.endsWith(CmsConstants.ROLES_BASEDN))
                        return;
 
                try {
index 71e25cf8b262e4941bcb1df9969362b8eb66c799..bad9fdfd551bbb37ab36cf286f8c24d2cef59a38 100644 (file)
@@ -6,13 +6,12 @@ import java.util.TreeMap;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.core.RepositoryImpl;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 
 class JackrabbitLocalRepository extends LocalRepository {
-       private final static Log log = LogFactory.getLog(JackrabbitLocalRepository.class);
+       private final static CmsLog log = CmsLog.getLog(JackrabbitLocalRepository.class);
        final String SECURITY_WORKSPACE = "security";
 
        private Map<String, CmsWorkspaceIndexer> workspaceMonitors = new TreeMap<>();
@@ -45,7 +44,7 @@ class JackrabbitLocalRepository extends LocalRepository {
        private void addMonitor(String realWorkspaceName) {
                if (realWorkspaceName.equals(SECURITY_WORKSPACE))
                        return;
-               if (!NodeConstants.NODE_REPOSITORY.equals(getCn()))
+               if (!CmsConstants.NODE_REPOSITORY.equals(getCn()))
                        return;
 
                if (!workspaceMonitors.containsKey(realWorkspaceName)) {
index 9915fb037012f00fa714ef038d27043f45b9c231..b541b41a435a1bd7924bcf30e7236fad36772eb1 100644 (file)
@@ -26,15 +26,12 @@ import javax.jcr.Session;
 import javax.security.auth.callback.CallbackHandler;
 import javax.servlet.Servlet;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.core.RepositoryContext;
 import org.apache.jackrabbit.core.RepositoryImpl;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeDeployment;
-import org.argeo.api.security.CryptoKeyring;
-import org.argeo.api.security.Keyring;
+import org.argeo.api.cms.CmsDeployment;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.internal.jcr.JcrInitUtils;
 import org.argeo.cms.jcr.CmsJcrUtils;
@@ -42,11 +39,13 @@ import org.argeo.cms.jcr.internal.servlet.CmsRemotingServlet;
 import org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet;
 import org.argeo.cms.jcr.internal.servlet.JcrHttpUtils;
 import org.argeo.cms.osgi.DataModelNamespace;
+import org.argeo.cms.security.CryptoKeyring;
+import org.argeo.cms.security.Keyring;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
-import org.argeo.naming.LdapAttrs;
 import org.argeo.util.LangUtils;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -62,7 +61,7 @@ import org.osgi.util.tracker.ServiceTracker;
 
 /** Implementation of a CMS deployment. */
 public class JcrDeployment {
-       private final Log log = LogFactory.getLog(getClass());
+       private final CmsLog log = CmsLog.getLog(getClass());
        private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
 
        private DataModels dataModels;
@@ -73,7 +72,7 @@ public class JcrDeployment {
        // Readiness
        private boolean nodeAvailable = false;
 
-       NodeDeployment nodeDeployment;
+       CmsDeployment nodeDeployment;
 
        public JcrDeployment() {
                dataModels = new DataModels(bc);
@@ -107,7 +106,7 @@ public class JcrDeployment {
 
        }
 
-       public void setNodeDeployment(NodeDeployment nodeDeployment) {
+       public void setNodeDeployment(CmsDeployment nodeDeployment) {
                this.nodeDeployment = nodeDeployment;
        }
 
@@ -144,7 +143,7 @@ public class JcrDeployment {
 //             }
 
                // home
-               prepareDataModel(NodeConstants.NODE_REPOSITORY, deployedNodeRepository, publishAsLocalRepo);
+               prepareDataModel(CmsConstants.NODE_REPOSITORY, deployedNodeRepository, publishAsLocalRepo);
 
                // init from backup
 //             if (deployConfig.isFirstInit()) {
@@ -162,7 +161,7 @@ public class JcrDeployment {
                Collection<ServiceReference<Repository>> initRepositorySr;
                try {
                        initRepositorySr = bc.getServiceReferences(Repository.class,
-                                       "(" + NodeConstants.CN + "=" + NodeConstants.NODE_INIT + ")");
+                                       "(" + CmsConstants.CN + "=" + CmsConstants.NODE_INIT + ")");
                } catch (InvalidSyntaxException e1) {
                        throw new IllegalArgumentException(e1);
                }
@@ -241,11 +240,11 @@ public class JcrDeployment {
 
                // Publish home with the highest service ranking
                Hashtable<String, Object> regProps = new Hashtable<>();
-               regProps.put(NodeConstants.CN, NodeConstants.EGO_REPOSITORY);
+               regProps.put(CmsConstants.CN, CmsConstants.EGO_REPOSITORY);
                regProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
                Repository egoRepository = new EgoRepository(deployedRepository, false);
                bc.registerService(Repository.class, egoRepository, regProps);
-               registerRepositoryServlets(NodeConstants.EGO_REPOSITORY, egoRepository);
+               registerRepositoryServlets(CmsConstants.EGO_REPOSITORY, egoRepository);
 
                // Keyring only if Argeo extensions are available
                if (argeoDataModelExtensionsAvailable) {
@@ -257,7 +256,7 @@ public class JcrDeployment {
                                        CallbackHandler callbackHandler = bc.getService(reference);
                                        nodeKeyring.setDefaultCallbackHandler(callbackHandler);
                                        bc.registerService(LangUtils.names(Keyring.class, CryptoKeyring.class, ManagedService.class),
-                                                       nodeKeyring, LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_KEYRING_PID));
+                                                       nodeKeyring, LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_KEYRING_PID));
                                        return callbackHandler;
                                }
 
@@ -274,7 +273,7 @@ public class JcrDeployment {
                                BundleWiring wiring = bundle.adapt(BundleWiring.class);
                                if (wiring == null)
                                        continue bundles;
-                               if (NodeConstants.NODE_REPOSITORY.equals(cn))// process all data models
+                               if (CmsConstants.NODE_REPOSITORY.equals(cn))// process all data models
                                        processWiring(cn, adminSession, wiring, processed, false, publishAsLocalRepo);
                                else {
                                        List<BundleCapability> capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
@@ -348,7 +347,7 @@ public class JcrDeployment {
                boolean publishLocalRepo;
                if (isStandalone && name.equals(cn))// includes the node itself
                        publishLocalRepo = true;
-               else if (!isStandalone && cn.equals(NodeConstants.NODE_REPOSITORY))
+               else if (!isStandalone && cn.equals(CmsConstants.NODE_REPOSITORY))
                        publishLocalRepo = true;
                else
                        publishLocalRepo = false;
@@ -357,12 +356,12 @@ public class JcrDeployment {
        }
 
        boolean isStandalone(String dataModelName) {
-               return nodeDeployment.getProps(NodeConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null;
+               return nodeDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null;
        }
 
        private void publishLocalRepo(String dataModelName, Repository repository) {
                Hashtable<String, Object> properties = new Hashtable<>();
-               properties.put(NodeConstants.CN, dataModelName);
+               properties.put(CmsConstants.CN, dataModelName);
                LocalRepository localRepository;
                String[] classes;
                if (repository instanceof RepositoryImpl) {
@@ -405,14 +404,14 @@ public class JcrDeployment {
 
                ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/" + alias + "/*");
                ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
-                               "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + NodeConstants.PATH_DATA + ")");
+                               "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + CmsConstants.PATH_DATA + ")");
                bc.registerService(Servlet.class, webdavServlet, ip);
        }
 
        protected void registerRemotingServlet(String alias, Repository repository) {
                CmsRemotingServlet remotingServlet = new CmsRemotingServlet(alias, repository);
                Hashtable<String, String> ip = new Hashtable<>();
-               ip.put(NodeConstants.CN, alias);
+               ip.put(CmsConstants.CN, alias);
                // Properties ip = new Properties();
                ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
                                "/" + alias);
@@ -435,7 +434,7 @@ public class JcrDeployment {
 
                ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/" + alias + "/*");
                ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
-                               "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + NodeConstants.PATH_JCR + ")");
+                               "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + CmsConstants.PATH_JCR + ")");
                bc.registerService(Servlet.class, remotingServlet, ip);
        }
 
@@ -448,10 +447,10 @@ public class JcrDeployment {
                @Override
                public RepositoryContext addingService(ServiceReference<RepositoryContext> reference) {
                        RepositoryContext repoContext = bc.getService(reference);
-                       String cn = (String) reference.getProperty(NodeConstants.CN);
+                       String cn = (String) reference.getProperty(CmsConstants.CN);
                        if (cn != null) {
                                List<String> publishAsLocalRepo = new ArrayList<>();
-                               if (cn.equals(NodeConstants.NODE_REPOSITORY)) {
+                               if (cn.equals(CmsConstants.NODE_REPOSITORY)) {
 //                                     JackrabbitDataModelMigration.clearRepositoryCaches(repoContext.getRepositoryConfig());
                                        prepareNodeRepository(repoContext.getRepository(), publishAsLocalRepo);
                                        // TODO separate home repository
index 11a68ce24612ca55a6e4399b499dc8d9b546969f..17625f5d2d1026ee6c330b2d3ff00a8bd838bb4a 100644 (file)
@@ -26,20 +26,19 @@ import javax.jcr.Session;
 import javax.jcr.query.Query;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.security.PBEKeySpecCallback;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.ArgeoTypes;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.cms.security.AbstractKeyring;
+import org.argeo.cms.security.PBEKeySpecCallback;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 
 /** JCR based implementation of a keyring */
 public class JcrKeyring extends AbstractKeyring implements ArgeoNames {
-       private final static Log log = LogFactory.getLog(JcrKeyring.class);
+       private final static CmsLog log = CmsLog.getLog(JcrKeyring.class);
        /**
         * Stronger with 256, but causes problem with Oracle JVM, force 128 in this case
         */
@@ -96,7 +95,7 @@ public class JcrKeyring extends AbstractKeyring implements ArgeoNames {
 
        private Session login() {
                try {
-                       return repository.login(NodeConstants.HOME_WORKSPACE);
+                       return repository.login(CmsConstants.HOME_WORKSPACE);
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot login key ring session", e);
                }
index 201f3ab2878efa831b5f5aa35c884415d48a23b0..93f29fbe8fda068c825be89c35a9fbda494d8415 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.jcr.internal;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 
 /** Internal CMS constants. */
 @Deprecated
@@ -12,10 +12,10 @@ public interface KernelConstants {
        String DIR_TRANSACTIONS = "transactions";
 
        // Files
-       String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif";
-       String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".p12";
-       String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".key";
-       String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".crt";
+       String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif";
+       String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".p12";
+       String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".key";
+       String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".crt";
        String NODE_KEY_TAB_PATH = DIR_NODE + "/krb5.keytab";
 
        // Security
index ed04518c004fb312a9d67d1bb0435378d48fbdea..edfe87a032d347a57440c71c8122039e5add56e7 100644 (file)
@@ -23,8 +23,8 @@ import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.apache.commons.logging.Log;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
 import org.argeo.cms.osgi.DataModelNamespace;
 import org.osgi.framework.BundleContext;
@@ -130,7 +130,7 @@ class KernelUtils implements KernelConstants {
        // }
        // }
 
-       static void logFrameworkProperties(Log log) {
+       static void logFrameworkProperties(CmsLog log) {
                BundleContext bc = getBundleContext();
                for (Object sysProp : new TreeSet<Object>(System.getProperties().keySet())) {
                        log.debug(sysProp + "=" + bc.getProperty(sysProp.toString()));
@@ -185,7 +185,7 @@ class KernelUtils implements KernelConstants {
                Thread.currentThread().setContextClassLoader(KernelUtils.class.getClassLoader());
                LoginContext loginContext;
                try {
-                       loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
+                       loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_DATA_ADMIN);
                        loginContext.login();
                } catch (LoginException e1) {
                        throw new IllegalStateException("Could not login as data admin", e1);
index 0f95b09d9f19c2e8050b3912dab9be44653a7b27..0bac94cc09bff9adae4fec233ace4a2c6ca13817 100644 (file)
@@ -2,7 +2,7 @@ package org.argeo.cms.jcr.internal;
 
 import javax.jcr.Repository;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.jcr.JcrRepositoryWrapper;
 
 class LocalRepository extends JcrRepositoryWrapper {
@@ -13,7 +13,7 @@ class LocalRepository extends JcrRepositoryWrapper {
                this.cn = cn;
                // Map<String, Object> attrs = dataModelCapability.getAttributes();
                // cn = (String) attrs.get(DataModelNamespace.NAME);
-               putDescriptor(NodeConstants.CN, cn);
+               putDescriptor(CmsConstants.CN, cn);
        }
 
        String getCn() {
index f4feabb098c99d919357ec7990b09dc344b18fc3..a4ab7cb2323e46b2b9b4b23427d6eb160ad255f7 100644 (file)
@@ -10,10 +10,9 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.jcr.RepoConf;
 import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
 import org.osgi.framework.BundleContext;
@@ -25,7 +24,7 @@ import org.osgi.framework.ServiceReference;
  * {@link Repository} as OSGi services.
  */
 public class NodeRepositoryFactory implements RepositoryFactory {
-       private final Log log = LogFactory.getLog(getClass());
+       private final CmsLog log = CmsLog.getLog(getClass());
 //     private final BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
 
        // private Resource fileRepositoryConfiguration = new ClassPathResource(
@@ -36,7 +35,7 @@ public class NodeRepositoryFactory implements RepositoryFactory {
                if (bundleContext != null) {
                        try {
                                Collection<ServiceReference<Repository>> srs = bundleContext.getServiceReferences(Repository.class,
-                                               "(" + NodeConstants.CN + "=" + alias + ")");
+                                               "(" + CmsConstants.CN + "=" + alias + ")");
                                if (srs.size() == 0)
                                        throw new IllegalArgumentException("No repository with alias " + alias + " found in OSGi registry");
                                else if (srs.size() > 1)
@@ -75,7 +74,7 @@ public class NodeRepositoryFactory implements RepositoryFactory {
                Repository repository;
                String uri = null;
                if (parameters.containsKey(RepoConf.labeledUri.name()))
-                       uri = parameters.get(NodeConstants.LABELED_URI).toString();
+                       uri = parameters.get(CmsConstants.LABELED_URI).toString();
                else if (parameters.containsKey(KernelConstants.JACKRABBIT_REPOSITORY_URI))
                        uri = parameters.get(KernelConstants.JACKRABBIT_REPOSITORY_URI).toString();
 
@@ -94,10 +93,10 @@ public class NodeRepositoryFactory implements RepositoryFactory {
 
                }
 
-               else if (parameters.containsKey(NodeConstants.CN)) {
+               else if (parameters.containsKey(CmsConstants.CN)) {
                        // Properties properties = new Properties();
                        // properties.putAll(parameters);
-                       String alias = parameters.get(NodeConstants.CN).toString();
+                       String alias = parameters.get(CmsConstants.CN).toString();
                        // publish(alias, repository, properties);
                        // log.info("Registered JCR repository under alias '" + alias + "'
                        // with properties " + properties);
index 2a47d120cfcd99c294332b28d1499c77133c8dd2..042ddb5d58a42bde320525b56e9c7f0c6e19a90f 100644 (file)
@@ -8,10 +8,9 @@ import java.util.Map;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryFactory;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.core.RepositoryContext;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.jcr.RepoConf;
 import org.argeo.cms.internal.jcr.RepositoryBuilder;
 import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
@@ -22,7 +21,7 @@ import org.osgi.service.cm.ManagedServiceFactory;
 
 /** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */
 public class RepositoryServiceFactory implements ManagedServiceFactory {
-       private final static Log log = LogFactory.getLog(RepositoryServiceFactory.class);
+       private final static CmsLog log = CmsLog.getLog(RepositoryServiceFactory.class);
 //     private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext();
 
        private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
@@ -55,16 +54,16 @@ public class RepositoryServiceFactory implements ManagedServiceFactory {
                                Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
                                // props.put(ArgeoJcrConstants.JCR_REPOSITORY_URI,
                                // properties.get(RepoConf.labeledUri.name()));
-                               Object cn = properties.get(NodeConstants.CN);
+                               Object cn = properties.get(CmsConstants.CN);
                                if (cn != null) {
-                                       props.put(NodeConstants.CN, cn);
+                                       props.put(CmsConstants.CN, cn);
                                        // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
                                        pidToCn.put(pid, cn);
                                }
                                CmsJcrActivator.registerService(RepositoryContext.class, repositoryContext, props);
                        } else {
                                try {
-                                       Object cn = properties.get(NodeConstants.CN);
+                                       Object cn = properties.get(CmsConstants.CN);
                                        Object defaultWorkspace = properties.get(RepoConf.defaultWorkspace.name());
                                        if (defaultWorkspace == null)
                                                defaultWorkspace = RepoConf.defaultWorkspace.getDefault();
@@ -83,16 +82,16 @@ public class RepositoryServiceFactory implements ManagedServiceFactory {
                                                        new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null)
                                                                        .toString());
                                        if (cn != null) {
-                                               props.put(NodeConstants.CN, cn);
+                                               props.put(CmsConstants.CN, cn);
                                                // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
                                                pidToCn.put(pid, cn);
                                        }
                                        CmsJcrActivator.registerService(Repository.class, repository, props);
 
                                        // home
-                                       if (cn.equals(NodeConstants.NODE_REPOSITORY)) {
-                                               Dictionary<String, Object> homeProps = LangUtils.dict(NodeConstants.CN,
-                                                               NodeConstants.EGO_REPOSITORY);
+                                       if (cn.equals(CmsConstants.NODE_REPOSITORY)) {
+                                               Dictionary<String, Object> homeProps = LangUtils.dict(CmsConstants.CN,
+                                                               CmsConstants.EGO_REPOSITORY);
                                                EgoRepository homeRepository = new EgoRepository(repository, true);
                                                CmsJcrActivator.registerService(Repository.class, homeRepository, homeProps);
                                        }
index b5ec05005f9f760e2d4ec53f55201ab075eed6f4..5a2cd5b7ba582fa947a6b55ce84459a17de7c1eb 100644 (file)
@@ -3,17 +3,16 @@ package org.argeo.cms.jcr.internal;
 import java.io.File;
 import java.lang.management.ManagementFactory;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.api.stats.RepositoryStatistics;
 import org.apache.jackrabbit.stats.RepositoryStatisticsImpl;
+import org.argeo.api.cms.CmsLog;
 
 /**
  * Background thread started by the kernel, which gather statistics and
  * monitor/control other processes.
  */
 public class StatisticsThread extends Thread {
-       private final static Log log = LogFactory.getLog(StatisticsThread.class);
+       private final static CmsLog log = CmsLog.getLog(StatisticsThread.class);
 
        private RepositoryStatisticsImpl repoStats;
 
@@ -25,8 +24,8 @@ public class StatisticsThread extends Thread {
 
        private boolean running = true;
 
-       private Log kernelStatsLog = LogFactory.getLog("argeo.stats.kernel");
-       private Log nodeStatsLog = LogFactory.getLog("argeo.stats.node");
+       private CmsLog kernelStatsLog = CmsLog.getLog("argeo.stats.kernel");
+       private CmsLog nodeStatsLog = CmsLog.getLog("argeo.stats.node");
 
        @SuppressWarnings("unused")
        private long cycle = 0l;
index 1fb81b7170c53b145a34bfbc2282c9694fd8922b..677fc73dabf40b904af4f74c72ab0300795c1fd9 100644 (file)
@@ -7,7 +7,7 @@ import java.util.List;
 
 import javax.jcr.RepositoryFactory;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.jcr.internal.CmsFsProvider;
 import org.argeo.cms.jcr.internal.StatisticsThread;
 import org.argeo.cms.jcr.internal.NodeRepositoryFactory;
@@ -46,7 +46,7 @@ public class CmsJcrActivator implements BundleActivator {
                repositoryServiceFactory = new RepositoryServiceFactory();
 //             stopHooks.add(() -> repositoryServiceFactory.shutdown());
                registerService(ManagedServiceFactory.class, repositoryServiceFactory,
-                               LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID));
+                               LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_REPOS_FACTORY_PID));
 
                NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory();
                registerService(RepositoryFactory.class, repositoryFactory, null);
@@ -64,7 +64,7 @@ public class CmsJcrActivator implements BundleActivator {
 //                     log.debug("Installed FileSystemProvider " + fsp);
 //             }
                registerService(FileSystemProvider.class, cmsFsProvider,
-                               LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_FS_PROVIDER_PID));
+                               LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_FS_PROVIDER_PID));
 
 //             jcrDeployment = new JcrDeployment();
 //             jcrDeployment.init();
index 9296203152c2129cea8aa351b6dc36ea6778cdaa..fa3f87f6739f1e3c2803dda54d2b69d130b380c9 100644 (file)
@@ -6,7 +6,7 @@ import javax.jcr.Repository;
 
 import org.apache.jackrabbit.server.SessionProvider;
 import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 
 /** A {@link JcrRemotingServlet} based on {@link CmsSessionProvider}. */
 public class CmsRemotingServlet extends JcrRemotingServlet {
@@ -29,7 +29,7 @@ public class CmsRemotingServlet extends JcrRemotingServlet {
 
        public void setRepository(Repository repository, Map<String, String> properties) {
                this.repository = repository;
-               String alias = properties.get(NodeConstants.CN);
+               String alias = properties.get(CmsConstants.CN);
                if (alias != null)
                        sessionProvider = new CmsSessionProvider(alias);
                else
index 45ca33855aea86772d918b3748c17a83d593557f..0f27fd005dca58aa2f17eea8d95ed59f40702159 100644 (file)
@@ -16,11 +16,10 @@ import javax.security.auth.Subject;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.jcr.JcrUtils;
 
 /**
@@ -30,7 +29,7 @@ import org.argeo.jcr.JcrUtils;
 public class CmsSessionProvider implements SessionProvider, Serializable {
        private static final long serialVersionUID = -1358136599534938466L;
 
-       private final static Log log = LogFactory.getLog(CmsSessionProvider.class);
+       private final static CmsLog log = CmsLog.getLog(CmsSessionProvider.class);
 
        private final String alias;
 
@@ -92,7 +91,7 @@ public class CmsSessionProvider implements SessionProvider, Serializable {
                        checkValid();
                        // FIXME make it more robust
                        if (workspace == null)
-                               workspace = NodeConstants.SYS_WORKSPACE;
+                               workspace = CmsConstants.SYS_WORKSPACE;
                        String path = cn + '/' + workspace;
                        if (dataSessionsInUse.contains(path)) {
                                try {
index 1557c4bc1ab085d638abeb8c84066366d096638e..0f0858f51776d5c0e1d512087434410381161b71 100644 (file)
@@ -5,7 +5,7 @@ import java.util.Map;
 import javax.jcr.Repository;
 
 import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 
 /** A {@link SimpleWebdavServlet} based on {@link CmsSessionProvider}. */
 public class CmsWebDavServlet extends SimpleWebdavServlet {
@@ -27,7 +27,7 @@ public class CmsWebDavServlet extends SimpleWebdavServlet {
 
        public void setRepository(Repository repository, Map<String, String> properties) {
                this.repository = repository;
-               String alias = properties.get(NodeConstants.CN);
+               String alias = properties.get(CmsConstants.CN);
                if (alias != null)
                        setSessionProvider(new CmsSessionProvider(alias));
                else
index c2746126adca12b71abb2477846e4825c63469d2..11e903db86138a18ec123fb5d71c183ce432f9a3 100644 (file)
@@ -5,7 +5,7 @@ import java.util.Enumeration;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.logging.Log;
+import org.argeo.api.cms.CmsLog;
 
 public class JcrHttpUtils {
        public final static String HEADER_AUTHORIZATION = "Authorization";
@@ -20,7 +20,7 @@ public class JcrHttpUtils {
                                || userAgent.contains("opera") || userAgent.contains("browser");
        }
 
-       public static void logResponseHeaders(Log log, HttpServletResponse response) {
+       public static void logResponseHeaders(CmsLog log, HttpServletResponse response) {
                if (!log.isDebugEnabled())
                        return;
                for (String headerName : response.getHeaderNames()) {
@@ -29,7 +29,7 @@ public class JcrHttpUtils {
                }
        }
 
-       public static void logRequestHeaders(Log log, HttpServletRequest request) {
+       public static void logRequestHeaders(CmsLog log, HttpServletRequest request) {
                if (!log.isDebugEnabled())
                        return;
                for (Enumeration<String> headerNames = request.getHeaderNames(); headerNames.hasMoreElements();) {
@@ -40,7 +40,7 @@ public class JcrHttpUtils {
                log.debug(request.getRequestURI() + "\n");
        }
 
-       public static void logRequest(Log log, HttpServletRequest request) {
+       public static void logRequest(CmsLog log, HttpServletRequest request) {
                log.debug("contextPath=" + request.getContextPath());
                log.debug("servletPath=" + request.getServletPath());
                log.debug("requestURI=" + request.getRequestURI());
index feaa00f303b18835afa7d87d0984d335749f82f9..62cdc5f6b08d92ce58fdc60e1d76193cbed9100d 100644 (file)
@@ -25,7 +25,8 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jcr.JcrUtils;
@@ -88,7 +89,7 @@ public class LinkServlet extends HttpServlet {
                                @Override
                                public Session run() throws Exception {
                                        Collection<ServiceReference<Repository>> srs = bc.getServiceReferences(Repository.class,
-                                                       "(" + NodeConstants.CN + "=" + NodeConstants.EGO_REPOSITORY + ")");
+                                                       "(" + CmsConstants.CN + "=" + CmsConstants.EGO_REPOSITORY + ")");
                                        Repository repository = bc.getService(srs.iterator().next());
                                        return repository.login();
                                }
@@ -196,7 +197,7 @@ public class LinkServlet extends HttpServlet {
        private String getDataUrl(Node node, HttpServletRequest request) throws RepositoryException {
                try {
                        StringBuilder buf = getServerBaseUrl(request);
-                       buf.append(CmsJcrUtils.getDataPath(NodeConstants.EGO_REPOSITORY, node));
+                       buf.append(CmsJcrUtils.getDataPath(CmsConstants.EGO_REPOSITORY, node));
                        return new URL(buf.toString()).toString();
                } catch (MalformedURLException e) {
                        throw new CmsException("Cannot build data URL for " + node, e);
@@ -247,7 +248,7 @@ public class LinkServlet extends HttpServlet {
                Subject subject = new Subject();
                LoginContext lc;
                try {
-                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, subject);
+                       lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS, subject);
                        lc.login();
                        return subject;
                } catch (LoginException e) {
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java
new file mode 100644 (file)
index 0000000..ccd543f
--- /dev/null
@@ -0,0 +1,23 @@
+package org.argeo.cms.jcr.tabular;
+
+import java.io.OutputStream;
+
+import org.argeo.cms.tabular.TabularWriter;
+import org.argeo.util.CsvWriter;
+
+/** Write tabular content in a stream as CSV. Wraps a {@link CsvWriter}. */
+public class CsvTabularWriter implements TabularWriter {
+       private CsvWriter csvWriter;
+
+       public CsvTabularWriter(OutputStream out) {
+               this.csvWriter = new CsvWriter(out);
+       }
+
+       public void appendRow(Object[] row) {
+               csvWriter.writeLine(row);
+       }
+
+       public void close() {
+       }
+
+}
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java
new file mode 100644 (file)
index 0000000..d1d9b58
--- /dev/null
@@ -0,0 +1,170 @@
+package org.argeo.cms.jcr.tabular;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.cms.ArgeoTypes;
+import org.argeo.cms.tabular.ArrayTabularRow;
+import org.argeo.cms.tabular.TabularColumn;
+import org.argeo.cms.tabular.TabularRow;
+import org.argeo.cms.tabular.TabularRowIterator;
+import org.argeo.jcr.JcrException;
+import org.argeo.util.CsvParser;
+
+/** Iterates over the rows of a {@link ArgeoTypes#ARGEO_TABLE} node. */
+public class JcrTabularRowIterator implements TabularRowIterator {
+       private Boolean hasNext = null;
+       private Boolean parsingCompleted = false;
+
+       private Long currentRowNumber = 0l;
+
+       private List<TabularColumn> header = new ArrayList<TabularColumn>();
+
+       /** referenced so that we can close it */
+       private Binary binary;
+       private InputStream in;
+
+       private CsvParser csvParser;
+       private ArrayBlockingQueue<List<String>> textLines;
+
+       public JcrTabularRowIterator(Node tableNode) {
+               try {
+                       for (NodeIterator it = tableNode.getNodes(); it.hasNext();) {
+                               Node node = it.nextNode();
+                               if (node.isNodeType(ArgeoTypes.ARGEO_COLUMN)) {
+                                       Integer type = PropertyType.valueFromName(node.getProperty(
+                                                       Property.JCR_REQUIRED_TYPE).getString());
+                                       TabularColumn tc = new TabularColumn(node.getProperty(
+                                                       Property.JCR_TITLE).getString(), type);
+                                       header.add(tc);
+                               }
+                       }
+                       Node contentNode = tableNode.getNode(Property.JCR_CONTENT);
+                       if (contentNode.isNodeType(ArgeoTypes.ARGEO_CSV)) {
+                               textLines = new ArrayBlockingQueue<List<String>>(1000);
+                               csvParser = new CsvParser() {
+                                       protected void processLine(Integer lineNumber,
+                                                       List<String> header, List<String> tokens) {
+                                               try {
+                                                       textLines.put(tokens);
+                                               } catch (InterruptedException e) {
+                                                       // TODO Auto-generated catch block
+                                                       e.printStackTrace();
+                                               }
+                                               // textLines.add(tokens);
+                                               if (hasNext == null) {
+                                                       hasNext = true;
+                                                       synchronized (JcrTabularRowIterator.this) {
+                                                               JcrTabularRowIterator.this.notifyAll();
+                                                       }
+                                               }
+                                       }
+                               };
+                               csvParser.setNoHeader(true);
+                               binary = contentNode.getProperty(Property.JCR_DATA).getBinary();
+                               in = binary.getStream();
+                               Thread thread = new Thread(contentNode.getPath() + " reader") {
+                                       public void run() {
+                                               try {
+                                                       csvParser.parse(in);
+                                               } finally {
+                                                       parsingCompleted = true;
+                                                       IOUtils.closeQuietly(in);
+                                               }
+                                       }
+                               };
+                               thread.start();
+                       }
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot read table " + tableNode, e);
+               }
+       }
+
+       public synchronized boolean hasNext() {
+               // we don't know if there is anything available
+               // while (hasNext == null)
+               // try {
+               // wait();
+               // } catch (InterruptedException e) {
+               // // silent
+               // // FIXME better deal with interruption
+               // Thread.currentThread().interrupt();
+               // break;
+               // }
+
+               // buffer not empty
+               if (!textLines.isEmpty())
+                       return true;
+
+               // maybe the parsing is finished but the flag has not been set
+               while (!parsingCompleted && textLines.isEmpty())
+                       try {
+                               wait(100);
+                       } catch (InterruptedException e) {
+                               // silent
+                               // FIXME better deal with interruption
+                               Thread.currentThread().interrupt();
+                               break;
+                       }
+
+               // buffer not empty
+               if (!textLines.isEmpty())
+                       return true;
+
+               // (parsingCompleted && textLines.isEmpty())
+               return false;
+
+               // if (!hasNext && textLines.isEmpty()) {
+               // if (in != null) {
+               // IOUtils.closeQuietly(in);
+               // in = null;
+               // }
+               // if (binary != null) {
+               // JcrUtils.closeQuietly(binary);
+               // binary = null;
+               // }
+               // return false;
+               // } else
+               // return true;
+       }
+
+       public synchronized TabularRow next() {
+               try {
+                       List<String> tokens = textLines.take();
+                       List<Object> objs = new ArrayList<Object>(tokens.size());
+                       for (String token : tokens) {
+                               // TODO convert to other formats using header
+                               objs.add(token);
+                       }
+                       currentRowNumber++;
+                       return new ArrayTabularRow(objs);
+               } catch (InterruptedException e) {
+                       // silent
+                       // FIXME better deal with interruption
+               }
+               return null;
+       }
+
+       public void remove() {
+               throw new UnsupportedOperationException();
+       }
+
+       public Long getCurrentRowNumber() {
+               return currentRowNumber;
+       }
+
+       public List<TabularColumn> getHeader() {
+               return header;
+       }
+
+}
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java
new file mode 100644 (file)
index 0000000..cc3e0d7
--- /dev/null
@@ -0,0 +1,82 @@
+package org.argeo.cms.jcr.tabular;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.List;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.cms.ArgeoTypes;
+import org.argeo.cms.tabular.TabularColumn;
+import org.argeo.cms.tabular.TabularWriter;
+import org.argeo.jcr.JcrException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.util.CsvWriter;
+
+/** Write / reference tabular content in a JCR repository. */
+public class JcrTabularWriter implements TabularWriter {
+       private Node contentNode;
+       private ByteArrayOutputStream out;
+       private CsvWriter csvWriter;
+       
+       @SuppressWarnings("unused")
+       private final List<TabularColumn> columns;
+
+       /** Creates a table node */
+       public JcrTabularWriter(Node tableNode, List<TabularColumn> columns,
+                       String contentNodeType) {
+               try {
+                       this.columns = columns;
+                       for (TabularColumn column : columns) {
+                               String normalized = JcrUtils.replaceInvalidChars(column
+                                               .getName());
+                               Node columnNode = tableNode.addNode(normalized,
+                                               ArgeoTypes.ARGEO_COLUMN);
+                               columnNode.setProperty(Property.JCR_TITLE, column.getName());
+                               if (column.getType() != null)
+                                       columnNode.setProperty(Property.JCR_REQUIRED_TYPE,
+                                                       PropertyType.nameFromValue(column.getType()));
+                               else
+                                       columnNode.setProperty(Property.JCR_REQUIRED_TYPE,
+                                                       PropertyType.TYPENAME_STRING);
+                       }
+                       contentNode = tableNode.addNode(Property.JCR_CONTENT,
+                                       contentNodeType);
+                       if (contentNodeType.equals(ArgeoTypes.ARGEO_CSV)) {
+                               contentNode.setProperty(Property.JCR_MIMETYPE, "text/csv");
+                               contentNode.setProperty(Property.JCR_ENCODING, "UTF-8");
+                               out = new ByteArrayOutputStream();
+                               csvWriter = new CsvWriter(out);
+                       }
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot create table node " + tableNode, e);
+               }
+       }
+
+       public void appendRow(Object[] row) {
+               csvWriter.writeLine(row);
+       }
+
+       public void close() {
+               Binary binary = null;
+               InputStream in = null;
+               try {
+                       // TODO parallelize with pipes and writing from another thread
+                       in = new ByteArrayInputStream(out.toByteArray());
+                       binary = contentNode.getSession().getValueFactory()
+                                       .createBinary(in);
+                       contentNode.setProperty(Property.JCR_DATA, binary);
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot store data in " + contentNode, e);
+               } finally {
+                       IOUtils.closeQuietly(in);
+                       JcrUtils.closeQuietly(binary);
+               }
+       }
+}
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java
new file mode 100644 (file)
index 0000000..506a6ac
--- /dev/null
@@ -0,0 +1,2 @@
+/** Argeo CMS implementation of the Argeo Tabular API (CSV, JCR). */
+package org.argeo.cms.jcr.tabular;
\ No newline at end of file
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/CsvTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/CsvTabularWriter.java
deleted file mode 100644 (file)
index 6f78672..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.argeo.cms.tabular;
-
-import java.io.OutputStream;
-
-import org.argeo.api.tabular.TabularWriter;
-import org.argeo.util.CsvWriter;
-
-/** Write tabular content in a stream as CSV. Wraps a {@link CsvWriter}. */
-public class CsvTabularWriter implements TabularWriter {
-       private CsvWriter csvWriter;
-
-       public CsvTabularWriter(OutputStream out) {
-               this.csvWriter = new CsvWriter(out);
-       }
-
-       public void appendRow(Object[] row) {
-               csvWriter.writeLine(row);
-       }
-
-       public void close() {
-       }
-
-}
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularRowIterator.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularRowIterator.java
deleted file mode 100644 (file)
index 23bc8e8..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-package org.argeo.cms.tabular;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ArrayBlockingQueue;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.api.tabular.ArrayTabularRow;
-import org.argeo.api.tabular.TabularColumn;
-import org.argeo.api.tabular.TabularRow;
-import org.argeo.api.tabular.TabularRowIterator;
-import org.argeo.cms.ArgeoTypes;
-import org.argeo.jcr.JcrException;
-import org.argeo.util.CsvParser;
-
-/** Iterates over the rows of a {@link ArgeoTypes#ARGEO_TABLE} node. */
-public class JcrTabularRowIterator implements TabularRowIterator {
-       private Boolean hasNext = null;
-       private Boolean parsingCompleted = false;
-
-       private Long currentRowNumber = 0l;
-
-       private List<TabularColumn> header = new ArrayList<TabularColumn>();
-
-       /** referenced so that we can close it */
-       private Binary binary;
-       private InputStream in;
-
-       private CsvParser csvParser;
-       private ArrayBlockingQueue<List<String>> textLines;
-
-       public JcrTabularRowIterator(Node tableNode) {
-               try {
-                       for (NodeIterator it = tableNode.getNodes(); it.hasNext();) {
-                               Node node = it.nextNode();
-                               if (node.isNodeType(ArgeoTypes.ARGEO_COLUMN)) {
-                                       Integer type = PropertyType.valueFromName(node.getProperty(
-                                                       Property.JCR_REQUIRED_TYPE).getString());
-                                       TabularColumn tc = new TabularColumn(node.getProperty(
-                                                       Property.JCR_TITLE).getString(), type);
-                                       header.add(tc);
-                               }
-                       }
-                       Node contentNode = tableNode.getNode(Property.JCR_CONTENT);
-                       if (contentNode.isNodeType(ArgeoTypes.ARGEO_CSV)) {
-                               textLines = new ArrayBlockingQueue<List<String>>(1000);
-                               csvParser = new CsvParser() {
-                                       protected void processLine(Integer lineNumber,
-                                                       List<String> header, List<String> tokens) {
-                                               try {
-                                                       textLines.put(tokens);
-                                               } catch (InterruptedException e) {
-                                                       // TODO Auto-generated catch block
-                                                       e.printStackTrace();
-                                               }
-                                               // textLines.add(tokens);
-                                               if (hasNext == null) {
-                                                       hasNext = true;
-                                                       synchronized (JcrTabularRowIterator.this) {
-                                                               JcrTabularRowIterator.this.notifyAll();
-                                                       }
-                                               }
-                                       }
-                               };
-                               csvParser.setNoHeader(true);
-                               binary = contentNode.getProperty(Property.JCR_DATA).getBinary();
-                               in = binary.getStream();
-                               Thread thread = new Thread(contentNode.getPath() + " reader") {
-                                       public void run() {
-                                               try {
-                                                       csvParser.parse(in);
-                                               } finally {
-                                                       parsingCompleted = true;
-                                                       IOUtils.closeQuietly(in);
-                                               }
-                                       }
-                               };
-                               thread.start();
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot read table " + tableNode, e);
-               }
-       }
-
-       public synchronized boolean hasNext() {
-               // we don't know if there is anything available
-               // while (hasNext == null)
-               // try {
-               // wait();
-               // } catch (InterruptedException e) {
-               // // silent
-               // // FIXME better deal with interruption
-               // Thread.currentThread().interrupt();
-               // break;
-               // }
-
-               // buffer not empty
-               if (!textLines.isEmpty())
-                       return true;
-
-               // maybe the parsing is finished but the flag has not been set
-               while (!parsingCompleted && textLines.isEmpty())
-                       try {
-                               wait(100);
-                       } catch (InterruptedException e) {
-                               // silent
-                               // FIXME better deal with interruption
-                               Thread.currentThread().interrupt();
-                               break;
-                       }
-
-               // buffer not empty
-               if (!textLines.isEmpty())
-                       return true;
-
-               // (parsingCompleted && textLines.isEmpty())
-               return false;
-
-               // if (!hasNext && textLines.isEmpty()) {
-               // if (in != null) {
-               // IOUtils.closeQuietly(in);
-               // in = null;
-               // }
-               // if (binary != null) {
-               // JcrUtils.closeQuietly(binary);
-               // binary = null;
-               // }
-               // return false;
-               // } else
-               // return true;
-       }
-
-       public synchronized TabularRow next() {
-               try {
-                       List<String> tokens = textLines.take();
-                       List<Object> objs = new ArrayList<Object>(tokens.size());
-                       for (String token : tokens) {
-                               // TODO convert to other formats using header
-                               objs.add(token);
-                       }
-                       currentRowNumber++;
-                       return new ArrayTabularRow(objs);
-               } catch (InterruptedException e) {
-                       // silent
-                       // FIXME better deal with interruption
-               }
-               return null;
-       }
-
-       public void remove() {
-               throw new UnsupportedOperationException();
-       }
-
-       public Long getCurrentRowNumber() {
-               return currentRowNumber;
-       }
-
-       public List<TabularColumn> getHeader() {
-               return header;
-       }
-
-}
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularWriter.java
deleted file mode 100644 (file)
index 29933cd..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.argeo.cms.tabular;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.util.List;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.api.tabular.TabularColumn;
-import org.argeo.api.tabular.TabularWriter;
-import org.argeo.cms.ArgeoTypes;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.util.CsvWriter;
-
-/** Write / reference tabular content in a JCR repository. */
-public class JcrTabularWriter implements TabularWriter {
-       private Node contentNode;
-       private ByteArrayOutputStream out;
-       private CsvWriter csvWriter;
-       
-       @SuppressWarnings("unused")
-       private final List<TabularColumn> columns;
-
-       /** Creates a table node */
-       public JcrTabularWriter(Node tableNode, List<TabularColumn> columns,
-                       String contentNodeType) {
-               try {
-                       this.columns = columns;
-                       for (TabularColumn column : columns) {
-                               String normalized = JcrUtils.replaceInvalidChars(column
-                                               .getName());
-                               Node columnNode = tableNode.addNode(normalized,
-                                               ArgeoTypes.ARGEO_COLUMN);
-                               columnNode.setProperty(Property.JCR_TITLE, column.getName());
-                               if (column.getType() != null)
-                                       columnNode.setProperty(Property.JCR_REQUIRED_TYPE,
-                                                       PropertyType.nameFromValue(column.getType()));
-                               else
-                                       columnNode.setProperty(Property.JCR_REQUIRED_TYPE,
-                                                       PropertyType.TYPENAME_STRING);
-                       }
-                       contentNode = tableNode.addNode(Property.JCR_CONTENT,
-                                       contentNodeType);
-                       if (contentNodeType.equals(ArgeoTypes.ARGEO_CSV)) {
-                               contentNode.setProperty(Property.JCR_MIMETYPE, "text/csv");
-                               contentNode.setProperty(Property.JCR_ENCODING, "UTF-8");
-                               out = new ByteArrayOutputStream();
-                               csvWriter = new CsvWriter(out);
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot create table node " + tableNode, e);
-               }
-       }
-
-       public void appendRow(Object[] row) {
-               csvWriter.writeLine(row);
-       }
-
-       public void close() {
-               Binary binary = null;
-               InputStream in = null;
-               try {
-                       // TODO parallelize with pipes and writing from another thread
-                       in = new ByteArrayInputStream(out.toByteArray());
-                       binary = contentNode.getSession().getValueFactory()
-                                       .createBinary(in);
-                       contentNode.setProperty(Property.JCR_DATA, binary);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot store data in " + contentNode, e);
-               } finally {
-                       IOUtils.closeQuietly(in);
-                       JcrUtils.closeQuietly(binary);
-               }
-       }
-}
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/package-info.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/package-info.java
deleted file mode 100644 (file)
index a95d866..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Argeo CMS implementation of the Argeo Tabular API (CSV, JCR). */
-package org.argeo.cms.tabular;
\ No newline at end of file
index 1a4c8a3ca724d24aec2b41f9c81a926f9c406eed..8c267e314551948d5087ffc359f20869d8d73c95 100644 (file)
@@ -9,12 +9,11 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.commons.cnd.ParseException;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
 import org.apache.jackrabbit.core.fs.FileSystemException;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.jcr.JcrCallback;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
@@ -22,7 +21,7 @@ import org.argeo.jcr.JcrUtils;
 /** Migrate the data in a Jackrabbit repository. */
 @Deprecated
 public class JackrabbitDataModelMigration implements Comparable<JackrabbitDataModelMigration> {
-       private final static Log log = LogFactory.getLog(JackrabbitDataModelMigration.class);
+       private final static CmsLog log = CmsLog.getLog(JackrabbitDataModelMigration.class);
 
        private String dataModelNodePath;
        private String targetVersion;
index a75c7954115cbc3991675588e9491cc10d7c10a7..f98cf99473a115f2a7561ded2d83d970be5897d5 100644 (file)
@@ -8,15 +8,14 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.security.Privilege;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.jcr.JcrUtils;
 
 /** Utilities around Jackrabbit security extensions. */
 public class JackrabbitSecurityUtils {
-       private final static Log log = LogFactory.getLog(JackrabbitSecurityUtils.class);
+       private final static CmsLog log = CmsLog.getLog(JackrabbitSecurityUtils.class);
 
        /**
         * Convenience method for denying a single privilege to a principal (user or
index fc6888851f31b3f39cb4c42a0ee6b90337154f76..d873ef6521b1f12172dac256bc7044acfe27b9bf 100644 (file)
@@ -7,12 +7,11 @@ import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.EventListener;
 import javax.jcr.observation.ObservationManager;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 
 /** To be overridden */
 public class DefaultJcrListener implements EventListener {
-       private final static Log log = LogFactory.getLog(DefaultJcrListener.class);
+       private final static CmsLog log = CmsLog.getLog(DefaultJcrListener.class);
        private Session session;
        private String path = "/";
        private Boolean deep = true;
index 1e23338b54660816148c68f546e5594958d01fb5..2208627ab80df1b1ee2469057d12e08c1d4aab5d 100644 (file)
@@ -17,13 +17,12 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 
 /** Proxy JCR sessions and attach them to calling threads. */
 @Deprecated
 public abstract class ThreadBoundJcrSessionFactory {
-       private final static Log log = LogFactory.getLog(ThreadBoundJcrSessionFactory.class);
+       private final static CmsLog log = CmsLog.getLog(ThreadBoundJcrSessionFactory.class);
 
        private Repository repository;
        /** can be injected as list, only used if repository is null */
index 0984276ddbb90c810d824fde99e3082e81560c17..0177636f8da910c6e94eebfc611e6e739c1e0427 100644 (file)
@@ -12,14 +12,13 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 
 /** Base class for URL based proxys. */
 public abstract class AbstractUrlProxy implements ResourceProxy {
-       private final static Log log = LogFactory.getLog(AbstractUrlProxy.class);
+       private final static CmsLog log = CmsLog.getLog(AbstractUrlProxy.class);
 
        private Repository jcrRepository;
        private Session jcrAdminSession;
index d77bd49dca21fed2b7e2e1e827723fe4ba3055c2..a8e00df601ab0f8b3f51018c0c8db41d58a78d13 100644 (file)
@@ -13,9 +13,8 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.jcr.JcrException;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.jcr.Bin;
 import org.argeo.jcr.JcrUtils;
 
@@ -23,7 +22,7 @@ import org.argeo.jcr.JcrUtils;
 public class ResourceProxyServlet extends HttpServlet {
        private static final long serialVersionUID = -8886549549223155801L;
 
-       private final static Log log = LogFactory
+       private final static CmsLog log = CmsLog
                        .getLog(ResourceProxyServlet.class);
 
        private ResourceProxy proxy;
index dc2963a51e73d9ac90db61d30a5c7dcb9bfc0a73..84e8cd31a3d99814c2ec4fed5dc582336e863ae8 100644 (file)
@@ -13,15 +13,14 @@ import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.jcr.JcrException;
 
 import junit.framework.TestCase;
 
 /** Base for unit tests with a JCR repository. */
 public abstract class AbstractJcrTestCase extends TestCase {
-       private final static Log log = LogFactory.getLog(AbstractJcrTestCase.class);
+       private final static CmsLog log = CmsLog.getLog(AbstractJcrTestCase.class);
 
        private Repository repository;
        private Session session = null;
index 804ab975886b9f211a4f800081fafea55d6a69e7..3c8f296c4c9243b9b9a0ce7ebfe297744b669ffd 100644 (file)
@@ -10,20 +10,19 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrUtils;
-import org.argeo.naming.Distinguished;
 import org.argeo.osgi.transaction.WorkTransaction;
+import org.argeo.util.naming.Distinguished;
 import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.UserAdmin;
 
 /** Make sure roles and access rights are properly configured. */
 public abstract class AbstractMaintenanceService {
-       private final static Log log = LogFactory.getLog(AbstractMaintenanceService.class);
+       private final static CmsLog log = CmsLog.getLog(AbstractMaintenanceService.class);
 
        private Repository repository;
 //     private UserAdminService userAdminService;
index 07dc3998569025c88c99e32026ee6e089e216283..ebb8c534da0e125220216012cad35331430496f9 100644 (file)
@@ -7,8 +7,7 @@ import java.util.Map;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.osgi.transaction.WorkTransaction;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.UserAdmin;
@@ -18,7 +17,7 @@ import org.osgi.service.useradmin.UserAdmin;
  * is already registered.
  */
 public class SimpleRoleRegistration implements Runnable {
-       private final static Log log = LogFactory.getLog(SimpleRoleRegistration.class);
+       private final static CmsLog log = CmsLog.getLog(SimpleRoleRegistration.class);
 
        private String role;
        private List<String> roles = new ArrayList<String>();
index c2a3582e79c5ed774807bee80e3ed8b4695a8943..00d4be8b0e464807bea727de61b778ac1474321c 100644 (file)
@@ -41,11 +41,10 @@ import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.api.JackrabbitSession;
 import org.apache.jackrabbit.api.JackrabbitValue;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
 import org.argeo.jcr.Jcr;
@@ -61,7 +60,7 @@ import org.osgi.framework.BundleContext;
  * recovery.
  */
 public class LogicalBackup implements Runnable {
-       private final static Log log = LogFactory.getLog(LogicalBackup.class);
+       private final static CmsLog log = CmsLog.getLog(LogicalBackup.class);
 
        public final static String WORKSPACES_BASE = "workspaces/";
        public final static String FILES_BASE = "files/";
@@ -369,7 +368,7 @@ public class LogicalBackup implements Runnable {
                Map<String, String> params = new HashMap<String, String>();
                params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString());
                // TODO make it configurable
-               params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, NodeConstants.SYS_WORKSPACE);
+               params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, CmsConstants.SYS_WORKSPACE);
                return repositoryFactory.getRepository(params);
        }
 
index 057a126106d72064c2ba458521f6cbe1e70dd815..122c967014dcf7cc34ccd41c82123f894bbd514b 100644 (file)
@@ -11,9 +11,8 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrException;
@@ -22,7 +21,7 @@ import org.osgi.framework.BundleContext;
 
 /** Restores a backup in the format defined by {@link LogicalBackup}. */
 public class LogicalRestore implements Runnable {
-       private final static Log log = LogFactory.getLog(LogicalRestore.class);
+       private final static CmsLog log = CmsLog.getLog(LogicalRestore.class);
 
        private final Repository repository;
        private final BundleContext bundleContext;
index 4b59453777de418830a22e3e4dd923de9f629c14..36ee547e5849527f40bfe13505ddf6e2f6b0ed14 100644 (file)
@@ -13,8 +13,6 @@ import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.x500.X500Principal;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.core.DefaultSecurityManager;
 import org.apache.jackrabbit.core.security.AMContext;
@@ -26,17 +24,18 @@ import org.apache.jackrabbit.core.security.authentication.CallbackHandlerImpl;
 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
 import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsSession;
-import org.argeo.api.security.AnonymousPrincipal;
-import org.argeo.api.security.DataAdminPrincipal;
+import org.argeo.api.cms.DataAdminPrincipal;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.AnonymousPrincipal;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.osgi.CmsOsgiUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 
 /** Customises Jackrabbit security. */
 public class ArgeoSecurityManager extends DefaultSecurityManager {
-       private final static Log log = LogFactory.getLog(ArgeoSecurityManager.class);
+       private final static CmsLog log = CmsLog.getLog(ArgeoSecurityManager.class);
 
        private BundleContext cmsBundleContext = null;
 
@@ -94,7 +93,7 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                        if (isDataAdmin || isJackrabbitSystem || isRegularUser)
                                throw new IllegalStateException("Inconsistent " + subject);
                        else
-                               return NodeConstants.ROLE_ANONYMOUS;
+                               return CmsConstants.ROLE_ANONYMOUS;
                } else if (isRegularUser) {// must be before DataAdmin
                        if (isAnonymous || isJackrabbitSystem)
                                throw new IllegalStateException("Inconsistent " + subject);
@@ -112,7 +111,7 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                                throw new IllegalStateException("Inconsistent " + subject);
                        else {
                                assert !subject.getPrincipals(AdminPrincipal.class).isEmpty();
-                               return NodeConstants.ROLE_DATA_ADMIN;
+                               return CmsConstants.ROLE_DATA_ADMIN;
                        }
                } else if (isJackrabbitSystem) {
                        if (isAnonymous || isDataAdmin || isRegularUser)
index 9c70e9b722ad57fea014c2648bf191120f2994cd..0f63957b7ed39b2197365f101dac37b7b2e39c06 100644 (file)
@@ -12,7 +12,7 @@ import javax.security.auth.x500.X500Principal;
 import org.apache.jackrabbit.core.security.AnonymousPrincipal;
 import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
-import org.argeo.api.security.DataAdminPrincipal;
+import org.argeo.api.cms.DataAdminPrincipal;
 
 /** JAAS login module used when initiating a new Jackrabbit session. */
 public class SystemJackrabbitLoginModule implements LoginModule {
@@ -31,8 +31,8 @@ public class SystemJackrabbitLoginModule implements LoginModule {
 
        @Override
        public boolean commit() throws LoginException {
-               Set<org.argeo.api.security.AnonymousPrincipal> anonPrincipal = subject
-                               .getPrincipals(org.argeo.api.security.AnonymousPrincipal.class);
+               Set<org.argeo.api.cms.AnonymousPrincipal> anonPrincipal = subject
+                               .getPrincipals(org.argeo.api.cms.AnonymousPrincipal.class);
                if (!anonPrincipal.isEmpty()) {
                        subject.getPrincipals().add(new AnonymousPrincipal());
                        return true;
index 011cbd6a3045b7c0dbd79c41870599b66c6b1a87..14575ada8c156fff61154661d234ad9dcefcea7d 100644 (file)
@@ -3,7 +3,6 @@ org.osgi.service.http;version=0.0.0,\
 org.osgi.service.http.whiteboard;version=0.0.0,\
 org.osgi.framework.namespace;version=0.0.0,\
 org.argeo.cms.osgi,\
-org.argeo.api,\
 *
 
 Service-Component:\
index ba19d0d5fd7a1325b56fac78069321fd6416bb10..40404c5d45d44eb70b675ee045acf2aee0674c1f 100644 (file)
@@ -11,9 +11,8 @@ import javax.security.auth.login.LoginException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.auth.RemoteAuthCallbackHandler;
 import org.argeo.cms.auth.RemoteAuthUtils;
 import org.argeo.cms.servlet.internal.HttpUtils;
@@ -26,7 +25,7 @@ import org.osgi.service.http.context.ServletContextHelper;
  * pre-authenticated.
  */
 public class CmsServletContext extends ServletContextHelper {
-       private final static Log log = LogFactory.getLog(CmsServletContext.class);
+       private final static CmsLog log = CmsLog.getLog(CmsServletContext.class);
        // use CMS bundle for resources
        private Bundle bundle = FrameworkUtil.getBundle(getClass());
 
@@ -44,7 +43,7 @@ public class CmsServletContext extends ServletContextHelper {
                        HttpUtils.logRequestHeaders(log, request);
                LoginContext lc;
                try {
-                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
+                       lc = CmsAuth.USER.newLoginContext(
                                        new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response)));
                        lc.login();
                } catch (LoginException e) {
@@ -78,7 +77,7 @@ public class CmsServletContext extends ServletContextHelper {
        protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) {
                // anonymous
                try {
-                       LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS,
+                       LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS,
                                        new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response)));
                        lc.login();
                        return lc;
index 5f8c8c560e252e6de248c38ca56051ba836b8a6c..70f2cc6b0390052693baff68f98641661b368f15 100644 (file)
@@ -5,7 +5,7 @@ import java.util.Enumeration;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.logging.Log;
+import org.argeo.api.cms.CmsLog;
 
 public class HttpUtils {
        public final static String HEADER_AUTHORIZATION = "Authorization";
@@ -17,7 +17,7 @@ public class HttpUtils {
                                || userAgent.contains("opera") || userAgent.contains("browser");
        }
 
-       public static void logResponseHeaders(Log log, HttpServletResponse response) {
+       public static void logResponseHeaders(CmsLog log, HttpServletResponse response) {
                if (!log.isDebugEnabled())
                        return;
                for (String headerName : response.getHeaderNames()) {
@@ -26,7 +26,7 @@ public class HttpUtils {
                }
        }
 
-       public static void logRequestHeaders(Log log, HttpServletRequest request) {
+       public static void logRequestHeaders(CmsLog log, HttpServletRequest request) {
                if (!log.isDebugEnabled())
                        return;
                for (Enumeration<String> headerNames = request.getHeaderNames(); headerNames.hasMoreElements();) {
@@ -37,7 +37,7 @@ public class HttpUtils {
                log.debug(request.getRequestURI() + "\n");
        }
 
-       public static void logRequest(Log log, HttpServletRequest request) {
+       public static void logRequest(CmsLog log, HttpServletRequest request) {
                log.debug("contextPath=" + request.getContextPath());
                log.debug("servletPath=" + request.getServletPath());
                log.debug("requestURI=" + request.getRequestURI());
index 66bccc07ad536775190ee3eb798ddd846a8ec94c..42eedf1a3a23417f9f828c75835e9c527cf926ff 100644 (file)
@@ -17,11 +17,10 @@ import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeState;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsState;
 import org.argeo.cms.CmsMsg;
 import org.argeo.cms.LocaleUtils;
 import org.argeo.cms.auth.RemoteAuthCallback;
@@ -48,7 +47,7 @@ import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 
 public class CmsLogin implements CmsStyles, CallbackHandler {
-       private final static Log log = LogFactory.getLog(CmsLogin.class);
+       private final static CmsLog log = CmsLog.getLog(CmsLogin.class);
 
        private Composite parent;
        private Text usernameT, passwordT;
@@ -65,7 +64,7 @@ public class CmsLogin implements CmsStyles, CallbackHandler {
 
        public CmsLogin(CmsView cmsView) {
                this.cmsView = cmsView;
-               NodeState nodeState = null;// = Activator.getNodeState();
+               CmsState nodeState = null;// = Activator.getNodeState();
                if (nodeState != null) {
                        defaultLocale = nodeState.getDefaultLocale();
                        List<Locale> locales = nodeState.getLocales();
@@ -272,9 +271,9 @@ public class CmsLogin implements CmsStyles, CallbackHandler {
                        // loginContext.logout();
                        LoginContext loginContext;
                        if (subject == null)
-                               loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, this);
+                               loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, this);
                        else
-                               loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, this);
+                               loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, this);
                        loginContext.login();
                        cmsView.authChange(loginContext);
                        return true;
index 2cf0c8c578c51e79553a6a4a61e6d0e3d9397785..8ff0862839536e45f12af7a0917a6a80dcc06a57 100644 (file)
@@ -3,9 +3,8 @@ package org.argeo.cms.swt.dialogs;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsMsg;
 import org.argeo.cms.CmsUserManager;
 import org.argeo.cms.swt.CmsSwtUtils;
@@ -18,7 +17,7 @@ import org.eclipse.swt.widgets.Text;
 
 /** Dialog to change a password. */
 public class ChangePasswordDialog extends CmsMessageDialog {
-       private final static Log log = LogFactory.getLog(ChangePasswordDialog.class);
+       private final static CmsLog log = CmsLog.getLog(ChangePasswordDialog.class);
 
        private CmsUserManager cmsUserManager;
        private CmsView cmsView;
index 512829873d0bd06f268c475088fbba3152802f93..a01c919e939a1ada8727d3630883acde5ea6c31b 100644 (file)
@@ -3,8 +3,7 @@ package org.argeo.cms.swt.dialogs;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsMsg;
 import org.argeo.cms.swt.Selected;
 import org.eclipse.swt.SWT;
@@ -19,7 +18,7 @@ import org.eclipse.swt.widgets.Text;
 
 /** A dialog feedback based on a {@link LightweightDialog}. */
 public class CmsFeedback extends LightweightDialog {
-       private final static Log log = LogFactory.getLog(CmsFeedback.class);
+       private final static CmsLog log = CmsLog.getLog(CmsFeedback.class);
 
        private String message;
        private Throwable exception;
index 2f00a37a6d914778ea19c23486db42b0a2169dda..bf6417beadd3baf911407cd57e6665c946649698 100644 (file)
@@ -1,7 +1,6 @@
 package org.argeo.cms.swt.dialogs;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.FocusEvent;
@@ -19,7 +18,7 @@ import org.eclipse.swt.widgets.Shell;
 
 /** Generic lightweight dialog, not based on JFace. */
 public class LightweightDialog {
-       private final static Log log = LogFactory.getLog(LightweightDialog.class);
+       private final static CmsLog log = CmsLog.getLog(LightweightDialog.class);
 
        // must be the same value as org.eclipse.jface.window.Window#OK
        public final static int OK = 0;
index 6f5aa9dc11baa760e698681bf9ad1d18e2273359..ed1bfd8684f50dba1fc7a6dc17442b747209edd2 100644 (file)
@@ -3,13 +3,13 @@ package org.argeo.cms.swt.useradmin;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.LdapObjs;
+import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.LdapObjs;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.dialogs.TrayDialog;
 import org.eclipse.jface.viewers.DoubleClickEvent;
@@ -214,7 +214,7 @@ public class PickUpUserDialog extends TrayDialog {
 
                                if (!showSystemRoleBtn.getSelection())
                                        typeStr = "(& " + typeStr + "(!(" + LdapAttrs.DN + "=*"
-                                                       + NodeConstants.ROLES_BASEDN + ")))";
+                                                       + CmsConstants.ROLES_BASEDN + ")))";
 
                                if (filterBuilder.length() > 1) {
                                        builder.append("(&" + typeStr);
index 88573cd0dc3c2c1268927d5c1eef2de263e64ce6..d1c90a43f76f316e1b58f92345d9bd13379bfdd4 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.swt.useradmin;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.auth.UserAdminUtils;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
@@ -46,7 +46,7 @@ class UserLP extends ColumnLabelProvider {
                if (COL_ICON.equals(currType)) {
                        User user = (User) element;
                        String dn = user.getName();
-                       if (dn.endsWith(NodeConstants.ROLES_BASEDN))
+                       if (dn.endsWith(CmsConstants.ROLES_BASEDN))
                                return UsersImages.ICON_ROLE;
                        else if (user.getType() == Role.GROUP)
                                return UsersImages.ICON_GROUP;
index f3d0531e18bef4c619b12bac1779b336d3cf4a62..a388e745ebc520c83da2b95b14aa98258f9b2803 100644 (file)
@@ -3,8 +3,7 @@ package org.argeo.eclipse.ui.dialogs;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.dialogs.TitleAreaDialog;
 import org.eclipse.swt.SWT;
@@ -26,7 +25,7 @@ import org.eclipse.swt.widgets.Text;
 public class ErrorFeedback extends TitleAreaDialog {
        private static final long serialVersionUID = -8918084784628179044L;
 
-       private final static Log log = LogFactory.getLog(ErrorFeedback.class);
+       private final static CmsLog log = CmsLog.getLog(ErrorFeedback.class);
 
        private final String message;
        private final Throwable exception;
index 825879cf985bf7ee32440e6be4f5af9ded4f499f..f2715bc05afe6a7734f24960e285f4772e941419 100644 (file)
@@ -3,8 +3,7 @@ package org.argeo.eclipse.ui.dialogs;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ShellAdapter;
@@ -27,7 +26,7 @@ import org.eclipse.swt.widgets.Text;
  */
 @Deprecated
 public class FeedbackDialog extends LightweightDialog {
-       private final static Log log = LogFactory.getLog(FeedbackDialog.class);
+       private final static CmsLog log = CmsLog.getLog(FeedbackDialog.class);
 
        private String message;
        private Throwable exception;
index d00365bf2c7e8ad1aa6547ffae2a326a6d8ecfd8..615e1417a74fc7442aab83d244b54f1cb84fd279 100644 (file)
@@ -1,7 +1,6 @@
 package org.argeo.eclipse.ui.dialogs;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.FocusEvent;
@@ -20,7 +19,7 @@ import org.eclipse.swt.widgets.Shell;
 /** Generic lightweight dialog, not based on JFace. */
 @Deprecated
 public class LightweightDialog {
-       private final static Log log = LogFactory.getLog(LightweightDialog.class);
+       private final static CmsLog log = CmsLog.getLog(LightweightDialog.class);
 
        // must be the same value as org.eclipse.jface.window.Window#OK
        public final static int OK = 0;
index 136eb5055b3f7e0f59ca97b4630694b5350e01b9..c01b2d7514d61ce7c509f27d8bf3bea913fb3cb6 100644 (file)
@@ -6,8 +6,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.LinkedHashMap;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -33,7 +32,7 @@ import org.eclipse.swt.widgets.Text;
 
 /** Simple UI provider that populates a composite parent given a NIO path */
 public class AdvancedFsBrowser {
-       private final static Log log = LogFactory.getLog(AdvancedFsBrowser.class);
+       private final static CmsLog log = CmsLog.getLog(AdvancedFsBrowser.class);
 
        // Some local constants to experiment. should be cleaned
        // private final static int THUMBNAIL_WIDTH = 400;
index ff93d82514b442ce00bdb7a2a84119936696d105..2e3d6b405a631ce6e40fa948358dc5d680392e20 100644 (file)
@@ -5,8 +5,7 @@ import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.jface.viewers.DoubleClickEvent;
@@ -30,7 +29,7 @@ import org.eclipse.swt.widgets.Table;
  * the left hand side and a simple table on the right hand side.
  */
 public class SimpleFsBrowser extends Composite {
-       private final static Log log = LogFactory.getLog(SimpleFsBrowser.class);
+       private final static CmsLog log = CmsLog.getLog(SimpleFsBrowser.class);
        private static final long serialVersionUID = -40347919096946585L;
 
        private Path currSelected;
index f8128d96c1f89881a368822ee2e28dfbde8603f5..401e5cb5e6ab466b0b3bb0718fa25f4a14f3d107 100644 (file)
@@ -5,8 +5,7 @@ import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -24,7 +23,7 @@ import org.eclipse.swt.widgets.Tree;
 
 /** A simple Java 7 nio files browser with a tree */
 public class SimpleFsTreeBrowser extends Composite {
-       private final static Log log = LogFactory.getLog(SimpleFsTreeBrowser.class);
+       private final static CmsLog log = CmsLog.getLog(SimpleFsTreeBrowser.class);
        private static final long serialVersionUID = -40347919096946585L;
 
        private Path currSelected;
index 66c0c1b30bc358b7d5547c8eeb1d695e407ed26f..23eb6d78de5e59f69d82213998c84ade7b2c54b0 100644 (file)
@@ -1,2 +1,6 @@
+Export-Package: \
+org.apache.commons.logging;version=1.2.555,\
+*
+
 Import-Package: \
 *;resolution:=optional
diff --git a/org.argeo.cms.tp/src/org/apache/commons/logging/Log.java b/org.argeo.cms.tp/src/org/apache/commons/logging/Log.java
new file mode 100644 (file)
index 0000000..bf9a94c
--- /dev/null
@@ -0,0 +1,7 @@
+package org.apache.commons.logging;
+
+/** An Apache logging facade. */
+@Deprecated
+public interface Log extends org.argeo.api.cms.CmsLog {
+
+}
diff --git a/org.argeo.cms.tp/src/org/apache/commons/logging/LogFactory.java b/org.argeo.cms.tp/src/org/apache/commons/logging/LogFactory.java
new file mode 100644 (file)
index 0000000..6a2e8f8
--- /dev/null
@@ -0,0 +1,32 @@
+package org.apache.commons.logging;
+
+import java.lang.System.Logger;
+import java.util.Objects;
+
+/** A pseudo implementation of Apache Commons Logging. */
+@Deprecated
+public abstract class LogFactory {
+       public static Log getLog(Class<?> clss) {
+               return getLog(Objects.requireNonNull(clss).getName());
+       }
+
+       public static Log getLog(String name) {
+               Logger logger = System.getLogger(Objects.requireNonNull(name));
+               return new LoggerWrapper(logger);
+       }
+
+       static class LoggerWrapper implements Log {
+               private final Logger logger;
+
+               LoggerWrapper(Logger logger) {
+                       super();
+                       this.logger = logger;
+               }
+
+               @Override
+               public Logger getLogger() {
+                       return logger;
+               }
+
+       }
+}
index 6763037509534e6530cf78d45129441f94b6f7bc..67b236a8e02b3318c91ed62bc6b4e0b74b16b910 100644 (file)
@@ -1,13 +1,13 @@
 package org.slf4j.impl;
 
-import org.apache.commons.logging.Log;
+import org.argeo.api.cms.CmsLog;
 import org.slf4j.helpers.MarkerIgnoringBase;
 
 class ArgeoLogger extends MarkerIgnoringBase {
        private static final long serialVersionUID = -7719157836932627307L;
-       private final Log log;
+       private final CmsLog log;
 
-       protected ArgeoLogger(String name, Log log) {
+       protected ArgeoLogger(String name, CmsLog log) {
                this.name = name;
                this.log = log;
        }
index 19943a157eb90320744191f4d80b420fbecd9e39..224b99bcea5a0c7e9258be2e1c4bb4519f7d5899 100644 (file)
@@ -1,7 +1,6 @@
 package org.slf4j.impl;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.slf4j.ILoggerFactory;
 import org.slf4j.spi.LoggerFactoryBinder;
 
@@ -34,7 +33,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder {
 
                @Override
                public org.slf4j.Logger getLogger(String name) {
-                       Log logger = LogFactory.getLog(name);
+                       CmsLog logger = CmsLog.getLog(name);
                        return new ArgeoLogger(name, logger);
                }
 
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java
deleted file mode 100644 (file)
index 8c324ad..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.argeo.cms.ui;
-
-import org.argeo.api.cms.Cms2DSize;
-
-/** Commons constants */
-@Deprecated
-public interface CmsConstants {
-       // DATAKEYS
-//     public final static String STYLE = EclipseUiConstants.CSS_CLASS;
-//     public final static String MARKUP = EclipseUiConstants.MARKUP_SUPPORT;
-       @Deprecated
-       /* RWT.CUSTOM_ITEM_HEIGHT */
-       public final static String ITEM_HEIGHT = "org.eclipse.rap.rwt.customItemHeight";
-
-       // EVENT DETAILS
-       @Deprecated
-       /* RWT.HYPERLINK */
-       public final static int HYPERLINK = 1 << 26;
-
-       // STANDARD RESOURCES
-       public final static String LOADING_IMAGE = "icons/loading.gif";
-
-       public final static String NO_IMAGE = "icons/noPic-square-640px.png";
-       public final static Cms2DSize NO_IMAGE_SIZE = new Cms2DSize(320, 320);
-       public final static Float NO_IMAGE_RATIO = 1f;
-       // MISCEALLENEOUS
-       String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm";
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiConstants.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiConstants.java
new file mode 100644 (file)
index 0000000..9df61dc
--- /dev/null
@@ -0,0 +1,28 @@
+package org.argeo.cms.ui;
+
+import org.argeo.api.cms.Cms2DSize;
+
+/** Commons constants */
+@Deprecated
+public interface CmsUiConstants {
+       // DATAKEYS
+//     public final static String STYLE = EclipseUiConstants.CSS_CLASS;
+//     public final static String MARKUP = EclipseUiConstants.MARKUP_SUPPORT;
+       @Deprecated
+       /* RWT.CUSTOM_ITEM_HEIGHT */
+       public final static String ITEM_HEIGHT = "org.eclipse.rap.rwt.customItemHeight";
+
+       // EVENT DETAILS
+       @Deprecated
+       /* RWT.HYPERLINK */
+       public final static int HYPERLINK = 1 << 26;
+
+       // STANDARD RESOURCES
+       public final static String LOADING_IMAGE = "icons/loading.gif";
+
+       public final static String NO_IMAGE = "icons/noPic-square-640px.png";
+       public final static Cms2DSize NO_IMAGE_SIZE = new Cms2DSize(320, 320);
+       public final static Float NO_IMAGE_RATIO = 1f;
+       // MISCEALLENEOUS
+       String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm";
+}
index bf0e86beae2c27ad91d5d123c281b4ee990e62bd..cc732d49d5a0ff225baa36a7ae6943b9d6ce7932 100644 (file)
@@ -14,11 +14,10 @@ import javax.jcr.Session;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.Cms2DSize;
 import org.argeo.api.cms.CmsEditable;
 import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.ui.viewers.AbstractPageViewer;
 import org.argeo.cms.ui.viewers.EditablePart;
@@ -62,7 +61,7 @@ import org.eclipse.swt.widgets.Text;
 
 /** Manage life cycle of a form page that is linked to a given node */
 public class FormPageViewer extends AbstractPageViewer {
-       private final static Log log = LogFactory.getLog(FormPageViewer.class);
+       private final static CmsLog log = CmsLog.getLog(FormPageViewer.class);
        private static final long serialVersionUID = 5277789504209413500L;
 
        private final Section mainSection;
index 822473973d05b506f01c73c53be0fa10bc02cdec..1a445bd7645d5f37ef06cd2ae7289830f65d1a8b 100644 (file)
@@ -9,9 +9,8 @@ import java.util.GregorianCalendar;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
@@ -29,7 +28,7 @@ import org.eclipse.swt.widgets.Text;
 
 /** Utilitary methods to ease implementation of CMS forms */
 public class FormUtils {
-       private final static Log log = LogFactory.getLog(FormUtils.class);
+       private final static CmsLog log = CmsLog.getLog(FormUtils.class);
 
        public final static String DEFAULT_SHORT_DATE_FORMAT = "dd/MM/yyyy";
 
index d50b8d84de88892cf28d8c41df1f2fbef00f561d..e875b5a3d1e23b1b9ee4b9de552bbcc5760257fc 100644 (file)
@@ -3,8 +3,7 @@ package org.argeo.cms.ui.fs;
 import java.io.IOException;
 import java.io.InputStream;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.specific.FileDropAdapter;
 import org.eclipse.swt.dnd.DND;
 import org.eclipse.swt.dnd.DropTarget;
@@ -13,7 +12,7 @@ import org.eclipse.swt.widgets.Control;
 
 /** Allows a control to receive file drops. */
 public class FileDrop {
-       private final static Log log = LogFactory.getLog(FileDrop.class);
+       private final static CmsLog log = CmsLog.getLog(FileDrop.class);
 
        public void createDropTarget(Control control) {
                FileDropAdapter fileDropAdapter = new FileDropAdapter() {
index 03ec415d8fc201b355ef5a03c6a4b35f92b8fe20..c548e2aa0b0cfdd25bf7ffcce158d9334886ba3c 100644 (file)
@@ -15,8 +15,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
@@ -40,7 +39,7 @@ import org.eclipse.swt.widgets.Shell;
 public class FsContextMenu extends Shell {
        private static final long serialVersionUID = -9120261153509855795L;
 
-       private final static Log log = LogFactory.getLog(FsContextMenu.class);
+       private final static CmsLog log = CmsLog.getLog(FsContextMenu.class);
 
        // Default known actions
        public final static String ACTION_ID_CREATE_FOLDER = "createFolder";
index 9ffddd8f3a202a6d985e6de1502d582c257fe8fe..e10da3aedb534d32fd074e81ffa7a9a3b9618bdf 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.ui.internal;
 
-import org.argeo.api.NodeState;
+import org.argeo.api.cms.CmsState;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.util.tracker.ServiceTracker;
@@ -10,7 +10,7 @@ public class Activator implements BundleActivator {
        // avoid dependency to RWT OSGi
        private final static String CONTEXT_NAME_PROP = "contextName";
 
-       private static ServiceTracker<NodeState, NodeState> nodeState;
+       private static ServiceTracker<CmsState, CmsState> nodeState;
 
        // @Override
        public void start(BundleContext bc) throws Exception {
@@ -19,7 +19,7 @@ public class Activator implements BundleActivator {
 //                             LangUtils.dico(CONTEXT_NAME_PROP, "system"));
 //             bc.registerService(ApplicationConfiguration.class, new UserUi(), LangUtils.dico(CONTEXT_NAME_PROP, "user"));
 
-               nodeState = new ServiceTracker<>(bc, NodeState.class, null);
+               nodeState = new ServiceTracker<>(bc, CmsState.class, null);
                nodeState.open();
        }
 
@@ -31,7 +31,7 @@ public class Activator implements BundleActivator {
                }
        }
 
-       public static NodeState getNodeState() {
+       public static CmsState getNodeState() {
                return nodeState.getService();
        }
 }
index f8a115af019c99cf6bb8d57a61229e156e62b9b8..380634118948707391a76aaf073e069f6790140c 100644 (file)
@@ -8,16 +8,15 @@ import java.util.TreeMap;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 
 public class DefaultRepositoryRegister extends Observable implements RepositoryRegister {
        /** Key for a JCR repository alias */
-       private final static String CN = NodeConstants.CN;
+       private final static String CN = CmsConstants.CN;
        /** Key for a JCR repository URI */
        // public final static String JCR_REPOSITORY_URI = "argeo.jcr.repository.uri";
-       private final static Log log = LogFactory.getLog(DefaultRepositoryRegister.class);
+       private final static CmsLog log = CmsLog.getLog(DefaultRepositoryRegister.class);
 
        /** Read only map which will be directly exposed. */
        private Map<String, Repository> repositories = Collections.unmodifiableMap(new TreeMap<String, Repository>());
index 602ae7f6c8073a35237b2eb47d76d4c29e48e9c1..00449df26c22643833d2d727ca390e133fa0e71f 100644 (file)
@@ -11,9 +11,9 @@ import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
 
-import org.argeo.api.NodeConstants;
-import org.argeo.api.security.Keyring;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.security.Keyring;
 import org.argeo.cms.ui.jcr.model.RepositoriesElem;
 import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
 import org.argeo.eclipse.ui.TreeParent;
@@ -62,7 +62,7 @@ public class NodeContentProvider implements ITreeContentProvider {
                                if (homeNode != null)
                                        homeNode.dispose();
                                homeNode = new SingleJcrNodeElem(null, userHome,
-                                               userSession.getUserID(), NodeConstants.EGO_REPOSITORY);
+                                               userSession.getUserID(), CmsConstants.EGO_REPOSITORY);
                        }
                }
                if (repositoryRegister != null) {
index e4e8004712c97c1941852eafb2d13bc7acd69b3f..a5751c083817375f9a131c425a7f39f68dfb4d47 100644 (file)
@@ -6,8 +6,7 @@ import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.NodeType;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.ui.jcr.model.RemoteRepositoryElem;
 import org.argeo.cms.ui.jcr.model.RepositoriesElem;
 import org.argeo.cms.ui.jcr.model.RepositoryElem;
@@ -21,7 +20,7 @@ import org.eclipse.swt.graphics.Image;
 public class NodeLabelProvider extends ColumnLabelProvider {
        private static final long serialVersionUID = -3662051696443321843L;
 
-       private final static Log log = LogFactory.getLog(NodeLabelProvider.class);
+       private final static CmsLog log = CmsLog.getLog(NodeLabelProvider.class);
 
        public String getText(Object element) {
                try {
index 6b77b370eae3a458fa8188f935028dab0d93516b..37b90f7ee5fddfba220025b54fc7522c596c905c 100644 (file)
@@ -8,7 +8,7 @@ import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 
-import org.argeo.cms.ui.CmsConstants;
+import org.argeo.cms.ui.CmsUiConstants;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.argeo.jcr.JcrUtils;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
@@ -25,7 +25,7 @@ public class PropertyLabelProvider extends ColumnLabelProvider {
        public static final int COLUMN_ATTRIBUTES = 3;
 
        // Utils
-       protected DateFormat timeFormatter = new SimpleDateFormat(CmsConstants.DATE_TIME_FORMAT);
+       protected DateFormat timeFormatter = new SimpleDateFormat(CmsUiConstants.DATE_TIME_FORMAT);
 
        public void update(ViewerCell cell) {
                Object element = cell.getElement();
index 3c035fc7766d7064905516efb22ff670d2ab9063..428e7f1cd2fe73a591dc770ebe702d8ebdbd99ce 100644 (file)
@@ -9,9 +9,9 @@ import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
 
-import org.argeo.api.security.Keyring;
 import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.security.Keyring;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.argeo.eclipse.ui.TreeParent;
 
index f5306d639ed1225ee7581a1790db37136ce67c8b..858633202d72d22d83c4a28c1bc85bb03c2334db 100644 (file)
@@ -9,9 +9,9 @@ import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 
-import org.argeo.api.security.Keyring;
 import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.security.Keyring;
 import org.argeo.cms.ui.jcr.RepositoryRegister;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.argeo.eclipse.ui.TreeParent;
index 5503484e0be329af865a53b820da6cd24a6c32e9..afff3ef9e6290bde6b4d0f8f5ab55798294d833c 100644 (file)
@@ -4,7 +4,7 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.jcr.JcrUtils;
@@ -31,7 +31,7 @@ public class RepositoryElem extends TreeParent {
 
        public void login() {
                try {
-                       defaultSession = repositoryLogin(NodeConstants.SYS_WORKSPACE);
+                       defaultSession = repositoryLogin(CmsConstants.SYS_WORKSPACE);
                        String[] wkpNames = defaultSession.getWorkspace().getAccessibleWorkspaceNames();
                        for (String wkpName : wkpNames) {
                                if (wkpName.equals(defaultSession.getWorkspace().getName()))
index af7e4020d16e6e75778d9ff1953d171c785b98fb..3821e604573782ed926a50397f6baf8475fe0352 100644 (file)
@@ -8,9 +8,8 @@ import java.net.URL;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsStyle;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.cms.swt.CmsSwtUtils;
@@ -29,7 +28,7 @@ import org.osgi.framework.BundleContext;
 
 /** A link to an internal or external location. */
 public class CmsLink implements CmsUiProvider {
-       private final static Log log = LogFactory.getLog(CmsLink.class);
+       private final static CmsLog log = CmsLog.getLog(CmsLink.class);
        private BundleContext bundleContext;
 
        private String label;
index ef4f7fa44b6de9f30fdff4af79ba7d37eb80f454..8b384799fb9e2410aacb7f42a88f1c63fb89af92 100644 (file)
@@ -12,12 +12,12 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.servlet.http.HttpServletRequest;
 
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.Cms2DSize;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsConstants;
+import org.argeo.cms.ui.CmsUiConstants;
 import org.argeo.jcr.JcrUtils;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.rap.rwt.service.ResourceManager;
@@ -74,7 +74,7 @@ public class CmsUiUtils {
 
        /** A path in the node repository */
        public static String getDataPath(Node node) {
-               return getDataPath(NodeConstants.EGO_REPOSITORY, node);
+               return getDataPath(CmsConstants.EGO_REPOSITORY, node);
        }
 
        public static String getDataPath(String cn, Node node) {
@@ -114,7 +114,7 @@ public class CmsUiUtils {
 
        @Deprecated
        public static void setItemHeight(Table table, int height) {
-               table.setData(CmsConstants.ITEM_HEIGHT, height);
+               table.setData(CmsUiConstants.ITEM_HEIGHT, height);
        }
 
        //
@@ -175,18 +175,18 @@ public class CmsUiUtils {
 
        public static String noImg(Cms2DSize size) {
                ResourceManager rm = RWT.getResourceManager();
-               return CmsUiUtils.img(rm.getLocation(CmsConstants.NO_IMAGE), size);
+               return CmsUiUtils.img(rm.getLocation(CmsUiConstants.NO_IMAGE), size);
        }
 
        public static String noImg() {
-               return noImg(CmsConstants.NO_IMAGE_SIZE);
+               return noImg(CmsUiConstants.NO_IMAGE_SIZE);
        }
 
        public static Image noImage(Cms2DSize size) {
                ResourceManager rm = RWT.getResourceManager();
                InputStream in = null;
                try {
-                       in = rm.getRegisteredContent(CmsConstants.NO_IMAGE);
+                       in = rm.getRegisteredContent(CmsUiConstants.NO_IMAGE);
                        ImageData id = new ImageData(in);
                        ImageData scaled = id.scaledTo(size.getWidth(), size.getHeight());
                        Image image = new Image(Display.getCurrent(), scaled);
index d7f3d7c03d8bf23497d37074332e1390f57524f3..1fc9bd1be625e90d5d16424bf0917e498357593f 100644 (file)
@@ -4,7 +4,7 @@ import static javax.jcr.Node.JCR_CONTENT;
 import static javax.jcr.Property.JCR_DATA;
 import static javax.jcr.nodetype.NodeType.NT_FILE;
 import static javax.jcr.nodetype.NodeType.NT_RESOURCE;
-import static org.argeo.cms.ui.CmsConstants.NO_IMAGE_SIZE;
+import static org.argeo.cms.ui.CmsUiConstants.NO_IMAGE_SIZE;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -18,10 +18,9 @@ import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.Cms2DSize;
 import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 import org.eclipse.rap.rwt.RWT;
@@ -36,7 +35,7 @@ import org.eclipse.swt.widgets.Label;
 
 /** Manages only public images so far. */
 public class DefaultImageManager implements CmsImageManager<Control, Node> {
-       private final static Log log = LogFactory.getLog(DefaultImageManager.class);
+       private final static CmsLog log = CmsLog.getLog(DefaultImageManager.class);
 //     private MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
 
        public Boolean load(Node node, Control control, Cms2DSize preferredSize) {
index 60cb228437adcd784b5e848d4e9682a7a8e460af..ef24ee0d5021fd729ab8fe3a9b055c3aa9c5e896 100644 (file)
@@ -11,9 +11,8 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.security.auth.Subject;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsEditable;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.ui.widgets.ScrolledPage;
 import org.argeo.jcr.JcrException;
 import org.eclipse.jface.viewers.ContentViewer;
@@ -33,7 +32,7 @@ import org.xml.sax.SAXParseException;
 public abstract class AbstractPageViewer extends ContentViewer implements Observer {
        private static final long serialVersionUID = 5438688173410341485L;
 
-       private final static Log log = LogFactory.getLog(AbstractPageViewer.class);
+       private final static CmsLog log = CmsLog.getLog(AbstractPageViewer.class);
 
        private final boolean readOnly;
        /** The basis for the layouts, typically a ScrolledPage. */
index e5f269a40d572ea82e589863562f04089cfd7c84..c2393f267a384df28f141cf00f8d57c3615a8021 100644 (file)
@@ -3,9 +3,8 @@ package org.argeo.cms.ui.widgets;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.Cms2DSize;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.eclipse.swt.graphics.Point;
@@ -17,7 +16,7 @@ import org.eclipse.swt.widgets.Text;
 /** A stylable and editable image. */
 public abstract class EditableImage extends StyledControl {
        private static final long serialVersionUID = -5689145523114022890L;
-       private final static Log log = LogFactory.getLog(EditableImage.class);
+       private final static CmsLog log = CmsLog.getLog(EditableImage.class);
 
        private Cms2DSize preferredImageSize;
        private Boolean loaded = false;
index 84e4cce86f993705235e02f3325e1441ea79c487..e3a5cb473d588fa47254ddb752773f04fda823d1 100644 (file)
@@ -3,7 +3,7 @@ package org.argeo.cms.ui.widgets;
 import javax.jcr.Item;
 
 import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsConstants;
+import org.argeo.cms.ui.CmsUiConstants;
 import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.FocusListener;
@@ -12,7 +12,7 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 
 /** Editable text part displaying styled text. */
-public abstract class StyledControl extends JcrComposite implements CmsConstants {
+public abstract class StyledControl extends JcrComposite implements CmsUiConstants {
        private static final long serialVersionUID = -6372283442330912755L;
        private Control control;
 
index 8f7c2f99afec281cd176674a95c6f1edf23c885d..fdafa982e99f89e5239b65925f1a3dc9748cc836 100644 (file)
@@ -8,8 +8,7 @@ import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.AbstractTreeContentProvider;
 import org.argeo.eclipse.ui.EclipseUiException;
 
@@ -18,7 +17,7 @@ public abstract class AbstractNodeContentProvider extends
                AbstractTreeContentProvider {
        private static final long serialVersionUID = -4905836490027272569L;
 
-       private final static Log log = LogFactory
+       private final static CmsLog log = CmsLog
                        .getLog(AbstractNodeContentProvider.class);
 
        private Session session;
index ae5c2936d01028a36e4c95b72a361ee6673352da..b880a63c5fa11dc39e065bab6e17342778789d35 100644 (file)
@@ -8,8 +8,7 @@ import javax.jcr.observation.Event;
 import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.EventListener;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.eclipse.ui.EclipseUiException;
 import org.eclipse.swt.widgets.Display;
 
@@ -19,7 +18,7 @@ import org.eclipse.swt.widgets.Display;
 public abstract class AsyncUiEventListener implements EventListener {
        // private final static Log logSuper = LogFactory
        // .getLog(AsyncUiEventListener.class);
-       private final Log logThis = LogFactory.getLog(getClass());
+       private final CmsLog logThis = CmsLog.getLog(getClass());
 
        private final Display display;
 
@@ -39,7 +38,7 @@ public abstract class AsyncUiEventListener implements EventListener {
                return true;
        }
 
-       protected Log getLog() {
+       protected CmsLog getLog() {
                return logThis;
        }
 
diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java
new file mode 100644 (file)
index 0000000..e4a9941
--- /dev/null
@@ -0,0 +1,24 @@
+package org.argeo.cms;
+
+/** Framework agnostic interface for log notifications */
+public interface ArgeoLogListener {
+       /**
+        * Appends a log
+        * 
+        * @param username
+        *            authentified user, null for anonymous
+        * @param level
+        *            INFO, DEBUG, WARN, etc. (logging framework specific)
+        * @param category
+        *            hierarchy (logging framework specific)
+        * @param thread
+        *            name of the thread which logged this message
+        * @param msg
+        *            any object as long as its toString() method returns the
+        *            message
+        * @param exception
+        *            exception in log4j ThrowableStrRep format
+        */
+       public void appendLog(String username, Long timestamp, String level,
+                       String category, String thread, Object msg, String[] exception);
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java
new file mode 100644 (file)
index 0000000..81a40f5
--- /dev/null
@@ -0,0 +1,31 @@
+package org.argeo.cms;
+
+/**
+ * Logging framework agnostic identifying a logging service, to which one can
+ * register
+ */
+public interface ArgeoLogger {
+       /**
+        * Register for events by threads with the same authentication (or all
+        * threads if admin)
+        */
+       public void register(ArgeoLogListener listener,
+                       Integer numberOfPreviousEvents);
+
+       /**
+        * For admin use only: register for all users
+        * 
+        * @param listener
+        *            the log listener
+        * @param numberOfPreviousEvents
+        *            the number of previous events to notify
+        * @param everything
+        *            if true even anonymous is logged
+        */
+       public void registerForAll(ArgeoLogListener listener,
+                       Integer numberOfPreviousEvents, boolean everything);
+
+       public void unregister(ArgeoLogListener listener);
+
+       public void unregisterForAll(ArgeoLogListener listener);
+}
index ec8c97f79e58a7551db78c479da1e542530bac2c..f02e6a2b4439f57a3e5a23f69aaecbda3dcf1c46 100644 (file)
@@ -8,15 +8,14 @@ import java.util.ResourceBundle;
 
 import javax.security.auth.Subject;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.auth.CurrentUser;
 
 /** Utilities simplifying the development of localization enums. */
 public class LocaleUtils {
        final static String DEFAULT_OSGI_l10N_BUNDLE = "/OSGI-INF/l10n/bundle";
 
-       private final static Log log = LogFactory.getLog(LocaleUtils.class);
+       private final static CmsLog log = CmsLog.getLog(LocaleUtils.class);
 
        private final static ThreadLocal<Locale> threadLocale = new ThreadLocal<>();
 
index 0217eb8ef7c9fe745214443b8bc451d09de925ca..de3a3027012b973b0ffbfff3b57d3e187b30035b 100644 (file)
@@ -8,8 +8,7 @@ import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.service.useradmin.Authorization;
@@ -17,7 +16,7 @@ import org.osgi.service.useradmin.UserAdmin;
 
 /** Anonymous CMS user */
 public class AnonymousLoginModule implements LoginModule {
-       private final static Log log = LogFactory.getLog(AnonymousLoginModule.class);
+       private final static CmsLog log = CmsLog.getLog(AnonymousLoginModule.class);
 
        private Subject subject;
        private Map<String, Object> sharedState = null;
index 33a9d7ae429bb365c9cd316493783aed3f9ca196..72676611e4e43f631429c52e8b31a6a0893e4529 100644 (file)
@@ -11,15 +11,15 @@ import javax.naming.ldap.LdapName;
 import javax.security.auth.Subject;
 import javax.security.auth.x500.X500Principal;
 
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsSession;
 import org.argeo.api.cms.CmsSessionId;
-import org.argeo.api.security.AnonymousPrincipal;
-import org.argeo.api.security.DataAdminPrincipal;
-import org.argeo.api.security.NodeSecurityUtils;
+import org.argeo.api.cms.DataAdminPrincipal;
+import org.argeo.api.cms.AnonymousPrincipal;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.internal.auth.CmsSessionImpl;
 import org.argeo.cms.internal.auth.ImpliedByPrincipal;
 import org.argeo.cms.internal.http.WebCmsSessionImpl;
+import org.argeo.cms.security.NodeSecurityUtils;
 import org.argeo.osgi.useradmin.AuthenticatingUser;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
@@ -131,7 +131,7 @@ class CmsAuthUtils {
                        assert httpSession != null;
                        String httpSessId = httpSession.getId();
                        boolean anonymous = authorization.getName() == null;
-                       String remoteUser = !anonymous ? authorization.getName() : NodeConstants.ROLE_ANONYMOUS;
+                       String remoteUser = !anonymous ? authorization.getName() : CmsConstants.ROLE_ANONYMOUS;
                        request.setAttribute(HttpContext.REMOTE_USER, remoteUser);
                        request.setAttribute(HttpContext.AUTHORIZATION, authorization);
 
index 9808305ce0000c4132b933db09142efe5c71cc7b..afb6360b476450401ad9fa06f638f01063f51558 100644 (file)
@@ -13,9 +13,9 @@ import java.util.UUID;
 import javax.security.auth.Subject;
 import javax.security.auth.x500.X500Principal;
 
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsSession;
 import org.argeo.api.cms.CmsSessionId;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.internal.auth.CmsSessionImpl;
 import org.argeo.cms.internal.auth.ImpliedByPrincipal;
 import org.argeo.cms.internal.kernel.Activator;
@@ -86,7 +86,7 @@ public final class CurrentUser {
                if (subject == null)
                        throw new IllegalArgumentException("Subject cannot be null");
                if (subject.getPrincipals(X500Principal.class).size() != 1)
-                       return NodeConstants.ROLE_ANONYMOUS;
+                       return CmsConstants.ROLE_ANONYMOUS;
                Principal principal = subject.getPrincipals(X500Principal.class).iterator().next();
                return principal.getName();
        }
@@ -118,7 +118,7 @@ public final class CurrentUser {
                if (subject == null)
                        return true;
                String username = getUsername(subject);
-               return username == null || username.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS);
+               return username == null || username.equalsIgnoreCase(CmsConstants.ROLE_ANONYMOUS);
        }
 
        public CmsSession getCmsSession() {
diff --git a/org.argeo.cms/src/org/argeo/cms/auth/DataAdminLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/DataAdminLoginModule.java
new file mode 100644 (file)
index 0000000..ea1046b
--- /dev/null
@@ -0,0 +1,48 @@
+package org.argeo.cms.auth;
+
+import java.util.Map;
+
+import javax.security.auth.AuthPermission;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.argeo.api.cms.DataAdminPrincipal;
+
+/**
+ * Log-in a system process as data admin. Protection is via
+ * {@link AuthPermission} on this login module, so if it can be accessed it will
+ * always succeed.
+ */
+public class DataAdminLoginModule implements LoginModule {
+       private Subject subject;
+
+       @Override
+       public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
+                       Map<String, ?> options) {
+               this.subject = subject;
+       }
+
+       @Override
+       public boolean login() throws LoginException {
+               return true;
+       }
+
+       @Override
+       public boolean commit() throws LoginException {
+               subject.getPrincipals().add(new DataAdminPrincipal());
+               return true;
+       }
+
+       @Override
+       public boolean abort() throws LoginException {
+               return true;
+       }
+
+       @Override
+       public boolean logout() throws LoginException {
+               subject.getPrincipals().removeAll(subject.getPrincipals(DataAdminPrincipal.class));
+               return true;
+       }
+}
index 32219dd8794d9bbd2b93108428df5e4a412ee281..ccf7fc724af1e8bf322c4c4545a84348883f3f9e 100644 (file)
@@ -10,14 +10,13 @@ import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.auth.ident.IdentClient;
 import org.argeo.cms.internal.kernel.Activator;
-import org.argeo.ident.IdentClient;
 
 /** Use an ident service to identify. */
 public class IdentLoginModule implements LoginModule {
-       private final static Log log = LogFactory.getLog(IdentLoginModule.class);
+       private final static CmsLog log = CmsLog.getLog(IdentLoginModule.class);
 
        private CallbackHandler callbackHandler = null;
        private Map<String, Object> sharedState = null;
index 920c76b650cbf6529d2d6bd31ae0793a0cb6de1d..c49a59ef1dcc5ea69033618702e0caff7d8c2271 100644 (file)
@@ -15,7 +15,7 @@ import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
-import org.argeo.api.security.PBEKeySpecCallback;
+import org.argeo.cms.security.PBEKeySpecCallback;
 import org.argeo.util.PasswordEncryption;
 
 /** Adds a secret key to the private credentials */
index ecbc844b5141c4c4ef7908fdc3bb1addf1057a09..4d3617eefc4150e01fdc07075b87d61ae03ce252 100644 (file)
@@ -14,8 +14,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.auth.CmsSessionImpl;
 import org.argeo.cms.internal.kernel.Activator;
 import org.osgi.framework.BundleContext;
@@ -25,7 +24,7 @@ import org.osgi.service.useradmin.Authorization;
 
 /** Use the HTTP session as the basis for authentication. */
 public class RemoteSessionLoginModule implements LoginModule {
-       private final static Log log = LogFactory.getLog(RemoteSessionLoginModule.class);
+       private final static CmsLog log = CmsLog.getLog(RemoteSessionLoginModule.class);
 
        private Subject subject = null;
        private CallbackHandler callbackHandler = null;
index 649ecc464b185a590c1ad54a6d8ef9036a1fd07d..08380ac5a227cd165756e9b430cec4e6fd9c5e6d 100644 (file)
@@ -13,16 +13,15 @@ import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 import javax.security.auth.x500.X500Principal;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.osgi.useradmin.IpaUtils;
 import org.argeo.osgi.useradmin.OsUserUtils;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.service.useradmin.Authorization;
 
 /** Login module for when the system is owned by a single user. */
 public class SingleUserLoginModule implements LoginModule {
-       private final static Log log = LogFactory.getLog(SingleUserLoginModule.class);
+       private final static CmsLog log = CmsLog.getLog(SingleUserLoginModule.class);
 
        private Subject subject;
        private Map<String, Object> sharedState = null;
index 568e2f6e0f6d085794e84932e7ff5b241d3cef60..c94480cb54de824d0ec2d9f31bdaf3f5cae993f7 100644 (file)
@@ -8,8 +8,7 @@ import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.kernel.Activator;
 import org.ietf.jgss.GSSContext;
 import org.ietf.jgss.GSSCredential;
@@ -19,7 +18,7 @@ import org.ietf.jgss.GSSName;
 
 /** SPNEGO login */
 public class SpnegoLoginModule implements LoginModule {
-       private final static Log log = LogFactory.getLog(SpnegoLoginModule.class);
+       private final static CmsLog log = CmsLog.getLog(SpnegoLoginModule.class);
 
        private Subject subject;
        private Map<String, Object> sharedState = null;
index 188e860581a7335dbda19bae5888bb2bea13b6c0..b9f8d4a5131df7d0773c63cd532239cfe7049f9f 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.auth;
 
-import static org.argeo.naming.LdapAttrs.cn;
+import static org.argeo.util.naming.LdapAttrs.cn;
 
 import java.io.IOException;
 import java.security.PrivilegedAction;
@@ -24,15 +24,14 @@ import javax.security.auth.login.CredentialNotFoundException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.security.CryptoKeyring;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.kernel.Activator;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.cms.security.CryptoKeyring;
 import org.argeo.osgi.useradmin.AuthenticatingUser;
 import org.argeo.osgi.useradmin.IpaUtils;
 import org.argeo.osgi.useradmin.TokenUtils;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
@@ -46,7 +45,7 @@ import org.osgi.service.useradmin.UserAdmin;
  * authentication.
  */
 public class UserAdminLoginModule implements LoginModule {
-       private final static Log log = LogFactory.getLog(UserAdminLoginModule.class);
+       private final static CmsLog log = CmsLog.getLog(UserAdminLoginModule.class);
 
        private Subject subject;
        private CallbackHandler callbackHandler;
@@ -337,7 +336,7 @@ public class UserAdminLoginModule implements LoginModule {
        }
 
        protected Group searchForToken(UserAdmin userAdmin, String token) {
-               String dn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN;
+               String dn = cn + "=" + token + "," + CmsConstants.TOKENS_BASEDN;
                Group tokenGroup = (Group) userAdmin.getRole(dn);
                return tokenGroup;
        }
index ad53086f5c206249d4b066fc7f5f90b0e087ab2b..eed38cc3285aa17de5ca6563f556c0f0e21027c3 100644 (file)
@@ -6,8 +6,8 @@ import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
-import org.argeo.api.NodeConstants;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
@@ -135,9 +135,9 @@ public class UserAdminUtils {
        /** Simply retrieves a display name of the relevant domain */
        public final static String getDomainName(User user) {
                String dn = user.getName();
-               if (dn.endsWith(NodeConstants.ROLES_BASEDN))
+               if (dn.endsWith(CmsConstants.ROLES_BASEDN))
                        return "System roles";
-               if (dn.endsWith(NodeConstants.TOKENS_BASEDN))
+               if (dn.endsWith(CmsConstants.TOKENS_BASEDN))
                        return "Tokens";
                try {
                        // FIXME deal with non-DC
diff --git a/org.argeo.cms/src/org/argeo/cms/auth/ident/IdentClient.java b/org.argeo.cms/src/org/argeo/cms/auth/ident/IdentClient.java
new file mode 100644 (file)
index 0000000..c55ec68
--- /dev/null
@@ -0,0 +1,124 @@
+package org.argeo.cms.auth.ident;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.ConnectException;
+import java.net.Socket;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * A simple ident client, supporting authd OpenSSL encrypted username.
+ * 
+ * @see RFC 1413 https://tools.ietf.org/html/rfc1413
+ */
+public class IdentClient {
+       public final static int DEFAULT_IDENT_PORT = 113;
+       public final static String AUTHD_PASSPHRASE_PATH = "/etc/ident.key";
+       final static String NO_USER = "NO-USER";
+
+       private final String host;
+       private final int port;
+
+       private OpenSslDecryptor openSslDecryptor = new OpenSslDecryptor();
+       private String identPassphrase = null;
+
+       public IdentClient(String host) {
+               this(host, readPassphrase(AUTHD_PASSPHRASE_PATH), DEFAULT_IDENT_PORT);
+       }
+
+       public IdentClient(String host, Path passPhrasePath) {
+               this(host, readPassphrase(passPhrasePath), DEFAULT_IDENT_PORT);
+       }
+
+       public IdentClient(String host, String identPassphrase) {
+               this(host, identPassphrase, DEFAULT_IDENT_PORT);
+       }
+
+       public IdentClient(String host, String identPassphrase, int port) {
+               this.host = host;
+               this.identPassphrase = identPassphrase;
+               this.port = port;
+       }
+
+       /** @return the username or null if none */
+       public String getUsername(int serverPort, int clientPort) {
+               String answer;
+               try (Socket socket = new Socket(host, port)) {
+                       String msg = clientPort + "," + serverPort + "\n";
+                       OutputStream out = socket.getOutputStream();
+                       out.write(msg.getBytes(StandardCharsets.US_ASCII));
+                       out.flush();
+                       BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+                       answer = reader.readLine();
+               } catch (ConnectException e) {
+                       System.err.println(
+                                       "Ident client is configured but no ident server available on " + host + " (port " + port + ")");
+                       return null;
+               } catch (Exception e) {
+                       throw new RuntimeException("Cannot read from ident server on " + host + " (port " + port + ")", e);
+               }
+               StringTokenizer st = new StringTokenizer(answer, " :\n");
+               String username = null;
+               while (st.hasMoreTokens())
+                       username = st.nextToken();
+
+               if (username.equals(NO_USER))
+                       return null;
+
+               if (identPassphrase != null && username.startsWith("[")) {
+                       String encrypted = username.substring(1, username.length() - 1);
+                       username = openSslDecryptor.decryptAuthd(encrypted, identPassphrase).trim();
+               }
+//             System.out.println(username);
+               return username;
+       }
+
+       public void setOpenSslDecryptor(OpenSslDecryptor openSslDecryptor) {
+               this.openSslDecryptor = openSslDecryptor;
+       }
+
+       public static String readPassphrase(String filePath) {
+               return readPassphrase(Paths.get(filePath));
+       }
+
+       /** @return the first line of the file. */
+       public static String readPassphrase(Path path) {
+               if (!isPathAvailable(path))
+                       return null;
+               List<String> lines;
+               try {
+                       lines = Files.readAllLines(path);
+               } catch (IOException e) {
+                       throw new IllegalStateException("Cannot read " + path, e);
+               }
+               if (lines.size() == 0)
+                       return null;
+               String passphrase = lines.get(0);
+               return passphrase;
+       }
+
+       public static boolean isDefaultAuthdPassphraseFileAvailable() {
+               return isPathAvailable(Paths.get(AUTHD_PASSPHRASE_PATH));
+       }
+
+       public static boolean isPathAvailable(Path path) {
+               if (!Files.exists(path))
+                       return false;
+               if (!Files.isReadable(path))
+                       return false;
+               return true;
+       }
+
+       public static void main(String[] args) {
+               IdentClient identClient = new IdentClient("127.0.0.1", "changeit");
+               String username = identClient.getUsername(7070, 55958);
+               System.out.println(username);
+       }
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/auth/ident/OpenSslDecryptor.java b/org.argeo.cms/src/org/argeo/cms/auth/ident/OpenSslDecryptor.java
new file mode 100644 (file)
index 0000000..ce7bee9
--- /dev/null
@@ -0,0 +1,162 @@
+package org.argeo.cms.auth.ident;
+
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.Base64;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Decrypts OpenSSL encrypted data.
+ * 
+ * From
+ * https://stackoverflow.com/questions/11783062/how-to-decrypt-file-in-java-encrypted-with-openssl-command-using-aes
+ * 
+ * See also
+ * https://stackoverflow.com/questions/54171959/badpadding-exception-when-trying-to-decrypt-aes-based-encrypted-text/54173509#54173509
+ * for new default message digest (not yet in CentOS 7 as of July 2019)
+ */
+public class OpenSslDecryptor {
+       private static final int INDEX_KEY = 0;
+       private static final int INDEX_IV = 1;
+       private static final int ITERATIONS = 1;
+
+       private static final int SALT_OFFSET = 8;
+       private static final int SALT_SIZE = 8;
+       private static final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE;
+
+       /** In bits. */
+       private final int keySize;
+
+       private Cipher cipher;
+       private MessageDigest messageDigest;
+
+       public OpenSslDecryptor() {
+               /*
+                * Changed to SHA-256 from OpenSSL v1.1.0 (see
+                * https://stackoverflow.com/questions/39637388/encryption-decryption-doesnt-
+                * work-well-between-two-different-openssl-versions)
+                */
+               this(128, "MD5");
+       }
+
+       public OpenSslDecryptor(int keySize, String messageDigest) {
+               this.keySize = keySize;
+               try {
+                       this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+                       this.messageDigest = MessageDigest.getInstance(messageDigest);
+               } catch (GeneralSecurityException e) {
+                       throw new IllegalArgumentException("Cannot initialise decryptor", e);
+               }
+       }
+
+       public String decryptAuthd(String dataBase64, String passphrase) {
+               try {
+                       byte[] headerSaltAndCipherText = Base64.getDecoder().decode(dataBase64);
+
+                       boolean withSalt = true;
+                       byte[] salt = withSalt ? Arrays.copyOfRange(headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE)
+                                       : null;
+                       byte[] encrypted = withSalt
+                                       ? Arrays.copyOfRange(headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length)
+                                       : headerSaltAndCipherText;
+
+                       final byte[][] keyAndIV = EVP_BytesToKey(keySize / Byte.SIZE, cipher.getBlockSize(), messageDigest, salt,
+                                       passphrase.getBytes(StandardCharsets.US_ASCII), ITERATIONS);
+                       SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES");
+                       IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]);
+
+                       cipher.init(Cipher.DECRYPT_MODE, key, iv);
+                       byte[] decrypted = cipher.doFinal(encrypted);
+
+                       String answer = new String(decrypted, StandardCharsets.US_ASCII);
+                       return answer;
+               } catch (BadPaddingException e) {
+                       throw new IllegalStateException("Bad password, algorithm, mode or padding;"
+                                       + " no salt, wrong number of iterations or corrupted ciphertext.", e);
+               } catch (IllegalBlockSizeException e) {
+                       throw new IllegalStateException("Bad algorithm, mode or corrupted (resized) ciphertext.", e);
+               } catch (GeneralSecurityException e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       private static byte[][] EVP_BytesToKey(int key_len, int iv_len, MessageDigest md, byte[] salt, byte[] data,
+                       int count) {
+               byte[][] both = new byte[2][];
+               byte[] key = new byte[key_len];
+               int key_ix = 0;
+               byte[] iv = new byte[iv_len];
+               int iv_ix = 0;
+               both[0] = key;
+               both[1] = iv;
+               byte[] md_buf = null;
+               int nkey = key_len;
+               int niv = iv_len;
+               int i = 0;
+               if (data == null) {
+                       return both;
+               }
+               int addmd = 0;
+               for (;;) {
+                       md.reset();
+                       if (addmd++ > 0) {
+                               md.update(md_buf);
+                       }
+                       md.update(data);
+                       if (null != salt) {
+                               md.update(salt, 0, 8);
+                       }
+                       md_buf = md.digest();
+                       for (i = 1; i < count; i++) {
+                               md.reset();
+                               md.update(md_buf);
+                               md_buf = md.digest();
+                       }
+                       i = 0;
+                       if (nkey > 0) {
+                               for (;;) {
+                                       if (nkey == 0)
+                                               break;
+                                       if (i == md_buf.length)
+                                               break;
+                                       key[key_ix++] = md_buf[i];
+                                       nkey--;
+                                       i++;
+                               }
+                       }
+                       if (niv > 0 && i != md_buf.length) {
+                               for (;;) {
+                                       if (niv == 0)
+                                               break;
+                                       if (i == md_buf.length)
+                                               break;
+                                       iv[iv_ix++] = md_buf[i];
+                                       niv--;
+                                       i++;
+                               }
+                       }
+                       if (nkey == 0 && niv == 0) {
+                               break;
+                       }
+               }
+               for (i = 0; i < md_buf.length; i++) {
+                       md_buf[i] = 0;
+               }
+               return both;
+       }
+
+       public static void main(String[] args) {
+               String dataBase64 = args[0];
+               String passphrase = args[1];
+               OpenSslDecryptor decryptor = new OpenSslDecryptor();
+               System.out.println(decryptor.decryptAuthd(dataBase64, passphrase));
+       }
+
+}
\ No newline at end of file
diff --git a/org.argeo.cms/src/org/argeo/cms/auth/ident/package-info.java b/org.argeo.cms/src/org/argeo/cms/auth/ident/package-info.java
new file mode 100644 (file)
index 0000000..7fbd5c6
--- /dev/null
@@ -0,0 +1,2 @@
+/** Ident authentication protocol support. */
+package org.argeo.cms.auth.ident;
\ No newline at end of file
index 4e9b4e07293188b62e31d4fcdf383e71f90ee613..b0824e84bb1924835d0232c1691a7609d8de1807 100644 (file)
@@ -21,11 +21,10 @@ import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.x500.X500Principal;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsSession;
-import org.argeo.api.security.NodeSecurityUtils;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.security.NodeSecurityUtils;
+import org.argeo.api.cms.CmsAuth;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
@@ -37,7 +36,7 @@ import org.osgi.service.useradmin.Authorization;
 public class CmsSessionImpl implements CmsSession, Serializable {
        private static final long serialVersionUID = 1867719354246307225L;
        private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionImpl.class).getBundleContext();
-       private final static Log log = LogFactory.getLog(CmsSessionImpl.class);
+       private final static CmsLog log = CmsLog.getLog(CmsSessionImpl.class);
 
        // private final Subject initialSubject;
        private transient AccessControlContext accessControlContext;
@@ -96,9 +95,9 @@ public class CmsSessionImpl implements CmsSession, Serializable {
                try {
                        LoginContext lc;
                        if (isAnonymous()) {
-                               lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, getSubject());
+                               lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS, getSubject());
                        } else {
-                               lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, getSubject());
+                               lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, getSubject());
                        }
                        lc.logout();
                } catch (LoginException e) {
index 5485fc5ee112ad445995a18c61c6523e2ff7855e..19136606da492a3f5d6029bc5f526a5907aa03fd 100644 (file)
@@ -1,8 +1,8 @@
 package org.argeo.cms.internal.auth;
 
-import static org.argeo.naming.LdapAttrs.cn;
-import static org.argeo.naming.LdapAttrs.description;
-import static org.argeo.naming.LdapAttrs.owner;
+import static org.argeo.util.naming.LdapAttrs.cn;
+import static org.argeo.util.naming.LdapAttrs.description;
+import static org.argeo.util.naming.LdapAttrs.owner;
 
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
@@ -23,19 +23,18 @@ import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.security.auth.Subject;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsUserManager;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.NamingUtils;
-import org.argeo.naming.SharedSecret;
 import org.argeo.osgi.transaction.WorkTransaction;
 import org.argeo.osgi.useradmin.TokenUtils;
 import org.argeo.osgi.useradmin.UserAdminConf;
 import org.argeo.osgi.useradmin.UserDirectory;
+import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.NamingUtils;
+import org.argeo.util.naming.SharedSecret;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Group;
@@ -56,7 +55,7 @@ import org.osgi.service.useradmin.UserAdmin;
  * </ul>
  */
 public class CmsUserManagerImpl implements CmsUserManager {
-       private final static Log log = LogFactory.getLog(CmsUserManagerImpl.class);
+       private final static CmsLog log = CmsLog.getLog(CmsUserManagerImpl.class);
 
        private UserAdmin userAdmin;
 //     private Map<String, String> serviceProperties;
@@ -152,7 +151,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                List<User> users = new ArrayList<User>();
                for (Role role : roles) {
                        if ((includeUsers && role.getType() == Role.USER || role.getType() == Role.GROUP) && !users.contains(role)
-                                       && (includeSystemRoles || !role.getName().toLowerCase().endsWith(NodeConstants.ROLES_BASEDN))) {
+                                       && (includeSystemRoles || !role.getName().toLowerCase().endsWith(CmsConstants.ROLES_BASEDN))) {
                                if (match(role, filter))
                                        users.add((User) role);
                        }
@@ -234,9 +233,9 @@ public class CmsUserManagerImpl implements CmsUserManager {
 
                        if (onlyWritable && readOnly)
                                continue;
-                       if (baseDn.equalsIgnoreCase(NodeConstants.ROLES_BASEDN))
+                       if (baseDn.equalsIgnoreCase(CmsConstants.ROLES_BASEDN))
                                continue;
-                       if (baseDn.equalsIgnoreCase(NodeConstants.TOKENS_BASEDN))
+                       if (baseDn.equalsIgnoreCase(CmsConstants.TOKENS_BASEDN))
                                continue;
                        dns.put(baseDn, UserAdminConf.propertiesAsUri(userDirectories.get(userDirectory)).toString());
 
@@ -364,7 +363,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
        public void expireAuthToken(String token) {
                try {
                        userTransaction.begin();
-                       String dn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN;
+                       String dn = cn + "=" + token + "," + CmsConstants.TOKENS_BASEDN;
                        Group tokenGroup = (Group) userAdmin.getRole(dn);
                        String ldapDate = NamingUtils.instantToLdapDate(ZonedDateTime.now(ZoneOffset.UTC));
                        tokenGroup.getProperties().put(description.name(), ldapDate);
@@ -385,7 +384,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
 
        @Override
        public void expireAuthTokens(Subject subject) {
-               Set<String> tokens = TokenUtils.tokensUsed(subject, NodeConstants.TOKENS_BASEDN);
+               Set<String> tokens = TokenUtils.tokensUsed(subject, CmsConstants.TOKENS_BASEDN);
                for (String token : tokens)
                        expireAuthToken(token);
        }
@@ -400,7 +399,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                try {
                        userTransaction.begin();
                        User user = (User) userAdmin.getRole(userDn);
-                       String tokenDn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN;
+                       String tokenDn = cn + "=" + token + "," + CmsConstants.TOKENS_BASEDN;
                        Group tokenGroup = (Group) userAdmin.createRole(tokenDn, Role.GROUP);
                        if (roles != null)
                                for (String role : roles) {
@@ -408,7 +407,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                                        if (r != null)
                                                tokenGroup.addMember(r);
                                        else {
-                                               if (!role.equals(NodeConstants.ROLE_USER)) {
+                                               if (!role.equals(CmsConstants.ROLE_USER)) {
                                                        throw new IllegalStateException(
                                                                        "Cannot add role " + role + " to token " + token + " for " + userDn);
                                                }
index 8d68be64309c3aad81b97cb6779937e260411d79..535c328534c9a8a17f4c1e8f74c6ea1d60c59a47 100644 (file)
@@ -11,14 +11,13 @@ import java.util.concurrent.Executors;
 
 import javax.security.auth.login.Configuration;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.ArgeoLogger;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeDeployment;
-import org.argeo.api.NodeInstance;
-import org.argeo.api.NodeState;
-import org.argeo.ident.IdentClient;
+import org.argeo.api.cms.CmsState;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsData;
+import org.argeo.api.cms.CmsDeployment;
+import org.argeo.cms.ArgeoLogger;
+import org.argeo.cms.auth.ident.IdentClient;
 import org.ietf.jgss.GSSCredential;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
@@ -40,7 +39,7 @@ import org.osgi.util.tracker.ServiceTracker;
  * bundle (and only it)
  */
 public class Activator implements BundleActivator {
-       private final static Log log = LogFactory.getLog(Activator.class);
+       private final static CmsLog log = CmsLog.getLog(Activator.class);
 
        private static Activator instance;
 
@@ -52,9 +51,9 @@ public class Activator implements BundleActivator {
        private LogReaderService logReaderService;
 
        private NodeLogger logger;
-       private CmsState nodeState;
-       private CmsDeployment nodeDeployment;
-       private CmsInstance nodeInstance;
+       private CmsStateImpl nodeState;
+       private CmsDeploymentImpl nodeDeployment;
+       private CmsDataImpl nodeInstance;
 
        private ServiceTracker<UserAdmin, NodeUserAdmin> userAdminSt;
        private ExecutorService internalExecutorService;
@@ -162,16 +161,16 @@ public class Activator implements BundleActivator {
 
        private void initNode() throws IOException {
                // Node state
-               nodeState = new CmsState();
-               registerService(NodeState.class, nodeState, null);
+               nodeState = new CmsStateImpl();
+               registerService(CmsState.class, nodeState, null);
 
                // Node deployment
-               nodeDeployment = new CmsDeployment();
+               nodeDeployment = new CmsDeploymentImpl();
 //             registerService(NodeDeployment.class, nodeDeployment, null);
 
                // Node instance
-               nodeInstance = new CmsInstance();
-               registerService(NodeInstance.class, nodeInstance, null);
+               nodeInstance = new CmsDataImpl();
+               registerService(CmsData.class, nodeInstance, null);
        }
 
        public static <T> void registerService(Class<T> clss, T service, Dictionary<String, ?> properties) {
@@ -218,7 +217,7 @@ public class Activator implements BundleActivator {
 //             return bundleContext.getService(sr);
 //     }
 
-       public static NodeState getNodeState() {
+       public static CmsState getNodeState() {
                return instance.nodeState;
        }
 
@@ -236,7 +235,7 @@ public class Activator implements BundleActivator {
        }
 
        public static String getHttpProxySslHeader() {
-               return KernelUtils.getFrameworkProp(NodeConstants.HTTP_PROXY_SSL_DN);
+               return KernelUtils.getFrameworkProp(CmsConstants.HTTP_PROXY_SSL_DN);
        }
 
        public static IdentClient getIdentClient(String remoteAddr) {
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDataImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDataImpl.java
new file mode 100644 (file)
index 0000000..3b197e2
--- /dev/null
@@ -0,0 +1,56 @@
+package org.argeo.cms.internal.kernel;
+
+import javax.naming.ldap.LdapName;
+
+import org.argeo.api.cms.CmsData;
+import org.argeo.api.cms.CmsLog;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+public class CmsDataImpl implements CmsData {
+       private final CmsLog log = CmsLog.getLog(getClass());
+       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
+
+//     private EgoRepository egoRepository;
+
+       public CmsDataImpl() {
+               initTrackers();
+       }
+
+       private void initTrackers() {
+               // node repository
+//             new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
+//                     @Override
+//                     public Repository addingService(ServiceReference<Repository> reference) {
+//                             Object cn = reference.getProperty(NodeConstants.CN);
+//                             if (cn != null && cn.equals(NodeConstants.EGO_REPOSITORY)) {
+////                                   egoRepository = (EgoRepository) bc.getService(reference);
+//                                     if (log.isTraceEnabled())
+//                                             log.trace("Home repository is available");
+//                             }
+//                             return super.addingService(reference);
+//                     }
+//
+//                     @Override
+//                     public void removedService(ServiceReference<Repository> reference, Repository service) {
+//                             super.removedService(reference, service);
+////                           egoRepository = null;
+//                     }
+//
+//             }.open();
+       }
+
+       public void shutdown() {
+
+       }
+
+       @Override
+       public void createWorkgroup(LdapName dn) {
+//             if (egoRepository == null)
+//                     throw new CmsException("Ego repository is not available");
+//             // TODO add check that the group exists
+//             egoRepository.createWorkgroup(dn);
+               throw new UnsupportedOperationException();
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java
deleted file mode 100644 (file)
index b24fb0a..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-package org.argeo.cms.internal.kernel;
-
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.net.URL;
-import java.util.Dictionary;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeDeployment;
-import org.argeo.api.NodeState;
-import org.argeo.osgi.transaction.WorkTransaction;
-import org.argeo.osgi.useradmin.UserAdminConf;
-import org.eclipse.equinox.http.jetty.JettyConfigurator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.http.HttpService;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-
-/** Implementation of a CMS deployment. */
-public class CmsDeployment implements NodeDeployment {
-       private final Log log = LogFactory.getLog(getClass());
-       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-       private DeployConfig deployConfig;
-
-       private Long availableSince;
-
-       // Readiness
-       private boolean nodeAvailable = false;
-       private boolean userAdminAvailable = false;
-       private boolean httpExpected = false;
-       private boolean httpAvailable = false;
-
-       public CmsDeployment() {
-//             ServiceReference<NodeState> nodeStateSr = bc.getServiceReference(NodeState.class);
-//             if (nodeStateSr == null)
-//                     throw new CmsException("No node state available");
-
-//             NodeState nodeState = bc.getService(nodeStateSr);
-//             cleanState = nodeState.isClean();
-
-//             nodeHttp = new NodeHttp();
-               initTrackers();
-       }
-
-       private void initTrackers() {
-               ServiceTracker<?, ?> httpSt = new ServiceTracker<HttpService, HttpService>(bc, HttpService.class, null) {
-
-                       @Override
-                       public HttpService addingService(ServiceReference<HttpService> sr) {
-                               httpAvailable = true;
-                               Object httpPort = sr.getProperty("http.port");
-                               Object httpsPort = sr.getProperty("https.port");
-                               log.info(httpPortsMsg(httpPort, httpsPort));
-                               checkReadiness();
-                               return super.addingService(sr);
-                       }
-               };
-               // httpSt.open();
-               KernelUtils.asyncOpen(httpSt);
-
-               ServiceTracker<?, ?> userAdminSt = new ServiceTracker<UserAdmin, UserAdmin>(bc, UserAdmin.class, null) {
-                       @Override
-                       public UserAdmin addingService(ServiceReference<UserAdmin> reference) {
-                               UserAdmin userAdmin = super.addingService(reference);
-                               addStandardSystemRoles(userAdmin);
-                               userAdminAvailable = true;
-                               checkReadiness();
-                               return userAdmin;
-                       }
-               };
-               // userAdminSt.open();
-               KernelUtils.asyncOpen(userAdminSt);
-
-               ServiceTracker<?, ?> confAdminSt = new ServiceTracker<ConfigurationAdmin, ConfigurationAdmin>(bc,
-                               ConfigurationAdmin.class, null) {
-                       @Override
-                       public ConfigurationAdmin addingService(ServiceReference<ConfigurationAdmin> reference) {
-                               ConfigurationAdmin configurationAdmin = bc.getService(reference);
-                               boolean isClean;
-                               try {
-                                       Configuration[] confs = configurationAdmin
-                                                       .listConfigurations("(service.factoryPid=" + NodeConstants.NODE_USER_ADMIN_PID + ")");
-                                       isClean = confs == null || confs.length == 0;
-                               } catch (Exception e) {
-                                       throw new IllegalStateException("Cannot analyse clean state", e);
-                               }
-                               deployConfig = new DeployConfig(configurationAdmin, isClean);
-                               Activator.registerService(NodeDeployment.class, CmsDeployment.this, null);
-//                             JcrInitUtils.addToDeployment(CmsDeployment.this);
-                               httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
-                               try {
-                                       Configuration[] configs = configurationAdmin
-                                                       .listConfigurations("(service.factoryPid=" + NodeConstants.NODE_USER_ADMIN_PID + ")");
-
-                                       boolean hasDomain = false;
-                                       for (Configuration config : configs) {
-                                               Object realm = config.getProperties().get(UserAdminConf.realm.name());
-                                               if (realm != null) {
-                                                       log.debug("Found realm: " + realm);
-                                                       hasDomain = true;
-                                               }
-                                       }
-                                       if (hasDomain) {
-                                               loadIpaJaasConfiguration();
-                                       }
-                               } catch (Exception e) {
-                                       throw new IllegalStateException("Cannot initialize config", e);
-                               }
-                               return super.addingService(reference);
-                       }
-               };
-               // confAdminSt.open();
-               KernelUtils.asyncOpen(confAdminSt);
-       }
-
-       public void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props) {
-               deployConfig.putFactoryDeployConfig(factoryPid, props);
-               deployConfig.save();
-               try {
-                       deployConfig.loadConfigs();
-               } catch (IOException e) {
-                       throw new IllegalStateException(e);
-               }
-       }
-
-       public Dictionary<String, Object> getProps(String factoryPid, String cn) {
-               return deployConfig.getProps(factoryPid, cn);
-       }
-
-       private String httpPortsMsg(Object httpPort, Object httpsPort) {
-               return (httpPort != null ? "HTTP " + httpPort + " " : " ") + (httpsPort != null ? "HTTPS " + httpsPort : "");
-       }
-
-       private void addStandardSystemRoles(UserAdmin userAdmin) {
-               // we assume UserTransaction is already available (TODO make it more robust)
-               WorkTransaction userTransaction = bc.getService(bc.getServiceReference(WorkTransaction.class));
-               try {
-                       userTransaction.begin();
-                       Role adminRole = userAdmin.getRole(NodeConstants.ROLE_ADMIN);
-                       if (adminRole == null) {
-                               adminRole = userAdmin.createRole(NodeConstants.ROLE_ADMIN, Role.GROUP);
-                       }
-                       if (userAdmin.getRole(NodeConstants.ROLE_USER_ADMIN) == null) {
-                               Group userAdminRole = (Group) userAdmin.createRole(NodeConstants.ROLE_USER_ADMIN, Role.GROUP);
-                               userAdminRole.addMember(adminRole);
-                       }
-                       userTransaction.commit();
-               } catch (Exception e) {
-                       try {
-                               userTransaction.rollback();
-                       } catch (Exception e1) {
-                               // silent
-                       }
-                       throw new IllegalStateException("Cannot add standard system roles", e);
-               }
-       }
-
-       private void loadIpaJaasConfiguration() {
-               if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
-                       String jaasConfig = KernelConstants.JAAS_CONFIG_IPA;
-                       URL url = getClass().getClassLoader().getResource(jaasConfig);
-                       KernelUtils.setJaasConfiguration(url);
-                       log.debug("Set IPA JAAS configuration.");
-               }
-       }
-
-       public void shutdown() {
-//             if (nodeHttp != null)
-//                     nodeHttp.destroy();
-
-               try {
-                       JettyConfigurator.stopServer(KernelConstants.DEFAULT_JETTY_SERVER);
-               } catch (Exception e) {
-                       log.error("Cannot stop default Jetty server.", e);
-               }
-
-               if (deployConfig != null) {
-                       new Thread(() -> deployConfig.save(), "Save Argeo Deploy Config").start();
-               }
-       }
-
-       /**
-        * Checks whether the deployment is available according to expectations, and
-        * mark it as available.
-        */
-       private synchronized void checkReadiness() {
-               if (isAvailable())
-                       return;
-               if (nodeAvailable && userAdminAvailable && (httpExpected ? httpAvailable : true)) {
-                       String data = KernelUtils.getFrameworkProp(KernelUtils.OSGI_INSTANCE_AREA);
-                       String state = KernelUtils.getFrameworkProp(KernelUtils.OSGI_CONFIGURATION_AREA);
-                       availableSince = System.currentTimeMillis();
-                       long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
-                       String jvmUptimeStr = " in " + (jvmUptime / 1000) + "." + (jvmUptime % 1000) + "s";
-                       log.info("## ARGEO NODE AVAILABLE" + (log.isDebugEnabled() ? jvmUptimeStr : "") + " ##");
-                       if (log.isDebugEnabled()) {
-                               log.debug("## state: " + state);
-                               if (data != null)
-                                       log.debug("## data: " + data);
-                       }
-                       long begin = bc.getService(bc.getServiceReference(NodeState.class)).getAvailableSince();
-                       long initDuration = System.currentTimeMillis() - begin;
-                       if (log.isTraceEnabled())
-                               log.trace("Kernel initialization took " + initDuration + "ms");
-                       tributeToFreeSoftware(initDuration);
-               }
-       }
-
-       final private void tributeToFreeSoftware(long initDuration) {
-               if (log.isTraceEnabled()) {
-                       long ms = initDuration / 100;
-                       log.trace("Spend " + ms + "ms" + " reflecting on the progress brought to mankind" + " by Free Software...");
-                       long beginNano = System.nanoTime();
-                       try {
-                               Thread.sleep(ms, 0);
-                       } catch (InterruptedException e) {
-                               // silent
-                       }
-                       long durationNano = System.nanoTime() - beginNano;
-                       final double M = 1000d * 1000d;
-                       double sleepAccuracy = ((double) durationNano) / (ms * M);
-                       log.trace("Sleep accuracy: " + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100)) + " %");
-               }
-       }
-
-       @Override
-       public synchronized Long getAvailableSince() {
-               return availableSince;
-       }
-
-       public synchronized boolean isAvailable() {
-               return availableSince != null;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeploymentImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeploymentImpl.java
new file mode 100644 (file)
index 0000000..4c7cb1d
--- /dev/null
@@ -0,0 +1,243 @@
+package org.argeo.cms.internal.kernel;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.URL;
+import java.util.Dictionary;
+
+import org.argeo.api.cms.CmsState;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsDeployment;
+import org.argeo.osgi.transaction.WorkTransaction;
+import org.argeo.osgi.useradmin.UserAdminConf;
+import org.eclipse.equinox.http.jetty.JettyConfigurator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.UserAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+/** Implementation of a CMS deployment. */
+public class CmsDeploymentImpl implements CmsDeployment {
+       private final CmsLog log = CmsLog.getLog(getClass());
+       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
+
+       private DeployConfig deployConfig;
+
+       private Long availableSince;
+
+       // Readiness
+       private boolean nodeAvailable = false;
+       private boolean userAdminAvailable = false;
+       private boolean httpExpected = false;
+       private boolean httpAvailable = false;
+
+       public CmsDeploymentImpl() {
+//             ServiceReference<NodeState> nodeStateSr = bc.getServiceReference(NodeState.class);
+//             if (nodeStateSr == null)
+//                     throw new CmsException("No node state available");
+
+//             NodeState nodeState = bc.getService(nodeStateSr);
+//             cleanState = nodeState.isClean();
+
+//             nodeHttp = new NodeHttp();
+               initTrackers();
+       }
+
+       private void initTrackers() {
+               ServiceTracker<?, ?> httpSt = new ServiceTracker<HttpService, HttpService>(bc, HttpService.class, null) {
+
+                       @Override
+                       public HttpService addingService(ServiceReference<HttpService> sr) {
+                               httpAvailable = true;
+                               Object httpPort = sr.getProperty("http.port");
+                               Object httpsPort = sr.getProperty("https.port");
+                               log.info(httpPortsMsg(httpPort, httpsPort));
+                               checkReadiness();
+                               return super.addingService(sr);
+                       }
+               };
+               // httpSt.open();
+               KernelUtils.asyncOpen(httpSt);
+
+               ServiceTracker<?, ?> userAdminSt = new ServiceTracker<UserAdmin, UserAdmin>(bc, UserAdmin.class, null) {
+                       @Override
+                       public UserAdmin addingService(ServiceReference<UserAdmin> reference) {
+                               UserAdmin userAdmin = super.addingService(reference);
+                               addStandardSystemRoles(userAdmin);
+                               userAdminAvailable = true;
+                               checkReadiness();
+                               return userAdmin;
+                       }
+               };
+               // userAdminSt.open();
+               KernelUtils.asyncOpen(userAdminSt);
+
+               ServiceTracker<?, ?> confAdminSt = new ServiceTracker<ConfigurationAdmin, ConfigurationAdmin>(bc,
+                               ConfigurationAdmin.class, null) {
+                       @Override
+                       public ConfigurationAdmin addingService(ServiceReference<ConfigurationAdmin> reference) {
+                               ConfigurationAdmin configurationAdmin = bc.getService(reference);
+                               boolean isClean;
+                               try {
+                                       Configuration[] confs = configurationAdmin
+                                                       .listConfigurations("(service.factoryPid=" + CmsConstants.NODE_USER_ADMIN_PID + ")");
+                                       isClean = confs == null || confs.length == 0;
+                               } catch (Exception e) {
+                                       throw new IllegalStateException("Cannot analyse clean state", e);
+                               }
+                               deployConfig = new DeployConfig(configurationAdmin, isClean);
+                               Activator.registerService(CmsDeployment.class, CmsDeploymentImpl.this, null);
+//                             JcrInitUtils.addToDeployment(CmsDeployment.this);
+                               httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
+                               try {
+                                       Configuration[] configs = configurationAdmin
+                                                       .listConfigurations("(service.factoryPid=" + CmsConstants.NODE_USER_ADMIN_PID + ")");
+
+                                       boolean hasDomain = false;
+                                       for (Configuration config : configs) {
+                                               Object realm = config.getProperties().get(UserAdminConf.realm.name());
+                                               if (realm != null) {
+                                                       log.debug("Found realm: " + realm);
+                                                       hasDomain = true;
+                                               }
+                                       }
+                                       if (hasDomain) {
+                                               loadIpaJaasConfiguration();
+                                       }
+                               } catch (Exception e) {
+                                       throw new IllegalStateException("Cannot initialize config", e);
+                               }
+                               return super.addingService(reference);
+                       }
+               };
+               // confAdminSt.open();
+               KernelUtils.asyncOpen(confAdminSt);
+       }
+
+       public void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props) {
+               deployConfig.putFactoryDeployConfig(factoryPid, props);
+               deployConfig.save();
+               try {
+                       deployConfig.loadConfigs();
+               } catch (IOException e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       public Dictionary<String, Object> getProps(String factoryPid, String cn) {
+               return deployConfig.getProps(factoryPid, cn);
+       }
+
+       private String httpPortsMsg(Object httpPort, Object httpsPort) {
+               return (httpPort != null ? "HTTP " + httpPort + " " : " ") + (httpsPort != null ? "HTTPS " + httpsPort : "");
+       }
+
+       private void addStandardSystemRoles(UserAdmin userAdmin) {
+               // we assume UserTransaction is already available (TODO make it more robust)
+               WorkTransaction userTransaction = bc.getService(bc.getServiceReference(WorkTransaction.class));
+               try {
+                       userTransaction.begin();
+                       Role adminRole = userAdmin.getRole(CmsConstants.ROLE_ADMIN);
+                       if (adminRole == null) {
+                               adminRole = userAdmin.createRole(CmsConstants.ROLE_ADMIN, Role.GROUP);
+                       }
+                       if (userAdmin.getRole(CmsConstants.ROLE_USER_ADMIN) == null) {
+                               Group userAdminRole = (Group) userAdmin.createRole(CmsConstants.ROLE_USER_ADMIN, Role.GROUP);
+                               userAdminRole.addMember(adminRole);
+                       }
+                       userTransaction.commit();
+               } catch (Exception e) {
+                       try {
+                               userTransaction.rollback();
+                       } catch (Exception e1) {
+                               // silent
+                       }
+                       throw new IllegalStateException("Cannot add standard system roles", e);
+               }
+       }
+
+       private void loadIpaJaasConfiguration() {
+               if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
+                       String jaasConfig = KernelConstants.JAAS_CONFIG_IPA;
+                       URL url = getClass().getClassLoader().getResource(jaasConfig);
+                       KernelUtils.setJaasConfiguration(url);
+                       log.debug("Set IPA JAAS configuration.");
+               }
+       }
+
+       public void shutdown() {
+//             if (nodeHttp != null)
+//                     nodeHttp.destroy();
+
+               try {
+                       JettyConfigurator.stopServer(KernelConstants.DEFAULT_JETTY_SERVER);
+               } catch (Exception e) {
+                       log.error("Cannot stop default Jetty server.", e);
+               }
+
+               if (deployConfig != null) {
+                       new Thread(() -> deployConfig.save(), "Save Argeo Deploy Config").start();
+               }
+       }
+
+       /**
+        * Checks whether the deployment is available according to expectations, and
+        * mark it as available.
+        */
+       private synchronized void checkReadiness() {
+               if (isAvailable())
+                       return;
+               if (nodeAvailable && userAdminAvailable && (httpExpected ? httpAvailable : true)) {
+                       String data = KernelUtils.getFrameworkProp(KernelUtils.OSGI_INSTANCE_AREA);
+                       String state = KernelUtils.getFrameworkProp(KernelUtils.OSGI_CONFIGURATION_AREA);
+                       availableSince = System.currentTimeMillis();
+                       long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
+                       String jvmUptimeStr = " in " + (jvmUptime / 1000) + "." + (jvmUptime % 1000) + "s";
+                       log.info("## ARGEO NODE AVAILABLE" + (log.isDebugEnabled() ? jvmUptimeStr : "") + " ##");
+                       if (log.isDebugEnabled()) {
+                               log.debug("## state: " + state);
+                               if (data != null)
+                                       log.debug("## data: " + data);
+                       }
+                       long begin = bc.getService(bc.getServiceReference(CmsState.class)).getAvailableSince();
+                       long initDuration = System.currentTimeMillis() - begin;
+                       if (log.isTraceEnabled())
+                               log.trace("Kernel initialization took " + initDuration + "ms");
+                       tributeToFreeSoftware(initDuration);
+               }
+       }
+
+       final private void tributeToFreeSoftware(long initDuration) {
+               if (log.isTraceEnabled()) {
+                       long ms = initDuration / 100;
+                       log.trace("Spend " + ms + "ms" + " reflecting on the progress brought to mankind" + " by Free Software...");
+                       long beginNano = System.nanoTime();
+                       try {
+                               Thread.sleep(ms, 0);
+                       } catch (InterruptedException e) {
+                               // silent
+                       }
+                       long durationNano = System.nanoTime() - beginNano;
+                       final double M = 1000d * 1000d;
+                       double sleepAccuracy = ((double) durationNano) / (ms * M);
+                       log.trace("Sleep accuracy: " + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100)) + " %");
+               }
+       }
+
+       @Override
+       public synchronized Long getAvailableSince() {
+               return availableSince;
+       }
+
+       public synchronized boolean isAvailable() {
+               return availableSince != null;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsInstance.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsInstance.java
deleted file mode 100644 (file)
index 0d65a6c..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.argeo.cms.internal.kernel;
-
-import javax.naming.ldap.LdapName;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeInstance;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-
-public class CmsInstance implements NodeInstance {
-       private final Log log = LogFactory.getLog(getClass());
-       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-//     private EgoRepository egoRepository;
-
-       public CmsInstance() {
-               initTrackers();
-       }
-
-       private void initTrackers() {
-               // node repository
-//             new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
-//                     @Override
-//                     public Repository addingService(ServiceReference<Repository> reference) {
-//                             Object cn = reference.getProperty(NodeConstants.CN);
-//                             if (cn != null && cn.equals(NodeConstants.EGO_REPOSITORY)) {
-////                                   egoRepository = (EgoRepository) bc.getService(reference);
-//                                     if (log.isTraceEnabled())
-//                                             log.trace("Home repository is available");
-//                             }
-//                             return super.addingService(reference);
-//                     }
-//
-//                     @Override
-//                     public void removedService(ServiceReference<Repository> reference, Repository service) {
-//                             super.removedService(reference, service);
-////                           egoRepository = null;
-//                     }
-//
-//             }.open();
-       }
-
-       public void shutdown() {
-
-       }
-
-       @Override
-       public void createWorkgroup(LdapName dn) {
-//             if (egoRepository == null)
-//                     throw new CmsException("Ego repository is not available");
-//             // TODO add check that the group exists
-//             egoRepository.createWorkgroup(dn);
-               throw new UnsupportedOperationException();
-       }
-
-}
index bfc58501c48ee1b4c0b8f5766524b6c4d18ccb9e..eb7657edc22380484e866d3b9d516a5f67b83443 100644 (file)
@@ -1,7 +1,6 @@
 package org.argeo.cms.internal.kernel;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.FrameworkEvent;
 import org.osgi.framework.FrameworkUtil;
@@ -14,7 +13,7 @@ class CmsShutdown extends Thread {
        public final int EXIT_TIMEOUT = 2;
        public final int EXIT_UNKNOWN = 3;
 
-       private final Log log = LogFactory.getLog(CmsShutdown.class);
+       private final CmsLog log = CmsLog.getLog(CmsShutdown.class);
        // private final BundleContext bc =
        // FrameworkUtil.getBundle(CmsShutdown.class).getBundleContext();
        private final Framework framework;
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java
deleted file mode 100644 (file)
index 219f2d5..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-package org.argeo.cms.internal.kernel;
-
-import static java.util.Locale.ENGLISH;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeState;
-import org.argeo.cms.LocaleUtils;
-import org.argeo.osgi.transaction.SimpleTransactionManager;
-import org.argeo.osgi.transaction.WorkControl;
-import org.argeo.osgi.transaction.WorkTransaction;
-import org.argeo.util.LangUtils;
-import org.osgi.framework.Constants;
-import org.osgi.service.cm.ManagedServiceFactory;
-
-/**
- * Implementation of a {@link NodeState}, initialising the required services.
- */
-public class CmsState implements NodeState {
-       private final static Log log = LogFactory.getLog(CmsState.class);
-//     private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext();
-
-       // REFERENCES
-       private Long availableSince;
-
-       // i18n
-       private Locale defaultLocale;
-       private List<Locale> locales = null;
-
-       private ThreadGroup threadGroup = new ThreadGroup("CMS");
-       private List<Runnable> stopHooks = new ArrayList<>();
-
-       private final String stateUuid;
-//     private final boolean cleanState;
-       private String hostname;
-
-       public CmsState() {
-//             this.stateUuid = stateUuid;
-               this.stateUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID);
-//             this.cleanState = stateUuid.equals(frameworkUuid);
-               try {
-                       this.hostname = InetAddress.getLocalHost().getHostName();
-               } catch (UnknownHostException e) {
-                       log.error("Cannot set hostname: " + e);
-               }
-
-               availableSince = System.currentTimeMillis();
-               if (log.isDebugEnabled())
-                       // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? "
-                       // (clean state) " : " "));
-                       log.debug("## CMS starting... (" + stateUuid + ")");
-
-               initI18n();
-               initServices();
-
-       }
-
-       private void initI18n() {
-               Object defaultLocaleValue = KernelUtils.getFrameworkProp(NodeConstants.I18N_DEFAULT_LOCALE);
-               defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
-                               : new Locale(ENGLISH.getLanguage());
-               locales = LocaleUtils.asLocaleList(KernelUtils.getFrameworkProp(NodeConstants.I18N_LOCALES));
-       }
-
-       private void initServices() {
-               // JTA
-               String tmType = KernelUtils.getFrameworkProp(NodeConstants.TRANSACTION_MANAGER,
-                               NodeConstants.TRANSACTION_MANAGER_SIMPLE);
-               if (NodeConstants.TRANSACTION_MANAGER_SIMPLE.equals(tmType)) {
-                       initSimpleTransactionManager();
-               } else if (NodeConstants.TRANSACTION_MANAGER_BITRONIX.equals(tmType)) {
-//                     initBitronixTransactionManager();
-                       throw new UnsupportedOperationException(
-                                       "Bitronix is not supported anymore, but could be again if there is enough interest.");
-               } else {
-                       throw new IllegalArgumentException("Usupported transaction manager type " + tmType);
-               }
-
-               // POI
-//             POIXMLTypeLoader.setClassLoader(CTConnection.class.getClassLoader());
-
-               // Tika
-//             OpenDocumentParser odfParser = new OpenDocumentParser();
-//             bc.registerService(Parser.class, odfParser, new Hashtable());
-//             PDFParser pdfParser = new PDFParser();
-//             bc.registerService(Parser.class, pdfParser, new Hashtable());
-//             OOXMLParser ooxmlParser = new OOXMLParser();
-//             bc.registerService(Parser.class, ooxmlParser, new Hashtable());
-//             TesseractOCRParser ocrParser = new TesseractOCRParser();
-//             ocrParser.setLanguage("ara");
-//             bc.registerService(Parser.class, ocrParser, new Hashtable());
-
-//             // JCR
-//             RepositoryServiceFactory repositoryServiceFactory = new RepositoryServiceFactory();
-//             stopHooks.add(() -> repositoryServiceFactory.shutdown());
-//             Activator.registerService(ManagedServiceFactory.class, repositoryServiceFactory,
-//                             LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID));
-//
-//             NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory();
-//             Activator.registerService(RepositoryFactory.class, repositoryFactory, null);
-
-               // Security
-               NodeUserAdmin userAdmin = new NodeUserAdmin(NodeConstants.ROLES_BASEDN, NodeConstants.TOKENS_BASEDN);
-               stopHooks.add(() -> userAdmin.destroy());
-               Activator.registerService(ManagedServiceFactory.class, userAdmin,
-                               LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_USER_ADMIN_PID));
-
-       }
-
-       private void initSimpleTransactionManager() {
-               SimpleTransactionManager transactionManager = new SimpleTransactionManager();
-               Activator.registerService(WorkControl.class, transactionManager, null);
-               Activator.registerService(WorkTransaction.class, transactionManager, null);
-//             Activator.registerService(TransactionManager.class, transactionManager, null);
-//             Activator.registerService(UserTransaction.class, transactionManager, null);
-               // TODO TransactionSynchronizationRegistry
-       }
-
-//     private void initBitronixTransactionManager() {
-//             // TODO manage it in a managed service, as startup could be long
-//             ServiceReference<TransactionManager> existingTm = bc.getServiceReference(TransactionManager.class);
-//             if (existingTm != null) {
-//                     if (log.isDebugEnabled())
-//                             log.debug("Using provided transaction manager " + existingTm);
-//                     return;
-//             }
-//
-//             if (!TransactionManagerServices.isTransactionManagerRunning()) {
-//                     bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration();
-//                     tmConf.setServerId(UUID.randomUUID().toString());
-//
-//                     Bundle bitronixBundle = FrameworkUtil.getBundle(bitronix.tm.Configuration.class);
-//                     File tmBaseDir = bitronixBundle.getDataFile(KernelConstants.DIR_TRANSACTIONS);
-//                     File tmDir1 = new File(tmBaseDir, "btm1");
-//                     tmDir1.mkdirs();
-//                     tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath());
-//                     File tmDir2 = new File(tmBaseDir, "btm2");
-//                     tmDir2.mkdirs();
-//                     tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath());
-//             }
-//             BitronixTransactionManager transactionManager = getTransactionManager();
-//             stopHooks.add(() -> transactionManager.shutdown());
-//             BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry = getTransactionSynchronizationRegistry();
-//             // register
-//             bc.registerService(TransactionManager.class, transactionManager, null);
-//             bc.registerService(UserTransaction.class, transactionManager, null);
-//             bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null);
-//             if (log.isDebugEnabled())
-//                     log.debug("Initialised default Bitronix transaction manager");
-//     }
-
-       void shutdown() {
-               if (log.isDebugEnabled())
-                       log.debug("CMS stopping...  (" + this.stateUuid + ")");
-
-               // In a different thread in order to avoid interruptions
-               Thread stopHookThread = new Thread(() -> applyStopHooks(), "Apply Argeo Stop Hooks");
-               stopHookThread.start();
-               try {
-                       stopHookThread.join(10 * 60 * 1000);
-               } catch (InterruptedException e) {
-                       // silent
-               }
-
-               long duration = ((System.currentTimeMillis() - availableSince) / 1000) / 60;
-               log.info("## ARGEO CMS STOPPED after " + (duration / 60) + "h " + (duration % 60) + "min uptime ##");
-       }
-
-       /** Apply shutdown hoos in reverse order. */
-       private void applyStopHooks() {
-               for (int i = stopHooks.size() - 1; i >= 0; i--) {
-                       try {
-                               stopHooks.get(i).run();
-                       } catch (Exception e) {
-                               log.error("Could not run shutdown hook #" + i);
-                       }
-               }
-               // Clean hanging Gogo shell thread
-               new GogoShellKiller().start();
-       }
-
-//     @Override
-//     public boolean isClean() {
-//             return cleanState;
-//     }
-
-       @Override
-       public Long getAvailableSince() {
-               return availableSince;
-       }
-
-       /*
-        * ACCESSORS
-        */
-       public Locale getDefaultLocale() {
-               return defaultLocale;
-       }
-
-       public List<Locale> getLocales() {
-               return locales;
-       }
-
-       public String getHostname() {
-               return hostname;
-       }
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsStateImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsStateImpl.java
new file mode 100644 (file)
index 0000000..6bc8ac8
--- /dev/null
@@ -0,0 +1,212 @@
+package org.argeo.cms.internal.kernel;
+
+import static java.util.Locale.ENGLISH;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import org.argeo.api.cms.CmsState;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.cms.LocaleUtils;
+import org.argeo.osgi.transaction.SimpleTransactionManager;
+import org.argeo.osgi.transaction.WorkControl;
+import org.argeo.osgi.transaction.WorkTransaction;
+import org.argeo.util.LangUtils;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+/**
+ * Implementation of a {@link CmsState}, initialising the required services.
+ */
+public class CmsStateImpl implements CmsState {
+       private final static CmsLog log = CmsLog.getLog(CmsStateImpl.class);
+//     private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext();
+
+       // REFERENCES
+       private Long availableSince;
+
+       // i18n
+       private Locale defaultLocale;
+       private List<Locale> locales = null;
+
+       private ThreadGroup threadGroup = new ThreadGroup("CMS");
+       private List<Runnable> stopHooks = new ArrayList<>();
+
+       private final String stateUuid;
+//     private final boolean cleanState;
+       private String hostname;
+
+       public CmsStateImpl() {
+//             this.stateUuid = stateUuid;
+               this.stateUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID);
+//             this.cleanState = stateUuid.equals(frameworkUuid);
+               try {
+                       this.hostname = InetAddress.getLocalHost().getHostName();
+               } catch (UnknownHostException e) {
+                       log.error("Cannot set hostname: " + e);
+               }
+
+               availableSince = System.currentTimeMillis();
+               if (log.isDebugEnabled())
+                       // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? "
+                       // (clean state) " : " "));
+                       log.debug("## CMS starting... (" + stateUuid + ")");
+
+               initI18n();
+               initServices();
+
+       }
+
+       private void initI18n() {
+               Object defaultLocaleValue = KernelUtils.getFrameworkProp(CmsConstants.I18N_DEFAULT_LOCALE);
+               defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
+                               : new Locale(ENGLISH.getLanguage());
+               locales = LocaleUtils.asLocaleList(KernelUtils.getFrameworkProp(CmsConstants.I18N_LOCALES));
+       }
+
+       private void initServices() {
+               // JTA
+               String tmType = KernelUtils.getFrameworkProp(CmsConstants.TRANSACTION_MANAGER,
+                               CmsConstants.TRANSACTION_MANAGER_SIMPLE);
+               if (CmsConstants.TRANSACTION_MANAGER_SIMPLE.equals(tmType)) {
+                       initSimpleTransactionManager();
+               } else if (CmsConstants.TRANSACTION_MANAGER_BITRONIX.equals(tmType)) {
+//                     initBitronixTransactionManager();
+                       throw new UnsupportedOperationException(
+                                       "Bitronix is not supported anymore, but could be again if there is enough interest.");
+               } else {
+                       throw new IllegalArgumentException("Usupported transaction manager type " + tmType);
+               }
+
+               // POI
+//             POIXMLTypeLoader.setClassLoader(CTConnection.class.getClassLoader());
+
+               // Tika
+//             OpenDocumentParser odfParser = new OpenDocumentParser();
+//             bc.registerService(Parser.class, odfParser, new Hashtable());
+//             PDFParser pdfParser = new PDFParser();
+//             bc.registerService(Parser.class, pdfParser, new Hashtable());
+//             OOXMLParser ooxmlParser = new OOXMLParser();
+//             bc.registerService(Parser.class, ooxmlParser, new Hashtable());
+//             TesseractOCRParser ocrParser = new TesseractOCRParser();
+//             ocrParser.setLanguage("ara");
+//             bc.registerService(Parser.class, ocrParser, new Hashtable());
+
+//             // JCR
+//             RepositoryServiceFactory repositoryServiceFactory = new RepositoryServiceFactory();
+//             stopHooks.add(() -> repositoryServiceFactory.shutdown());
+//             Activator.registerService(ManagedServiceFactory.class, repositoryServiceFactory,
+//                             LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID));
+//
+//             NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory();
+//             Activator.registerService(RepositoryFactory.class, repositoryFactory, null);
+
+               // Security
+               NodeUserAdmin userAdmin = new NodeUserAdmin(CmsConstants.ROLES_BASEDN, CmsConstants.TOKENS_BASEDN);
+               stopHooks.add(() -> userAdmin.destroy());
+               Activator.registerService(ManagedServiceFactory.class, userAdmin,
+                               LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_USER_ADMIN_PID));
+
+       }
+
+       private void initSimpleTransactionManager() {
+               SimpleTransactionManager transactionManager = new SimpleTransactionManager();
+               Activator.registerService(WorkControl.class, transactionManager, null);
+               Activator.registerService(WorkTransaction.class, transactionManager, null);
+//             Activator.registerService(TransactionManager.class, transactionManager, null);
+//             Activator.registerService(UserTransaction.class, transactionManager, null);
+               // TODO TransactionSynchronizationRegistry
+       }
+
+//     private void initBitronixTransactionManager() {
+//             // TODO manage it in a managed service, as startup could be long
+//             ServiceReference<TransactionManager> existingTm = bc.getServiceReference(TransactionManager.class);
+//             if (existingTm != null) {
+//                     if (log.isDebugEnabled())
+//                             log.debug("Using provided transaction manager " + existingTm);
+//                     return;
+//             }
+//
+//             if (!TransactionManagerServices.isTransactionManagerRunning()) {
+//                     bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration();
+//                     tmConf.setServerId(UUID.randomUUID().toString());
+//
+//                     Bundle bitronixBundle = FrameworkUtil.getBundle(bitronix.tm.Configuration.class);
+//                     File tmBaseDir = bitronixBundle.getDataFile(KernelConstants.DIR_TRANSACTIONS);
+//                     File tmDir1 = new File(tmBaseDir, "btm1");
+//                     tmDir1.mkdirs();
+//                     tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath());
+//                     File tmDir2 = new File(tmBaseDir, "btm2");
+//                     tmDir2.mkdirs();
+//                     tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath());
+//             }
+//             BitronixTransactionManager transactionManager = getTransactionManager();
+//             stopHooks.add(() -> transactionManager.shutdown());
+//             BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry = getTransactionSynchronizationRegistry();
+//             // register
+//             bc.registerService(TransactionManager.class, transactionManager, null);
+//             bc.registerService(UserTransaction.class, transactionManager, null);
+//             bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null);
+//             if (log.isDebugEnabled())
+//                     log.debug("Initialised default Bitronix transaction manager");
+//     }
+
+       void shutdown() {
+               if (log.isDebugEnabled())
+                       log.debug("CMS stopping...  (" + this.stateUuid + ")");
+
+               // In a different thread in order to avoid interruptions
+               Thread stopHookThread = new Thread(() -> applyStopHooks(), "Apply Argeo Stop Hooks");
+               stopHookThread.start();
+               try {
+                       stopHookThread.join(10 * 60 * 1000);
+               } catch (InterruptedException e) {
+                       // silent
+               }
+
+               long duration = ((System.currentTimeMillis() - availableSince) / 1000) / 60;
+               log.info("## ARGEO CMS STOPPED after " + (duration / 60) + "h " + (duration % 60) + "min uptime ##");
+       }
+
+       /** Apply shutdown hoos in reverse order. */
+       private void applyStopHooks() {
+               for (int i = stopHooks.size() - 1; i >= 0; i--) {
+                       try {
+                               stopHooks.get(i).run();
+                       } catch (Exception e) {
+                               log.error("Could not run shutdown hook #" + i);
+                       }
+               }
+               // Clean hanging Gogo shell thread
+               new GogoShellKiller().start();
+       }
+
+//     @Override
+//     public boolean isClean() {
+//             return cleanState;
+//     }
+
+       @Override
+       public Long getAvailableSince() {
+               return availableSince;
+       }
+
+       /*
+        * ACCESSORS
+        */
+       public Locale getDefaultLocale() {
+               return defaultLocale;
+       }
+
+       public List<Locale> getLocales() {
+               return locales;
+       }
+
+       public String getHostname() {
+               return hostname;
+       }
+}
index 2f60b73374035c6f6e6b8243179c286eaea33796..4a88dd1b499e4fd3e15c67d64512108d846d34a3 100644 (file)
@@ -18,13 +18,12 @@ import javax.naming.directory.BasicAttributes;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.naming.AttributesDictionary;
-import org.argeo.naming.LdifParser;
-import org.argeo.naming.LdifWriter;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.osgi.useradmin.UserAdminConf;
+import org.argeo.util.naming.AttributesDictionary;
+import org.argeo.util.naming.LdifParser;
+import org.argeo.util.naming.LdifWriter;
 import org.eclipse.equinox.http.jetty.JettyConfigurator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -35,7 +34,7 @@ import org.osgi.service.cm.ConfigurationListener;
 
 /** Manages the LDIF-based deployment configuration. */
 class DeployConfig implements ConfigurationListener {
-       private final Log log = LogFactory.getLog(getClass());
+       private final CmsLog log = CmsLog.getLog(getClass());
        private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
 
        private static Path deployConfigPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH);
@@ -92,16 +91,16 @@ class DeployConfig implements ConfigurationListener {
                                Dictionary<String, Object> userDirectoryConfig = userDirectoryConfigs.get(i);
                                String baseDn = (String) userDirectoryConfig.get(UserAdminConf.baseDn.name());
                                String cn;
-                               if (NodeConstants.ROLES_BASEDN.equals(baseDn))
+                               if (CmsConstants.ROLES_BASEDN.equals(baseDn))
                                        cn = ROLES;
                                else
                                        cn = UserAdminConf.baseDnHash(userDirectoryConfig);
                                activeCns.add(cn);
-                               userDirectoryConfig.put(NodeConstants.CN, cn);
-                               putFactoryDeployConfig(NodeConstants.NODE_USER_ADMIN_PID, userDirectoryConfig);
+                               userDirectoryConfig.put(CmsConstants.CN, cn);
+                               putFactoryDeployConfig(CmsConstants.NODE_USER_ADMIN_PID, userDirectoryConfig);
                        }
                        // disable others
-                       LdapName userAdminFactoryName = serviceFactoryDn(NodeConstants.NODE_USER_ADMIN_PID);
+                       LdapName userAdminFactoryName = serviceFactoryDn(CmsConstants.NODE_USER_ADMIN_PID);
                        for (LdapName name : deployConfigs.keySet()) {
                                if (name.startsWith(userAdminFactoryName) && !name.equals(userAdminFactoryName)) {
 //                                     try {
@@ -125,7 +124,7 @@ class DeployConfig implements ConfigurationListener {
 //                     webServerConfig.put("customizer.class", "org.argeo.equinox.jetty.CmsJettyCustomizer");
 //                     putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig);
 //             }
-               LdapName defaultHttpServiceDn = serviceDn(KernelConstants.JETTY_FACTORY_PID, NodeConstants.DEFAULT);
+               LdapName defaultHttpServiceDn = serviceDn(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT);
                if (deployConfigs.containsKey(defaultHttpServiceDn)) {
                        // remove old default configs since we have now to start Jetty servlet bridge
                        // indirectly
@@ -139,7 +138,7 @@ class DeployConfig implements ConfigurationListener {
                // Explicitly configures Jetty so that the default server is not started by the
                // activator of the Equinox Jetty bundle.
                Dictionary<String, Object> webServerConfig = InitUtils
-                               .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, NodeConstants.DEFAULT));
+                               .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT));
 //             if (!webServerConfig.isEmpty()) {
 //                     webServerConfig.put("customizer.class", KernelConstants.CMS_JETTY_CUSTOMIZER_CLASS);
 //
@@ -203,8 +202,8 @@ class DeployConfig implements ConfigurationListener {
                deployConfigs: for (LdapName dn : deployConfigs.keySet()) {
                        Rdn lastRdn = dn.getRdn(dn.size() - 1);
                        LdapName prefix = (LdapName) dn.getPrefix(dn.size() - 1);
-                       if (prefix.toString().equals(NodeConstants.DEPLOY_BASEDN)) {
-                               if (lastRdn.getType().equals(NodeConstants.CN)) {
+                       if (prefix.toString().equals(CmsConstants.DEPLOY_BASEDN)) {
+                               if (lastRdn.getType().equals(CmsConstants.CN)) {
                                        // service
                                        String pid = lastRdn.getValue().toString();
                                        Configuration conf = configurationAdmin.getConfiguration(pid);
@@ -220,7 +219,7 @@ class DeployConfig implements ConfigurationListener {
                                        continue deployConfigs;
                                // service factory service
                                Rdn beforeLastRdn = dn.getRdn(dn.size() - 2);
-                               assert beforeLastRdn.getType().equals(NodeConstants.OU);
+                               assert beforeLastRdn.getType().equals(CmsConstants.OU);
                                String factoryPid = beforeLastRdn.getValue().toString();
                                Configuration conf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null);
                                if (systemRolesDn.equals(dn)) {
@@ -253,7 +252,7 @@ class DeployConfig implements ConfigurationListener {
                                                for (LdapName dn : deployConfigs.keySet()) {
                                                        if (dn.startsWith(serviceFactoryDn)) {
                                                                Rdn lastRdn = dn.getRdn(dn.size() - 1);
-                                                               assert lastRdn.getType().equals(NodeConstants.CN);
+                                                               assert lastRdn.getType().equals(CmsConstants.CN);
                                                                Object value = conf.getProperties().get(lastRdn.getType());
                                                                assert value != null;
                                                                if (value.equals(lastRdn.getValue())) {
@@ -263,7 +262,7 @@ class DeployConfig implements ConfigurationListener {
                                                        }
                                                }
 
-                                               Object cn = conf.getProperties().get(NodeConstants.CN);
+                                               Object cn = conf.getProperties().get(CmsConstants.CN);
                                                if (cn == null)
                                                        throw new IllegalArgumentException("Properties must contain cn");
                                                if (serviceDn == null) {
@@ -299,12 +298,12 @@ class DeployConfig implements ConfigurationListener {
        }
 
        void putFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props) {
-               Object cn = props.get(NodeConstants.CN);
+               Object cn = props.get(CmsConstants.CN);
                if (cn == null)
                        throw new IllegalArgumentException("cn must be set in properties");
                LdapName serviceFactoryDn = serviceFactoryDn(factoryPid);
                if (!deployConfigs.containsKey(serviceFactoryDn))
-                       deployConfigs.put(serviceFactoryDn, new BasicAttributes(NodeConstants.OU, factoryPid));
+                       deployConfigs.put(serviceFactoryDn, new BasicAttributes(CmsConstants.OU, factoryPid));
                LdapName serviceDn = serviceDn(factoryPid, cn.toString());
                Attributes attrs = new BasicAttributes();
                AttributesDictionary.copy(props, attrs);
@@ -313,7 +312,7 @@ class DeployConfig implements ConfigurationListener {
 
        void putDeployConfig(String servicePid, Dictionary<String, Object> props) {
                LdapName serviceDn = serviceDn(servicePid);
-               Attributes attrs = new BasicAttributes(NodeConstants.CN, servicePid);
+               Attributes attrs = new BasicAttributes(CmsConstants.CN, servicePid);
                AttributesDictionary.copy(props, attrs);
                deployConfigs.put(serviceDn, attrs);
        }
@@ -332,7 +331,7 @@ class DeployConfig implements ConfigurationListener {
         */
        private LdapName serviceFactoryDn(String factoryPid) {
                try {
-                       return new LdapName(NodeConstants.OU + "=" + factoryPid + "," + NodeConstants.DEPLOY_BASEDN);
+                       return new LdapName(CmsConstants.OU + "=" + factoryPid + "," + CmsConstants.DEPLOY_BASEDN);
                } catch (InvalidNameException e) {
                        throw new IllegalArgumentException("Cannot generate DN from " + factoryPid, e);
                }
@@ -340,7 +339,7 @@ class DeployConfig implements ConfigurationListener {
 
        private LdapName serviceDn(String servicePid) {
                try {
-                       return new LdapName(NodeConstants.CN + "=" + servicePid + "," + NodeConstants.DEPLOY_BASEDN);
+                       return new LdapName(CmsConstants.CN + "=" + servicePid + "," + CmsConstants.DEPLOY_BASEDN);
                } catch (InvalidNameException e) {
                        throw new IllegalArgumentException("Cannot generate DN from " + servicePid, e);
                }
@@ -348,7 +347,7 @@ class DeployConfig implements ConfigurationListener {
 
        private LdapName serviceDn(String factoryPid, String cn) {
                try {
-                       return (LdapName) serviceFactoryDn(factoryPid).add(new Rdn(NodeConstants.CN, cn));
+                       return (LdapName) serviceFactoryDn(factoryPid).add(new Rdn(CmsConstants.CN, cn));
                } catch (InvalidNameException e) {
                        throw new IllegalArgumentException("Cannot generate DN from " + factoryPid + " and " + cn, e);
                }
index 98b625a98e4effc29da792ee8a09aff591e71236..a2006a7049e306018c57902fb86c636e417fc904 100644 (file)
@@ -21,9 +21,8 @@ import java.util.List;
 import javax.security.auth.x500.X500Principal;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.http.InternalHttpConstants;
 import org.argeo.osgi.useradmin.UserAdminConf;
 
@@ -32,7 +31,7 @@ import org.argeo.osgi.useradmin.UserAdminConf;
  * configuration.
  */
 class InitUtils {
-       private final static Log log = LogFactory.getLog(InitUtils.class);
+       private final static CmsLog log = CmsLog.getLog(InitUtils.class);
 
 
        /** Override the provided config with the framework properties */
@@ -118,7 +117,7 @@ class InitUtils {
                        if (webSocketEnabled != null && webSocketEnabled.equals("true"))
                                props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true);
 
-                       props.put(NodeConstants.CN, NodeConstants.DEFAULT);
+                       props.put(CmsConstants.CN, CmsConstants.DEFAULT);
                }
                return props;
        }
@@ -129,8 +128,8 @@ class InitUtils {
                List<String> uris = new ArrayList<>();
 
                // node roles
-               String nodeRolesUri = getFrameworkProp(NodeConstants.ROLES_URI);
-               String baseNodeRoleDn = NodeConstants.ROLES_BASEDN;
+               String nodeRolesUri = getFrameworkProp(CmsConstants.ROLES_URI);
+               String baseNodeRoleDn = CmsConstants.ROLES_BASEDN;
                if (nodeRolesUri == null) {
                        nodeRolesUri = baseNodeRoleDn + ".ldif";
                        File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri);
@@ -146,8 +145,8 @@ class InitUtils {
                uris.add(nodeRolesUri);
 
                // node tokens
-               String nodeTokensUri = getFrameworkProp(NodeConstants.TOKENS_URI);
-               String baseNodeTokensDn = NodeConstants.TOKENS_BASEDN;
+               String nodeTokensUri = getFrameworkProp(CmsConstants.TOKENS_URI);
+               String baseNodeTokensDn = CmsConstants.TOKENS_BASEDN;
                if (nodeTokensUri == null) {
                        nodeTokensUri = baseNodeTokensDn + ".ldif";
                        File nodeTokensFile = new File(nodeBaseDir, nodeTokensUri);
@@ -163,7 +162,7 @@ class InitUtils {
                uris.add(nodeTokensUri);
 
                // Business roles
-               String userAdminUris = getFrameworkProp(NodeConstants.USERADMIN_URIS);
+               String userAdminUris = getFrameworkProp(CmsConstants.USERADMIN_URIS);
                if (userAdminUris == null) {
                        String demoBaseDn = "dc=example,dc=com";
                        userAdminUris = demoBaseDn + ".ldif";
@@ -220,7 +219,7 @@ class InitUtils {
         * some files (typically LDIF, etc).
         */
        static void prepareFirstInitInstanceArea() {
-               String nodeInits = getFrameworkProp(NodeConstants.NODE_INIT);
+               String nodeInits = getFrameworkProp(CmsConstants.NODE_INIT);
                if (nodeInits == null)
                        nodeInits = "../../init";
 
index 7d14ae9e619d2492083501bcac9440f2e16d5551..90f2382d7e493ee5440606c32f7358ebbb79224c 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.internal.kernel;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 
 /** Internal CMS constants. */
 public interface KernelConstants {
@@ -11,10 +11,10 @@ public interface KernelConstants {
        String DIR_TRANSACTIONS = "transactions";
 
        // Files
-       String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif";
-       String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".p12";
-       String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".key";
-       String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".crt";
+       String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif";
+       String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".p12";
+       String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".key";
+       String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".crt";
        String NODE_KEY_TAB_PATH = DIR_NODE + "/krb5.keytab";
 
        // Security
index f29d9e98e9420a78b89d14d5a9c38180bf00c1b7..f267933cf5910de37b95213d30bab126c34cf8bd 100644 (file)
@@ -15,7 +15,7 @@ import java.util.Properties;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
-import org.apache.commons.logging.Log;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.osgi.DataModelNamespace;
 import org.osgi.framework.BundleContext;
 import org.osgi.util.tracker.ServiceTracker;
@@ -120,7 +120,7 @@ class KernelUtils implements KernelConstants {
        // }
        // }
 
-       static void logFrameworkProperties(Log log) {
+       static void logFrameworkProperties(CmsLog log) {
                BundleContext bc = getBundleContext();
                for (Object sysProp : new TreeSet<Object>(System.getProperties().keySet())) {
                        log.debug(sysProp + "=" + bc.getProperty(sysProp.toString()));
index 89c7e05a67d9a9c8b2c2024c2203424660f3456a..0b410379402af36dfaa35fe21b75b3d7c5822be5 100644 (file)
@@ -23,11 +23,10 @@ import java.util.Properties;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.ArgeoLogListener;
-import org.argeo.api.ArgeoLogger;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.ArgeoLogListener;
+import org.argeo.cms.ArgeoLogger;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.osgi.useradmin.UserAdminConf;
@@ -151,7 +150,7 @@ class NodeLogger implements ArgeoLogger, LogListener {
        //
        @Override
        public void logged(LogEntry status) {
-               Log pluginLog = LogFactory.getLog(status.getBundle().getSymbolicName());
+               CmsLog pluginLog = CmsLog.getLog(status.getBundle().getSymbolicName());
                LogLevel severity = status.getLogLevel();
                if (severity.equals(LogLevel.ERROR) && pluginLog.isErrorEnabled()) {
                        // FIXME Fix Argeo TP
@@ -190,9 +189,9 @@ class NodeLogger implements ArgeoLogger, LogListener {
                        } else {
                                sb.append(arrayToString(objectClasses));
                        }
-                       Object cn = sr.getProperty(NodeConstants.CN);
+                       Object cn = sr.getProperty(CmsConstants.CN);
                        if (cn != null)
-                               sb.append(" " + NodeConstants.CN + ": " + cn);
+                               sb.append(" " + CmsConstants.CN + ": " + cn);
                        Object factoryPid = sr.getProperty(ConfigurationAdmin.SERVICE_FACTORYPID);
                        if (factoryPid != null)
                                sb.append(" " + ConfigurationAdmin.SERVICE_FACTORYPID + ": " + factoryPid);
index 11efa9e0f9dc9920520b9f800a9b7c17d9061bce..17daa3e14ae15b33f8af32f1dfe6560a9c6c04cb 100644 (file)
@@ -31,14 +31,13 @@ import org.apache.commons.httpclient.auth.CredentialsProvider;
 import org.apache.commons.httpclient.params.DefaultHttpParams;
 import org.apache.commons.httpclient.params.HttpMethodParams;
 import org.apache.commons.httpclient.params.HttpParams;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsUserManager;
 import org.argeo.cms.internal.auth.CmsUserManagerImpl;
 import org.argeo.cms.internal.http.client.HttpCredentialProvider;
 import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
-import org.argeo.naming.DnsBrowser;
 import org.argeo.osgi.transaction.WorkControl;
 import org.argeo.osgi.transaction.WorkTransaction;
 import org.argeo.osgi.useradmin.AbstractUserDirectory;
@@ -48,6 +47,7 @@ import org.argeo.osgi.useradmin.LdifUserAdmin;
 import org.argeo.osgi.useradmin.OsUserDirectory;
 import org.argeo.osgi.useradmin.UserAdminConf;
 import org.argeo.osgi.useradmin.UserDirectory;
+import org.argeo.util.naming.DnsBrowser;
 import org.ietf.jgss.GSSCredential;
 import org.ietf.jgss.GSSException;
 import org.ietf.jgss.GSSManager;
@@ -67,7 +67,7 @@ import org.osgi.util.tracker.ServiceTracker;
  * roles.
  */
 class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactory, KernelConstants {
-       private final static Log log = LogFactory.getLog(NodeUserAdmin.class);
+       private final static CmsLog log = CmsLog.getLog(NodeUserAdmin.class);
 //     private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
 
        // OSGi
@@ -166,7 +166,7 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
                if (isSystemRolesBaseDn(baseDn)) {
                        // publishes only when system roles are available
                        Dictionary<String, Object> userAdminregProps = new Hashtable<>();
-                       userAdminregProps.put(NodeConstants.CN, NodeConstants.DEFAULT);
+                       userAdminregProps.put(CmsConstants.CN, CmsConstants.DEFAULT);
                        userAdminregProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
                        Activator.registerService(UserAdmin.class, this, userAdminregProps);
                }
@@ -205,9 +205,9 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
        @Override
        protected void addAbstractSystemRoles(Authorization rawAuthorization, Set<String> sysRoles) {
                if (rawAuthorization.getName() == null) {
-                       sysRoles.add(NodeConstants.ROLE_ANONYMOUS);
+                       sysRoles.add(CmsConstants.ROLE_ANONYMOUS);
                } else {
-                       sysRoles.add(NodeConstants.ROLE_USER);
+                       sysRoles.add(CmsConstants.ROLE_USER);
                }
        }
 
@@ -235,7 +235,7 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
                                                }
                                        };
                                        try {
-                                               LoginContext nodeLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_NODE, callbackHandler);
+                                               LoginContext nodeLc = new LoginContext(CmsAuth.LOGIN_CONTEXT_NODE, callbackHandler);
                                                nodeLc.login();
                                                acceptorCredentials = logInAsAcceptor(nodeLc.getSubject(), servicePrincipal);
                                        } catch (LoginException e) {
index cf16719bd0c3470b96c5f60e798b284cb56bd6b7..c7c804c649ef13b561e57d3611301c9f9c07faaf 100644 (file)
@@ -11,7 +11,7 @@ ANONYMOUS {
 };
 
 DATA_ADMIN {
-    org.argeo.api.DataAdminLoginModule requisite;
+    org.argeo.cms.auth.DataAdminLoginModule requisite;
 };
 
 NODE {
@@ -19,7 +19,7 @@ NODE {
      keyTab="${osgi.instance.area}node/krb5.keytab" 
      useKeyTab=true
      storeKey=true;
-    org.argeo.api.DataAdminLoginModule requisite;
+    org.argeo.cms.auth.DataAdminLoginModule requisite;
 };
 
 KEYRING {
index 441e1bf2a477cd64d745de494c6d2383ecb5d36b..364977d4b3b9054cac876bb96a05007f8739ba9d 100644 (file)
@@ -10,11 +10,11 @@ ANONYMOUS {
 };
 
 DATA_ADMIN {
-    org.argeo.api.DataAdminLoginModule requisite;
+    org.argeo.cms.auth.DataAdminLoginModule requisite;
 };
 
 NODE {
-    org.argeo.api.DataAdminLoginModule requisite;
+    org.argeo.cms.auth.DataAdminLoginModule requisite;
 };
 
 KEYRING {
index cc8294da775abaeed04f7f2195e0126a804091aa..08ac5493613758af5d4123f6441a83f3674b2e9e 100644 (file)
@@ -26,10 +26,7 @@ import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
 import org.apache.commons.io.IOUtils;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.security.CryptoKeyring;
-import org.argeo.api.security.Keyring;
-import org.argeo.api.security.PBEKeySpecCallback;
+import org.argeo.api.cms.CmsAuth;
 import org.argeo.cms.CmsException;
 
 /** username / password based keyring. TODO internationalize */
@@ -77,7 +74,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                        ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
                        try {
-                               LoginContext loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_KEYRING, subject,
+                               LoginContext loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_KEYRING, subject,
                                                callbackHandler);
                                loginContext.login();
                                // FIXME will login even if password is wrong
diff --git a/org.argeo.cms/src/org/argeo/cms/security/CryptoKeyring.java b/org.argeo.cms/src/org/argeo/cms/security/CryptoKeyring.java
new file mode 100644 (file)
index 0000000..df26c6b
--- /dev/null
@@ -0,0 +1,10 @@
+package org.argeo.cms.security;
+
+/**
+ * Marker interface for an advanced keyring based on cryptography.
+ */
+public interface CryptoKeyring extends Keyring {
+       public void changePassword(char[] oldPassword, char[] newPassword);
+
+       public void unlock(char[] password);
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/security/Keyring.java b/org.argeo.cms/src/org/argeo/cms/security/Keyring.java
new file mode 100644 (file)
index 0000000..53740c6
--- /dev/null
@@ -0,0 +1,26 @@
+package org.argeo.cms.security;
+
+import java.io.InputStream;
+
+/**
+ * Access to private (typically encrypted) data. The keyring is responsible for
+ * retrieving the necessary credentials. <b>Experimental. This API may
+ * change.</b>
+ */
+public interface Keyring {
+       /**
+        * Returns the confidential information as chars. Must ask for it if it is
+        * not stored.
+        */
+       public char[] getAsChars(String path);
+
+       /**
+        * Returns the confidential information as a stream. Must ask for it if it
+        * is not stored.
+        */
+       public InputStream getAsStream(String path);
+
+       public void set(String path, char[] arr);
+
+       public void set(String path, InputStream in);
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/security/NodeSecurityUtils.java b/org.argeo.cms/src/org/argeo/cms/security/NodeSecurityUtils.java
new file mode 100644 (file)
index 0000000..fb53940
--- /dev/null
@@ -0,0 +1,40 @@
+package org.argeo.cms.security;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+
+import org.argeo.api.cms.CmsConstants;
+
+public class NodeSecurityUtils {
+       public final static LdapName ROLE_ADMIN_NAME, ROLE_DATA_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME,
+                       ROLE_USER_ADMIN_NAME;
+       public final static List<LdapName> RESERVED_ROLES;
+       static {
+               try {
+                       ROLE_ADMIN_NAME = new LdapName(CmsConstants.ROLE_ADMIN);
+                       ROLE_DATA_ADMIN_NAME = new LdapName(CmsConstants.ROLE_DATA_ADMIN);
+                       ROLE_USER_NAME = new LdapName(CmsConstants.ROLE_USER);
+                       ROLE_USER_ADMIN_NAME = new LdapName(CmsConstants.ROLE_USER_ADMIN);
+                       ROLE_ANONYMOUS_NAME = new LdapName(CmsConstants.ROLE_ANONYMOUS);
+                       RESERVED_ROLES = Collections.unmodifiableList(Arrays.asList(
+                                       new LdapName[] { ROLE_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, ROLE_USER_ADMIN_NAME }));
+               } catch (InvalidNameException e) {
+                       throw new Error("Cannot initialize login module class", e);
+               }
+       }
+
+       public static void checkUserName(LdapName name) throws IllegalArgumentException {
+               if (RESERVED_ROLES.contains(name))
+                       throw new IllegalArgumentException(name + " is a reserved name");
+       }
+
+       public static void checkImpliedPrincipalName(LdapName roleName) throws IllegalArgumentException {
+//             if (ROLE_USER_NAME.equals(roleName) || ROLE_ANONYMOUS_NAME.equals(roleName))
+//                     throw new IllegalArgumentException(roleName + " cannot be listed as role");
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/security/PBEKeySpecCallback.java b/org.argeo.cms/src/org/argeo/cms/security/PBEKeySpecCallback.java
new file mode 100644 (file)
index 0000000..13e8d75
--- /dev/null
@@ -0,0 +1,63 @@
+package org.argeo.cms.security;
+
+import javax.crypto.spec.PBEKeySpec;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.PasswordCallback;
+
+/**
+ * All information required to set up a {@link PBEKeySpec} bar the password
+ * itself (use a {@link PasswordCallback})
+ */
+public class PBEKeySpecCallback implements Callback {
+       private String secretKeyFactory;
+       private byte[] salt;
+       private Integer iterationCount;
+       /** Can be null for some algorithms */
+       private Integer keyLength;
+       /** Can be null, will trigger secret key encryption if not */
+       private String secretKeyEncryption;
+
+       private String encryptedPasswordHashCipher;
+       private byte[] encryptedPasswordHash;
+
+       public void set(String secretKeyFactory, byte[] salt,
+                       Integer iterationCount, Integer keyLength,
+                       String secretKeyEncryption) {
+               this.secretKeyFactory = secretKeyFactory;
+               this.salt = salt;
+               this.iterationCount = iterationCount;
+               this.keyLength = keyLength;
+               this.secretKeyEncryption = secretKeyEncryption;
+//             this.encryptedPasswordHashCipher = encryptedPasswordHashCipher;
+//             this.encryptedPasswordHash = encryptedPasswordHash;
+       }
+
+       public String getSecretKeyFactory() {
+               return secretKeyFactory;
+       }
+
+       public byte[] getSalt() {
+               return salt;
+       }
+
+       public Integer getIterationCount() {
+               return iterationCount;
+       }
+
+       public Integer getKeyLength() {
+               return keyLength;
+       }
+
+       public String getSecretKeyEncryption() {
+               return secretKeyEncryption;
+       }
+
+       public String getEncryptedPasswordHashCipher() {
+               return encryptedPasswordHashCipher;
+       }
+
+       public byte[] getEncryptedPasswordHash() {
+               return encryptedPasswordHash;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/ArrayTabularRow.java b/org.argeo.cms/src/org/argeo/cms/tabular/ArrayTabularRow.java
new file mode 100644 (file)
index 0000000..cfd4827
--- /dev/null
@@ -0,0 +1,25 @@
+package org.argeo.cms.tabular;
+
+import java.util.List;
+
+/** Minimal tabular row wrapping an {@link Object} array */
+public class ArrayTabularRow implements TabularRow {
+       private final Object[] arr;
+
+       public ArrayTabularRow(List<?> objs) {
+               this.arr = objs.toArray();
+       }
+
+       public Object get(Integer col) {
+               return arr[col];
+       }
+
+       public int size() {
+               return arr.length;
+       }
+
+       public Object[] toArray() {
+               return arr;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularColumn.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularColumn.java
new file mode 100644 (file)
index 0000000..7f7ac1e
--- /dev/null
@@ -0,0 +1,41 @@
+package org.argeo.cms.tabular;
+
+/** The column in a tabular content */
+public class TabularColumn {
+       private String name;
+       /**
+        * JCR types, see
+        * http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/index.html
+        * ?javax/jcr/PropertyType.html
+        */
+       private Integer type;
+
+       /** column with default type */
+       public TabularColumn(String name) {
+               super();
+               this.name = name;
+       }
+
+       public TabularColumn(String name, Integer type) {
+               super();
+               this.name = name;
+               this.type = type;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public Integer getType() {
+               return type;
+       }
+
+       public void setType(Integer type) {
+               this.type = type;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularContent.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularContent.java
new file mode 100644 (file)
index 0000000..c6d2ab8
--- /dev/null
@@ -0,0 +1,14 @@
+package org.argeo.cms.tabular;
+
+import java.util.List;
+
+/**
+ * Content organized as a table, possibly with headers. Only JCR types are
+ * supported even though there is not direct dependency on JCR.
+ */
+public interface TabularContent {
+       /** The headers of this table or <code>null</code> is none available. */
+       public List<TabularColumn> getColumns();
+
+       public TabularRowIterator read();
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularRow.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularRow.java
new file mode 100644 (file)
index 0000000..69b9732
--- /dev/null
@@ -0,0 +1,13 @@
+package org.argeo.cms.tabular;
+
+/** A row of tabular data */
+public interface TabularRow {
+       /** The value at this column index */
+       public Object get(Integer col);
+
+       /** The raw objects (direct references) */
+       public Object[] toArray();
+
+       /** Number of columns */
+       public int size();
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularRowIterator.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularRowIterator.java
new file mode 100644 (file)
index 0000000..7ad8719
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.cms.tabular;
+
+import java.util.Iterator;
+
+/** Navigation of rows */
+public interface TabularRowIterator extends Iterator<TabularRow> {
+       /**
+        * Current row number, has to be incremented by each call to next() ; starts at 0, will
+        * therefore be 1 for the first row returned.
+        */
+       public Long getCurrentRowNumber();
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularWriter.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularWriter.java
new file mode 100644 (file)
index 0000000..34fc85b
--- /dev/null
@@ -0,0 +1,11 @@
+package org.argeo.cms.tabular;
+
+
+/** Write to a tabular content */
+public interface TabularWriter {
+       /** Append a new row of data */
+       public void appendRow(Object[] row);
+
+       /** Finish persisting data and release resources */
+       public void close();
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/package-info.java b/org.argeo.cms/src/org/argeo/cms/tabular/package-info.java
new file mode 100644 (file)
index 0000000..6cb48d0
--- /dev/null
@@ -0,0 +1,2 @@
+/** Tabular format API. */
+package org.argeo.cms.tabular;
\ No newline at end of file
index 122d7f586ee40edd3a66294049bb14e9a0e44adf..5074d5d1b1225018ba1e02c9d1de7dda6fa81792 100644 (file)
@@ -6,6 +6,3 @@ Bundle-Activator: org.argeo.init.osgi.Activator
 Import-Package: \
 org.osgi.*;version=0.0.0,\
 java.util.logging.*;resolution:=optional
-
-Private-Package: *
-Export-Package: !*
diff --git a/org.argeo.util/src/org/argeo/ident/IdentClient.java b/org.argeo.util/src/org/argeo/ident/IdentClient.java
deleted file mode 100644 (file)
index c42da97..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.argeo.ident;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.ConnectException;
-import java.net.Socket;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * A simple ident client, supporting authd OpenSSL encrypted username.
- * 
- * @see RFC 1413 https://tools.ietf.org/html/rfc1413
- */
-public class IdentClient {
-       public final static int DEFAULT_IDENT_PORT = 113;
-       public final static String AUTHD_PASSPHRASE_PATH = "/etc/ident.key";
-       final static String NO_USER = "NO-USER";
-
-       private final String host;
-       private final int port;
-
-       private OpenSslDecryptor openSslDecryptor = new OpenSslDecryptor();
-       private String identPassphrase = null;
-
-       public IdentClient(String host) {
-               this(host, readPassphrase(AUTHD_PASSPHRASE_PATH), DEFAULT_IDENT_PORT);
-       }
-
-       public IdentClient(String host, Path passPhrasePath) {
-               this(host, readPassphrase(passPhrasePath), DEFAULT_IDENT_PORT);
-       }
-
-       public IdentClient(String host, String identPassphrase) {
-               this(host, identPassphrase, DEFAULT_IDENT_PORT);
-       }
-
-       public IdentClient(String host, String identPassphrase, int port) {
-               this.host = host;
-               this.identPassphrase = identPassphrase;
-               this.port = port;
-       }
-
-       /** @return the username or null if none */
-       public String getUsername(int serverPort, int clientPort) {
-               String answer;
-               try (Socket socket = new Socket(host, port)) {
-                       String msg = clientPort + "," + serverPort + "\n";
-                       OutputStream out = socket.getOutputStream();
-                       out.write(msg.getBytes(StandardCharsets.US_ASCII));
-                       out.flush();
-                       BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-                       answer = reader.readLine();
-               } catch (ConnectException e) {
-                       System.err.println(
-                                       "Ident client is configured but no ident server available on " + host + " (port " + port + ")");
-                       return null;
-               } catch (Exception e) {
-                       throw new RuntimeException("Cannot read from ident server on " + host + " (port " + port + ")", e);
-               }
-               StringTokenizer st = new StringTokenizer(answer, " :\n");
-               String username = null;
-               while (st.hasMoreTokens())
-                       username = st.nextToken();
-
-               if (username.equals(NO_USER))
-                       return null;
-
-               if (identPassphrase != null && username.startsWith("[")) {
-                       String encrypted = username.substring(1, username.length() - 1);
-                       username = openSslDecryptor.decryptAuthd(encrypted, identPassphrase).trim();
-               }
-//             System.out.println(username);
-               return username;
-       }
-
-       public void setOpenSslDecryptor(OpenSslDecryptor openSslDecryptor) {
-               this.openSslDecryptor = openSslDecryptor;
-       }
-
-       public static String readPassphrase(String filePath) {
-               return readPassphrase(Paths.get(filePath));
-       }
-
-       /** @return the first line of the file. */
-       public static String readPassphrase(Path path) {
-               if (!isPathAvailable(path))
-                       return null;
-               List<String> lines;
-               try {
-                       lines = Files.readAllLines(path);
-               } catch (IOException e) {
-                       throw new IllegalStateException("Cannot read " + path, e);
-               }
-               if (lines.size() == 0)
-                       return null;
-               String passphrase = lines.get(0);
-               return passphrase;
-       }
-
-       public static boolean isDefaultAuthdPassphraseFileAvailable() {
-               return isPathAvailable(Paths.get(AUTHD_PASSPHRASE_PATH));
-       }
-
-       public static boolean isPathAvailable(Path path) {
-               if (!Files.exists(path))
-                       return false;
-               if (!Files.isReadable(path))
-                       return false;
-               return true;
-       }
-
-       public static void main(String[] args) {
-               IdentClient identClient = new IdentClient("127.0.0.1", "changeit");
-               String username = identClient.getUsername(7070, 55958);
-               System.out.println(username);
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/ident/OpenSslDecryptor.java b/org.argeo.util/src/org/argeo/ident/OpenSslDecryptor.java
deleted file mode 100644 (file)
index 702b09b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.argeo.ident;
-
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.util.Arrays;
-import java.util.Base64;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Decrypts OpenSSL encrypted data.
- * 
- * From
- * https://stackoverflow.com/questions/11783062/how-to-decrypt-file-in-java-encrypted-with-openssl-command-using-aes
- * 
- * See also
- * https://stackoverflow.com/questions/54171959/badpadding-exception-when-trying-to-decrypt-aes-based-encrypted-text/54173509#54173509
- * for new default message digest (not yet in CentOS 7 as of July 2019)
- */
-public class OpenSslDecryptor {
-       private static final int INDEX_KEY = 0;
-       private static final int INDEX_IV = 1;
-       private static final int ITERATIONS = 1;
-
-       private static final int SALT_OFFSET = 8;
-       private static final int SALT_SIZE = 8;
-       private static final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE;
-
-       /** In bits. */
-       private final int keySize;
-
-       private Cipher cipher;
-       private MessageDigest messageDigest;
-
-       public OpenSslDecryptor() {
-               /*
-                * Changed to SHA-256 from OpenSSL v1.1.0 (see
-                * https://stackoverflow.com/questions/39637388/encryption-decryption-doesnt-
-                * work-well-between-two-different-openssl-versions)
-                */
-               this(128, "MD5");
-       }
-
-       public OpenSslDecryptor(int keySize, String messageDigest) {
-               this.keySize = keySize;
-               try {
-                       this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
-                       this.messageDigest = MessageDigest.getInstance(messageDigest);
-               } catch (GeneralSecurityException e) {
-                       throw new IllegalArgumentException("Cannot initialise decryptor", e);
-               }
-       }
-
-       public String decryptAuthd(String dataBase64, String passphrase) {
-               try {
-                       byte[] headerSaltAndCipherText = Base64.getDecoder().decode(dataBase64);
-
-                       boolean withSalt = true;
-                       byte[] salt = withSalt ? Arrays.copyOfRange(headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE)
-                                       : null;
-                       byte[] encrypted = withSalt
-                                       ? Arrays.copyOfRange(headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length)
-                                       : headerSaltAndCipherText;
-
-                       final byte[][] keyAndIV = EVP_BytesToKey(keySize / Byte.SIZE, cipher.getBlockSize(), messageDigest, salt,
-                                       passphrase.getBytes(StandardCharsets.US_ASCII), ITERATIONS);
-                       SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES");
-                       IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]);
-
-                       cipher.init(Cipher.DECRYPT_MODE, key, iv);
-                       byte[] decrypted = cipher.doFinal(encrypted);
-
-                       String answer = new String(decrypted, StandardCharsets.US_ASCII);
-                       return answer;
-               } catch (BadPaddingException e) {
-                       throw new IllegalStateException("Bad password, algorithm, mode or padding;"
-                                       + " no salt, wrong number of iterations or corrupted ciphertext.", e);
-               } catch (IllegalBlockSizeException e) {
-                       throw new IllegalStateException("Bad algorithm, mode or corrupted (resized) ciphertext.", e);
-               } catch (GeneralSecurityException e) {
-                       throw new IllegalStateException(e);
-               }
-       }
-
-       private static byte[][] EVP_BytesToKey(int key_len, int iv_len, MessageDigest md, byte[] salt, byte[] data,
-                       int count) {
-               byte[][] both = new byte[2][];
-               byte[] key = new byte[key_len];
-               int key_ix = 0;
-               byte[] iv = new byte[iv_len];
-               int iv_ix = 0;
-               both[0] = key;
-               both[1] = iv;
-               byte[] md_buf = null;
-               int nkey = key_len;
-               int niv = iv_len;
-               int i = 0;
-               if (data == null) {
-                       return both;
-               }
-               int addmd = 0;
-               for (;;) {
-                       md.reset();
-                       if (addmd++ > 0) {
-                               md.update(md_buf);
-                       }
-                       md.update(data);
-                       if (null != salt) {
-                               md.update(salt, 0, 8);
-                       }
-                       md_buf = md.digest();
-                       for (i = 1; i < count; i++) {
-                               md.reset();
-                               md.update(md_buf);
-                               md_buf = md.digest();
-                       }
-                       i = 0;
-                       if (nkey > 0) {
-                               for (;;) {
-                                       if (nkey == 0)
-                                               break;
-                                       if (i == md_buf.length)
-                                               break;
-                                       key[key_ix++] = md_buf[i];
-                                       nkey--;
-                                       i++;
-                               }
-                       }
-                       if (niv > 0 && i != md_buf.length) {
-                               for (;;) {
-                                       if (niv == 0)
-                                               break;
-                                       if (i == md_buf.length)
-                                               break;
-                                       iv[iv_ix++] = md_buf[i];
-                                       niv--;
-                                       i++;
-                               }
-                       }
-                       if (nkey == 0 && niv == 0) {
-                               break;
-                       }
-               }
-               for (i = 0; i < md_buf.length; i++) {
-                       md_buf[i] = 0;
-               }
-               return both;
-       }
-
-       public static void main(String[] args) {
-               String dataBase64 = args[0];
-               String passphrase = args[1];
-               OpenSslDecryptor decryptor = new OpenSslDecryptor();
-               System.out.println(decryptor.decryptAuthd(dataBase64, passphrase));
-       }
-
-}
\ No newline at end of file
diff --git a/org.argeo.util/src/org/argeo/ident/package-info.java b/org.argeo.util/src/org/argeo/ident/package-info.java
deleted file mode 100644 (file)
index 35dd1a2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Ident authentication protocol support. */
-package org.argeo.ident;
\ No newline at end of file
diff --git a/org.argeo.util/src/org/argeo/naming/AttributesDictionary.java b/org.argeo.util/src/org/argeo/naming/AttributesDictionary.java
deleted file mode 100644 (file)
index e047216..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-package org.argeo.naming;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttribute;
-
-public class AttributesDictionary extends Dictionary<String, Object> {
-       private final Attributes attributes;
-
-       /** The provided attributes is wrapped, not copied. */
-       public AttributesDictionary(Attributes attributes) {
-               if (attributes == null)
-                       throw new IllegalArgumentException("Attributes cannot be null");
-               this.attributes = attributes;
-       }
-
-       @Override
-       public int size() {
-               return attributes.size();
-       }
-
-       @Override
-       public boolean isEmpty() {
-               return attributes.size() == 0;
-       }
-
-       @Override
-       public Enumeration<String> keys() {
-               NamingEnumeration<String> namingEnumeration = attributes.getIDs();
-               return new Enumeration<String>() {
-
-                       @Override
-                       public boolean hasMoreElements() {
-                               return namingEnumeration.hasMoreElements();
-                       }
-
-                       @Override
-                       public String nextElement() {
-                               return namingEnumeration.nextElement();
-                       }
-
-               };
-       }
-
-       @Override
-       public Enumeration<Object> elements() {
-               NamingEnumeration<String> namingEnumeration = attributes.getIDs();
-               return new Enumeration<Object>() {
-
-                       @Override
-                       public boolean hasMoreElements() {
-                               return namingEnumeration.hasMoreElements();
-                       }
-
-                       @Override
-                       public Object nextElement() {
-                               String key = namingEnumeration.nextElement();
-                               return get(key);
-                       }
-
-               };
-       }
-
-       @Override
-       /** @returns a <code>String</code> or <code>String[]</code> */
-       public Object get(Object key) {
-               try {
-                       if (key == null)
-                               throw new IllegalArgumentException("Key cannot be null");
-                       Attribute attr = attributes.get(key.toString());
-                       if (attr == null)
-                               return null;
-                       if (attr.size() == 0)
-                               throw new IllegalStateException("There must be at least one value");
-                       else if (attr.size() == 1) {
-                               return attr.get().toString();
-                       } else {// multiple
-                               String[] res = new String[attr.size()];
-                               for (int i = 0; i < attr.size(); i++) {
-                                       Object value = attr.get();
-                                       if (value == null)
-                                               throw new RuntimeException("Values cannot be null");
-                                       res[i] = attr.get(i).toString();
-                               }
-                               return res;
-                       }
-               } catch (NamingException e) {
-                       throw new RuntimeException("Cannot get value for " + key, e);
-               }
-       }
-
-       @Override
-       public Object put(String key, Object value) {
-               if (key == null)
-                       throw new IllegalArgumentException("Key cannot be null");
-               if (value == null)
-                       throw new IllegalArgumentException("Value cannot be null");
-
-               Object oldValue = get(key);
-               Attribute attr = attributes.get(key);
-               if (attr == null) {
-                       attr = new BasicAttribute(key);
-                       attributes.put(attr);
-               }
-
-               if (value instanceof String[]) {
-                       String[] values = (String[]) value;
-                       // clean additional values
-                       for (int i = values.length; i < attr.size(); i++)
-                               attr.remove(i);
-                       // set values
-                       for (int i = 0; i < values.length; i++) {
-                               attr.set(i, values[i]);
-                       }
-               } else {
-                       if (attr.size() > 1)
-                               throw new IllegalArgumentException("Attribute " + key + " is multi-valued");
-                       if (attr.size() == 1) {
-                               try {
-                                       if (!attr.get(0).equals(value))
-                                               attr.set(0, value.toString());
-                               } catch (NamingException e) {
-                                       throw new RuntimeException("Cannot check existing value", e);
-                               }
-                       } else {
-                               attr.add(value.toString());
-                       }
-               }
-               return oldValue;
-       }
-
-       @Override
-       public Object remove(Object key) {
-               if (key == null)
-                       throw new IllegalArgumentException("Key cannot be null");
-               Object oldValue = get(key);
-               if (oldValue == null)
-                       return null;
-               return attributes.remove(key.toString());
-       }
-
-       /**
-        * Copy the <b>content</b> of an {@link Attributes} to the provided
-        * {@link Dictionary}.
-        */
-       public static void copy(Attributes attributes, Dictionary<String, Object> dictionary) {
-               AttributesDictionary ad = new AttributesDictionary(attributes);
-               Enumeration<String> keys = ad.keys();
-               while (keys.hasMoreElements()) {
-                       String key = keys.nextElement();
-                       dictionary.put(key, ad.get(key));
-               }
-       }
-
-       /**
-        * Copy a {@link Dictionary} into an {@link Attributes}.
-        */
-       public static void copy(Dictionary<String, Object> dictionary, Attributes attributes) {
-               AttributesDictionary ad = new AttributesDictionary(attributes);
-               Enumeration<String> keys = dictionary.keys();
-               while (keys.hasMoreElements()) {
-                       String key = keys.nextElement();
-                       ad.put(key, dictionary.get(key));
-               }
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/naming/AuthPassword.java b/org.argeo.util/src/org/argeo/naming/AuthPassword.java
deleted file mode 100644 (file)
index 6d4c62b..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-package org.argeo.naming;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.StringTokenizer;
-
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.argeo.osgi.useradmin.UserDirectoryException;
-
-/** LDAP authPassword field according to RFC 3112 */
-public class AuthPassword implements CallbackHandler {
-       private final String authScheme;
-       private final String authInfo;
-       private final String authValue;
-
-       public AuthPassword(String value) {
-               StringTokenizer st = new StringTokenizer(value, "$");
-               // TODO make it more robust, deal with bad formatting
-               this.authScheme = st.nextToken().trim();
-               this.authInfo = st.nextToken().trim();
-               this.authValue = st.nextToken().trim();
-
-               String expectedAuthScheme = getExpectedAuthScheme();
-               if (expectedAuthScheme != null && !authScheme.equals(expectedAuthScheme))
-                       throw new IllegalArgumentException(
-                                       "Auth scheme " + authScheme + " is not compatible with " + expectedAuthScheme);
-       }
-
-       protected AuthPassword(String authInfo, String authValue) {
-               this.authScheme = getExpectedAuthScheme();
-               if (authScheme == null)
-                       throw new IllegalArgumentException("Expected auth scheme cannot be null");
-               this.authInfo = authInfo;
-               this.authValue = authValue;
-       }
-
-       protected AuthPassword(AuthPassword authPassword) {
-               this.authScheme = authPassword.getAuthScheme();
-               this.authInfo = authPassword.getAuthInfo();
-               this.authValue = authPassword.getAuthValue();
-       }
-
-       protected String getExpectedAuthScheme() {
-               return null;
-       }
-
-       protected boolean matchAuthValue(Object object) {
-               return authValue.equals(object.toString());
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (!(obj instanceof AuthPassword))
-                       return false;
-               AuthPassword authPassword = (AuthPassword) obj;
-               return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo)
-                               && authValue.equals(authValue);
-       }
-
-       public boolean keyEquals(AuthPassword authPassword) {
-               return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo);
-       }
-
-       @Override
-       public int hashCode() {
-               return authValue.hashCode();
-       }
-
-       @Override
-       public String toString() {
-               return toAuthPassword();
-       }
-
-       public final String toAuthPassword() {
-               return getAuthScheme() + '$' + authInfo + '$' + authValue;
-       }
-
-       public String getAuthScheme() {
-               return authScheme;
-       }
-
-       public String getAuthInfo() {
-               return authInfo;
-       }
-
-       public String getAuthValue() {
-               return authValue;
-       }
-
-       public static AuthPassword matchAuthValue(Attributes attributes, char[] value) {
-               try {
-                       Attribute authPassword = attributes.get(LdapAttrs.authPassword.name());
-                       if (authPassword != null) {
-                               NamingEnumeration<?> values = authPassword.getAll();
-                               while (values.hasMore()) {
-                                       Object val = values.next();
-                                       AuthPassword token = new AuthPassword(val.toString());
-                                       String auth;
-                                       if (Arrays.binarySearch(value, '$') >= 0) {
-                                               auth = token.authInfo + '$' + token.authValue;
-                                       } else {
-                                               auth = token.authValue;
-                                       }
-                                       if (Arrays.equals(auth.toCharArray(), value))
-                                               return token;
-                                       // if (token.matchAuthValue(value))
-                                       // return token;
-                               }
-                       }
-                       return null;
-               } catch (NamingException e) {
-                       throw new UserDirectoryException("Cannot check attribute", e);
-               }
-       }
-
-       public static boolean remove(Attributes attributes, AuthPassword value) {
-               Attribute authPassword = attributes.get(LdapAttrs.authPassword.name());
-               return authPassword.remove(value.toAuthPassword());
-       }
-
-       @Override
-       public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
-               for (Callback callback : callbacks) {
-                       if (callback instanceof NameCallback)
-                               ((NameCallback) callback).setName(toAuthPassword());
-                       else if (callback instanceof PasswordCallback)
-                               ((PasswordCallback) callback).setPassword(getAuthValue().toCharArray());
-               }
-       }
-
-}
diff --git a/org.argeo.util/src/org/argeo/naming/Distinguished.java b/org.argeo.util/src/org/argeo/naming/Distinguished.java
deleted file mode 100644 (file)
index 8b9c4b9..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.argeo.naming;
-
-import java.util.EnumSet;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-
-/**
- * An object that can be identified with an X.500 distinguished name.
- * 
- * @see https://tools.ietf.org/html/rfc1779
- */
-public interface Distinguished {
-       /** The related distinguished name. */
-       String dn();
-
-       /** The related distinguished name as an {@link LdapName}. */
-       default LdapName distinguishedName() {
-               try {
-                       return new LdapName(dn());
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Distinguished name " + dn() + " is not properly formatted.", e);
-               }
-       }
-
-       /** List all DNs of an enumeration as strings. */
-       static Set<String> enumToDns(EnumSet<? extends Distinguished> enumSet) {
-               Set<String> res = new TreeSet<>();
-               for (Enum<? extends Distinguished> enm : enumSet) {
-                       res.add(((Distinguished) enm).dn());
-               }
-               return res;
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/naming/DnsBrowser.java b/org.argeo.util/src/org/argeo/naming/DnsBrowser.java
deleted file mode 100644 (file)
index d9358c0..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-package org.argeo.naming;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import javax.naming.Binding;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.InitialDirContext;
-
-public class DnsBrowser implements Closeable {
-       private final DirContext initialCtx;
-
-       public DnsBrowser() throws NamingException {
-               this(null);
-       }
-
-       public DnsBrowser(String dnsServerUrls) throws NamingException {
-               Hashtable<String, Object> env = new Hashtable<>();
-               env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
-               if (dnsServerUrls != null)
-                       env.put("java.naming.provider.url", dnsServerUrls);
-               initialCtx = new InitialDirContext(env);
-       }
-
-       public Map<String, List<String>> getAllRecords(String name) throws NamingException {
-               Map<String, List<String>> res = new TreeMap<>();
-               Attributes attrs = initialCtx.getAttributes(name);
-               NamingEnumeration<String> ids = attrs.getIDs();
-               while (ids.hasMore()) {
-                       String recordType = ids.next();
-                       List<String> lst = new ArrayList<String>();
-                       res.put(recordType, lst);
-                       Attribute attr = attrs.get(recordType);
-                       addValues(attr, lst);
-               }
-               return Collections.unmodifiableMap(res);
-       }
-
-       /**
-        * Return a single record (typically A, AAAA, etc. or null if not available.
-        * Will fail if multiple records.
-        */
-       public String getRecord(String name, String recordType) throws NamingException {
-               Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType });
-               if (attrs.size() == 0)
-                       return null;
-               Attribute attr = attrs.get(recordType);
-               if (attr.size() > 1)
-                       throw new IllegalArgumentException("Multiple record type " + recordType);
-               assert attr.size() != 0;
-               Object value = attr.get();
-               assert value != null;
-               return value.toString();
-       }
-
-       /**
-        * Return records of a given type.
-        */
-       public List<String> getRecords(String name, String recordType) throws NamingException {
-               List<String> res = new ArrayList<String>();
-               Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType });
-               Attribute attr = attrs.get(recordType);
-               addValues(attr, res);
-               return res;
-       }
-
-       /** Ordered, with preferred first. */
-       public List<String> getSrvRecordsAsHosts(String name, boolean withPort) throws NamingException {
-               List<String> raw = getRecords(name, "SRV");
-               if (raw.size() == 0)
-                       return null;
-               SortedSet<SrvRecord> res = new TreeSet<>();
-               for (int i = 0; i < raw.size(); i++) {
-                       String record = raw.get(i);
-                       String[] arr = record.split(" ");
-                       Integer priority = Integer.parseInt(arr[0]);
-                       Integer weight = Integer.parseInt(arr[1]);
-                       Integer port = Integer.parseInt(arr[2]);
-                       String hostname = arr[3];
-                       SrvRecord order = new SrvRecord(priority, weight, port, hostname);
-                       res.add(order);
-               }
-               List<String> lst = new ArrayList<>();
-               for (SrvRecord order : res) {
-                       lst.add(order.toHost(withPort));
-               }
-               return Collections.unmodifiableList(lst);
-       }
-
-       private void addValues(Attribute attr, List<String> lst) throws NamingException {
-               NamingEnumeration<?> values = attr.getAll();
-               while (values.hasMore()) {
-                       Object value = values.next();
-                       if (value != null) {
-                               if (value instanceof byte[]) {
-                                       String str = Base64.getEncoder().encodeToString((byte[]) value);
-                                       lst.add(str);
-                               } else
-                                       lst.add(value.toString());
-                       }
-               }
-
-       }
-
-       public List<String> listEntries(String name) throws NamingException {
-               List<String> res = new ArrayList<String>();
-               NamingEnumeration<Binding> ne = initialCtx.listBindings(name);
-               while (ne.hasMore()) {
-                       Binding b = ne.next();
-                       res.add(b.getName());
-               }
-               return Collections.unmodifiableList(res);
-       }
-
-       @Override
-       public void close() throws IOException {
-               destroy();
-       }
-
-       public void destroy() {
-               try {
-                       initialCtx.close();
-               } catch (NamingException e) {
-                       // silent
-               }
-       }
-
-       public static void main(String[] args) {
-               if (args.length == 0) {
-                       printUsage(System.err);
-                       System.exit(1);
-               }
-               try (DnsBrowser dnsBrowser = new DnsBrowser()) {
-                       String hostname = args[0];
-                       String recordType = args.length > 1 ? args[1] : "A";
-                       if (recordType.equals("*")) {
-                               Map<String, List<String>> records = dnsBrowser.getAllRecords(hostname);
-                               for (String type : records.keySet()) {
-                                       for (String record : records.get(type)) {
-                                               String typeLabel;
-                                               if ("44".equals(type))
-                                                       typeLabel = "SSHFP";
-                                               else if ("46".equals(type))
-                                                       typeLabel = "RRSIG";
-                                               else if ("48".equals(type))
-                                                       typeLabel = "DNSKEY";
-                                               else
-                                                       typeLabel = type;
-                                               System.out.println(typeLabel + "\t" + record);
-                                       }
-                               }
-                       } else {
-                               System.out.println(dnsBrowser.getRecord(hostname, recordType));
-                       }
-
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-       }
-
-       public static void printUsage(PrintStream out) {
-               out.println("java org.argeo.naming.DnsBrowser <hostname> [<record type> | *]");
-       }
-
-}
\ No newline at end of file
diff --git a/org.argeo.util/src/org/argeo/naming/LdapAttrs.csv b/org.argeo.util/src/org/argeo/naming/LdapAttrs.csv
deleted file mode 100644 (file)
index 676d727..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-uid,,,0.9.2342.19200300.100.1.1,,RFC 4519
-mail,,,0.9.2342.19200300.100.1.3,,RFC 4524
-info,,,0.9.2342.19200300.100.1.4,,RFC 4524
-drink,,,0.9.2342.19200300.100.1.5,,RFC 4524
-roomNumber,,,0.9.2342.19200300.100.1.6,,RFC 4524
-photo,,,0.9.2342.19200300.100.1.7,,RFC 2798
-userClass,,,0.9.2342.19200300.100.1.8,,RFC 4524
-host,,,0.9.2342.19200300.100.1.9,,RFC 4524
-manager,,,0.9.2342.19200300.100.1.10,,RFC 4524
-documentIdentifier,,,0.9.2342.19200300.100.1.11,,RFC 4524
-documentTitle,,,0.9.2342.19200300.100.1.12,,RFC 4524
-documentVersion,,,0.9.2342.19200300.100.1.13,,RFC 4524
-documentAuthor,,,0.9.2342.19200300.100.1.14,,RFC 4524
-documentLocation,,,0.9.2342.19200300.100.1.15,,RFC 4524
-homePhone,,,0.9.2342.19200300.100.1.20,,RFC 4524
-secretary,,,0.9.2342.19200300.100.1.21,,RFC 4524
-dc,,,0.9.2342.19200300.100.1.25,,RFC 4519
-associatedDomain,,,0.9.2342.19200300.100.1.37,,RFC 4524
-associatedName,,,0.9.2342.19200300.100.1.38,,RFC 4524
-homePostalAddress,,,0.9.2342.19200300.100.1.39,,RFC 4524
-personalTitle,,,0.9.2342.19200300.100.1.40,,RFC 4524
-mobile,,,0.9.2342.19200300.100.1.41,,RFC 4524
-pager,,,0.9.2342.19200300.100.1.42,,RFC 4524
-co,,,0.9.2342.19200300.100.1.43,,RFC 4524
-uniqueIdentifier,,,0.9.2342.19200300.100.1.44,,RFC 4524
-organizationalStatus,,,0.9.2342.19200300.100.1.45,,RFC 4524
-buildingName,,,0.9.2342.19200300.100.1.48,,RFC 4524
-audio,,,0.9.2342.19200300.100.1.55,,RFC 2798
-documentPublisher,,,0.9.2342.19200300.100.1.56,,RFC 4524
-jpegPhoto,,,0.9.2342.19200300.100.1.60,,RFC 2798
-vendorName,,,1.3.6.1.1.4,,RFC 3045
-vendorVersion,,,1.3.6.1.1.5,,RFC 3045
-entryUUID,,,1.3.6.1.1.16.4,,RFC 4530
-entryDN,,,1.3.6.1.1.20,,RFC 5020
-labeledURI,,,1.3.6.1.4.1.250.1.57,,RFC 2798
-numSubordinates,,,1.3.6.1.4.1.453.16.2.103,,draft-ietf-boreham-numsubordinates
-namingContexts,,,1.3.6.1.4.1.1466.101.120.5,,RFC 4512
-altServer,,,1.3.6.1.4.1.1466.101.120.6,,RFC 4512
-supportedExtension,,,1.3.6.1.4.1.1466.101.120.7,,RFC 4512
-supportedControl,,,1.3.6.1.4.1.1466.101.120.13,,RFC 4512
-supportedSASLMechanisms,,,1.3.6.1.4.1.1466.101.120.14,,RFC 4512
-supportedLDAPVersion,,,1.3.6.1.4.1.1466.101.120.15,,RFC 4512
-ldapSyntaxes,,,1.3.6.1.4.1.1466.101.120.16,,RFC 4512
-supportedAuthPasswordSchemes,,,1.3.6.1.4.1.4203.1.3.3,,RFC 3112
-authPassword,,,1.3.6.1.4.1.4203.1.3.4,,RFC 3112
-supportedFeatures,,,1.3.6.1.4.1.4203.1.3.5,,RFC 4512
-inheritable,,,1.3.6.1.4.1.7628.5.4.1,,draft-ietf-ldup-subentry
-blockInheritance,,,1.3.6.1.4.1.7628.5.4.2,,draft-ietf-ldup-subentry
-objectClass,,,2.5.4.0,,RFC 4512
-aliasedObjectName,,,2.5.4.1,,RFC 4512
-cn,,,2.5.4.3,,RFC 4519
-sn,,,2.5.4.4,,RFC 4519
-serialNumber,,,2.5.4.5,,RFC 4519
-c,,,2.5.4.6,,RFC 4519
-l,,,2.5.4.7,,RFC 4519
-st,,,2.5.4.8,,RFC 4519
-street,,,2.5.4.9,,RFC 4519
-o,,,2.5.4.10,,RFC 4519
-ou,,,2.5.4.11,,RFC 4519
-title,,,2.5.4.12,,RFC 4519
-description,,,2.5.4.13,,RFC 4519
-searchGuide,,,2.5.4.14,,RFC 4519
-businessCategory,,,2.5.4.15,,RFC 4519
-postalAddress,,,2.5.4.16,,RFC 4519
-postalCode,,,2.5.4.17,,RFC 4519
-postOfficeBox,,,2.5.4.18,,RFC 4519
-physicalDeliveryOfficeName,,,2.5.4.19,,RFC 4519
-telephoneNumber,,,2.5.4.20,,RFC 4519
-telexNumber,,,2.5.4.21,,RFC 4519
-teletexTerminalIdentifier,,,2.5.4.22,,RFC 4519
-facsimileTelephoneNumber,,,2.5.4.23,,RFC 4519
-x121Address,,,2.5.4.24,,RFC 4519
-internationalISDNNumber,,,2.5.4.25,,RFC 4519
-registeredAddress,,,2.5.4.26,,RFC 4519
-destinationIndicator,,,2.5.4.27,,RFC 4519
-preferredDeliveryMethod,,,2.5.4.28,,RFC 4519
-member,,,2.5.4.31,,RFC 4519
-owner,,,2.5.4.32,,RFC 4519
-roleOccupant,,,2.5.4.33,,RFC 4519
-seeAlso,,,2.5.4.34,,RFC 4519
-userPassword,,,2.5.4.35,,RFC 4519
-userCertificate,,,2.5.4.36,,RFC 4523
-cACertificate,,,2.5.4.37,,RFC 4523
-authorityRevocationList,,,2.5.4.38,,RFC 4523
-certificateRevocationList,,,2.5.4.39,,RFC 4523
-crossCertificatePair,,,2.5.4.40,,RFC 4523
-name,,,2.5.4.41,,RFC 4519
-givenName,,,2.5.4.42,,RFC 4519
-initials,,,2.5.4.43,,RFC 4519
-generationQualifier,,,2.5.4.44,,RFC 4519
-x500UniqueIdentifier,,,2.5.4.45,,RFC 4519
-dnQualifier,,,2.5.4.46,,RFC 4519
-enhancedSearchGuide,,,2.5.4.47,,RFC 4519
-distinguishedName,,,2.5.4.49,,RFC 4519
-uniqueMember,,,2.5.4.50,,RFC 4519
-houseIdentifier,,,2.5.4.51,,RFC 4519
-supportedAlgorithms,,,2.5.4.52,,RFC 4523
-deltaRevocationList,,,2.5.4.53,,RFC 4523
-createTimestamp,,,2.5.18.1,,RFC 4512
-modifyTimestamp,,,2.5.18.2,,RFC 4512
-creatorsName,,,2.5.18.3,,RFC 4512
-modifiersName,,,2.5.18.4,,RFC 4512
-subschemaSubentry,,,2.5.18.10,,RFC 4512
-dITStructureRules,,,2.5.21.1,,RFC 4512
-dITContentRules,,,2.5.21.2,,RFC 4512
-matchingRules,,,2.5.21.4,,RFC 4512
-attributeTypes,,,2.5.21.5,,RFC 4512
-objectClasses,,,2.5.21.6,,RFC 4512
-nameForms,,,2.5.21.7,,RFC 4512
-matchingRuleUse,,,2.5.21.8,,RFC 4512
-structuralObjectClass,,,2.5.21.9,,RFC 4512
-governingStructureRule,,,2.5.21.10,,RFC 4512
-carLicense,,,2.16.840.1.113730.3.1.1,,RFC 2798
-departmentNumber,,,2.16.840.1.113730.3.1.2,,RFC 2798
-employeeNumber,,,2.16.840.1.113730.3.1.3,,RFC 2798
-employeeType,,,2.16.840.1.113730.3.1.4,,RFC 2798
-changeNumber,,,2.16.840.1.113730.3.1.5,,draft-good-ldap-changelog
-targetDN,,,2.16.840.1.113730.3.1.6,,draft-good-ldap-changelog
-changeType,,,2.16.840.1.113730.3.1.7,,draft-good-ldap-changelog
-changes,,,2.16.840.1.113730.3.1.8,,draft-good-ldap-changelog
-newRDN,,,2.16.840.1.113730.3.1.9,,draft-good-ldap-changelog
-deleteOldRDN,,,2.16.840.1.113730.3.1.10,,draft-good-ldap-changelog
-newSuperior,,,2.16.840.1.113730.3.1.11,,draft-good-ldap-changelog
-ref,,,2.16.840.1.113730.3.1.34,,RFC 3296
-changelog,,,2.16.840.1.113730.3.1.35,,draft-good-ldap-changelog
-preferredLanguage,,,2.16.840.1.113730.3.1.39,,RFC 2798
-userSMIMECertificate,,,2.16.840.1.113730.3.1.40,,RFC 2798
-userPKCS12,,,2.16.840.1.113730.3.1.216,,RFC 2798
-displayName,,,2.16.840.1.113730.3.1.241,,RFC 2798
diff --git a/org.argeo.util/src/org/argeo/naming/LdapAttrs.java b/org.argeo.util/src/org/argeo/naming/LdapAttrs.java
deleted file mode 100644 (file)
index cfabeb7..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-package org.argeo.naming;
-
-/**
- * Standard LDAP attributes as per:<br>
- * - <a href= "https://www.ldap.com/ldap-oid-reference">Standard LDAP</a><br>
- * - <a href=
- * "https://github.com/krb5/krb5/blob/master/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema">Kerberos
- * LDAP (partial)</a>
- */
-public enum LdapAttrs implements SpecifiedName {
-       /** */
-       uid("0.9.2342.19200300.100.1.1", "RFC 4519"),
-       /** */
-       mail("0.9.2342.19200300.100.1.3", "RFC 4524"),
-       /** */
-       info("0.9.2342.19200300.100.1.4", "RFC 4524"),
-       /** */
-       drink("0.9.2342.19200300.100.1.5", "RFC 4524"),
-       /** */
-       roomNumber("0.9.2342.19200300.100.1.6", "RFC 4524"),
-       /** */
-       photo("0.9.2342.19200300.100.1.7", "RFC 2798"),
-       /** */
-       userClass("0.9.2342.19200300.100.1.8", "RFC 4524"),
-       /** */
-       host("0.9.2342.19200300.100.1.9", "RFC 4524"),
-       /** */
-       manager("0.9.2342.19200300.100.1.10", "RFC 4524"),
-       /** */
-       documentIdentifier("0.9.2342.19200300.100.1.11", "RFC 4524"),
-       /** */
-       documentTitle("0.9.2342.19200300.100.1.12", "RFC 4524"),
-       /** */
-       documentVersion("0.9.2342.19200300.100.1.13", "RFC 4524"),
-       /** */
-       documentAuthor("0.9.2342.19200300.100.1.14", "RFC 4524"),
-       /** */
-       documentLocation("0.9.2342.19200300.100.1.15", "RFC 4524"),
-       /** */
-       homePhone("0.9.2342.19200300.100.1.20", "RFC 4524"),
-       /** */
-       secretary("0.9.2342.19200300.100.1.21", "RFC 4524"),
-       /** */
-       dc("0.9.2342.19200300.100.1.25", "RFC 4519"),
-       /** */
-       associatedDomain("0.9.2342.19200300.100.1.37", "RFC 4524"),
-       /** */
-       associatedName("0.9.2342.19200300.100.1.38", "RFC 4524"),
-       /** */
-       homePostalAddress("0.9.2342.19200300.100.1.39", "RFC 4524"),
-       /** */
-       personalTitle("0.9.2342.19200300.100.1.40", "RFC 4524"),
-       /** */
-       mobile("0.9.2342.19200300.100.1.41", "RFC 4524"),
-       /** */
-       pager("0.9.2342.19200300.100.1.42", "RFC 4524"),
-       /** */
-       co("0.9.2342.19200300.100.1.43", "RFC 4524"),
-       /** */
-       uniqueIdentifier("0.9.2342.19200300.100.1.44", "RFC 4524"),
-       /** */
-       organizationalStatus("0.9.2342.19200300.100.1.45", "RFC 4524"),
-       /** */
-       buildingName("0.9.2342.19200300.100.1.48", "RFC 4524"),
-       /** */
-       audio("0.9.2342.19200300.100.1.55", "RFC 2798"),
-       /** */
-       documentPublisher("0.9.2342.19200300.100.1.56", "RFC 4524"),
-       /** */
-       jpegPhoto("0.9.2342.19200300.100.1.60", "RFC 2798"),
-       /** */
-       vendorName("1.3.6.1.1.4", "RFC 3045"),
-       /** */
-       vendorVersion("1.3.6.1.1.5", "RFC 3045"),
-       /** */
-       entryUUID("1.3.6.1.1.16.4", "RFC 4530"),
-       /** */
-       entryDN("1.3.6.1.1.20", "RFC 5020"),
-       /** */
-       labeledURI("1.3.6.1.4.1.250.1.57", "RFC 2798"),
-       /** */
-       numSubordinates("1.3.6.1.4.1.453.16.2.103", "draft-ietf-boreham-numsubordinates"),
-       /** */
-       namingContexts("1.3.6.1.4.1.1466.101.120.5", "RFC 4512"),
-       /** */
-       altServer("1.3.6.1.4.1.1466.101.120.6", "RFC 4512"),
-       /** */
-       supportedExtension("1.3.6.1.4.1.1466.101.120.7", "RFC 4512"),
-       /** */
-       supportedControl("1.3.6.1.4.1.1466.101.120.13", "RFC 4512"),
-       /** */
-       supportedSASLMechanisms("1.3.6.1.4.1.1466.101.120.14", "RFC 4512"),
-       /** */
-       supportedLDAPVersion("1.3.6.1.4.1.1466.101.120.15", "RFC 4512"),
-       /** */
-       ldapSyntaxes("1.3.6.1.4.1.1466.101.120.16", "RFC 4512"),
-       /** */
-       supportedAuthPasswordSchemes("1.3.6.1.4.1.4203.1.3.3", "RFC 3112"),
-       /** */
-       authPassword("1.3.6.1.4.1.4203.1.3.4", "RFC 3112"),
-       /** */
-       supportedFeatures("1.3.6.1.4.1.4203.1.3.5", "RFC 4512"),
-       /** */
-       inheritable("1.3.6.1.4.1.7628.5.4.1", "draft-ietf-ldup-subentry"),
-       /** */
-       blockInheritance("1.3.6.1.4.1.7628.5.4.2", "draft-ietf-ldup-subentry"),
-       /** */
-       objectClass("2.5.4.0", "RFC 4512"),
-       /** */
-       aliasedObjectName("2.5.4.1", "RFC 4512"),
-       /** */
-       cn("2.5.4.3", "RFC 4519"),
-       /** */
-       sn("2.5.4.4", "RFC 4519"),
-       /** */
-       serialNumber("2.5.4.5", "RFC 4519"),
-       /** */
-       c("2.5.4.6", "RFC 4519"),
-       /** */
-       l("2.5.4.7", "RFC 4519"),
-       /** */
-       st("2.5.4.8", "RFC 4519"),
-       /** */
-       street("2.5.4.9", "RFC 4519"),
-       /** */
-       o("2.5.4.10", "RFC 4519"),
-       /** */
-       ou("2.5.4.11", "RFC 4519"),
-       /** */
-       title("2.5.4.12", "RFC 4519"),
-       /** */
-       description("2.5.4.13", "RFC 4519"),
-       /** */
-       searchGuide("2.5.4.14", "RFC 4519"),
-       /** */
-       businessCategory("2.5.4.15", "RFC 4519"),
-       /** */
-       postalAddress("2.5.4.16", "RFC 4519"),
-       /** */
-       postalCode("2.5.4.17", "RFC 4519"),
-       /** */
-       postOfficeBox("2.5.4.18", "RFC 4519"),
-       /** */
-       physicalDeliveryOfficeName("2.5.4.19", "RFC 4519"),
-       /** */
-       telephoneNumber("2.5.4.20", "RFC 4519"),
-       /** */
-       telexNumber("2.5.4.21", "RFC 4519"),
-       /** */
-       teletexTerminalIdentifier("2.5.4.22", "RFC 4519"),
-       /** */
-       facsimileTelephoneNumber("2.5.4.23", "RFC 4519"),
-       /** */
-       x121Address("2.5.4.24", "RFC 4519"),
-       /** */
-       internationalISDNNumber("2.5.4.25", "RFC 4519"),
-       /** */
-       registeredAddress("2.5.4.26", "RFC 4519"),
-       /** */
-       destinationIndicator("2.5.4.27", "RFC 4519"),
-       /** */
-       preferredDeliveryMethod("2.5.4.28", "RFC 4519"),
-       /** */
-       member("2.5.4.31", "RFC 4519"),
-       /** */
-       owner("2.5.4.32", "RFC 4519"),
-       /** */
-       roleOccupant("2.5.4.33", "RFC 4519"),
-       /** */
-       seeAlso("2.5.4.34", "RFC 4519"),
-       /** */
-       userPassword("2.5.4.35", "RFC 4519"),
-       /** */
-       userCertificate("2.5.4.36", "RFC 4523"),
-       /** */
-       cACertificate("2.5.4.37", "RFC 4523"),
-       /** */
-       authorityRevocationList("2.5.4.38", "RFC 4523"),
-       /** */
-       certificateRevocationList("2.5.4.39", "RFC 4523"),
-       /** */
-       crossCertificatePair("2.5.4.40", "RFC 4523"),
-       /** */
-       name("2.5.4.41", "RFC 4519"),
-       /** */
-       givenName("2.5.4.42", "RFC 4519"),
-       /** */
-       initials("2.5.4.43", "RFC 4519"),
-       /** */
-       generationQualifier("2.5.4.44", "RFC 4519"),
-       /** */
-       x500UniqueIdentifier("2.5.4.45", "RFC 4519"),
-       /** */
-       dnQualifier("2.5.4.46", "RFC 4519"),
-       /** */
-       enhancedSearchGuide("2.5.4.47", "RFC 4519"),
-       /** */
-       distinguishedName("2.5.4.49", "RFC 4519"),
-       /** */
-       uniqueMember("2.5.4.50", "RFC 4519"),
-       /** */
-       houseIdentifier("2.5.4.51", "RFC 4519"),
-       /** */
-       supportedAlgorithms("2.5.4.52", "RFC 4523"),
-       /** */
-       deltaRevocationList("2.5.4.53", "RFC 4523"),
-       /** */
-       createTimestamp("2.5.18.1", "RFC 4512"),
-       /** */
-       modifyTimestamp("2.5.18.2", "RFC 4512"),
-       /** */
-       creatorsName("2.5.18.3", "RFC 4512"),
-       /** */
-       modifiersName("2.5.18.4", "RFC 4512"),
-       /** */
-       subschemaSubentry("2.5.18.10", "RFC 4512"),
-       /** */
-       dITStructureRules("2.5.21.1", "RFC 4512"),
-       /** */
-       dITContentRules("2.5.21.2", "RFC 4512"),
-       /** */
-       matchingRules("2.5.21.4", "RFC 4512"),
-       /** */
-       attributeTypes("2.5.21.5", "RFC 4512"),
-       /** */
-       objectClasses("2.5.21.6", "RFC 4512"),
-       /** */
-       nameForms("2.5.21.7", "RFC 4512"),
-       /** */
-       matchingRuleUse("2.5.21.8", "RFC 4512"),
-       /** */
-       structuralObjectClass("2.5.21.9", "RFC 4512"),
-       /** */
-       governingStructureRule("2.5.21.10", "RFC 4512"),
-       /** */
-       carLicense("2.16.840.1.113730.3.1.1", "RFC 2798"),
-       /** */
-       departmentNumber("2.16.840.1.113730.3.1.2", "RFC 2798"),
-       /** */
-       employeeNumber("2.16.840.1.113730.3.1.3", "RFC 2798"),
-       /** */
-       employeeType("2.16.840.1.113730.3.1.4", "RFC 2798"),
-       /** */
-       changeNumber("2.16.840.1.113730.3.1.5", "draft-good-ldap-changelog"),
-       /** */
-       targetDN("2.16.840.1.113730.3.1.6", "draft-good-ldap-changelog"),
-       /** */
-       changeType("2.16.840.1.113730.3.1.7", "draft-good-ldap-changelog"),
-       /** */
-       changes("2.16.840.1.113730.3.1.8", "draft-good-ldap-changelog"),
-       /** */
-       newRDN("2.16.840.1.113730.3.1.9", "draft-good-ldap-changelog"),
-       /** */
-       deleteOldRDN("2.16.840.1.113730.3.1.10", "draft-good-ldap-changelog"),
-       /** */
-       newSuperior("2.16.840.1.113730.3.1.11", "draft-good-ldap-changelog"),
-       /** */
-       ref("2.16.840.1.113730.3.1.34", "RFC 3296"),
-       /** */
-       changelog("2.16.840.1.113730.3.1.35", "draft-good-ldap-changelog"),
-       /** */
-       preferredLanguage("2.16.840.1.113730.3.1.39", "RFC 2798"),
-       /** */
-       userSMIMECertificate("2.16.840.1.113730.3.1.40", "RFC 2798"),
-       /** */
-       userPKCS12("2.16.840.1.113730.3.1.216", "RFC 2798"),
-       /** */
-       displayName("2.16.840.1.113730.3.1.241", "RFC 2798"),
-
-       // Sun memberOf
-       memberOf("1.2.840.113556.1.2.102", "389 DS memberOf"),
-
-       // KERBEROS (partial)
-       krbPrincipalName("2.16.840.1.113719.1.301.6.8.1", "Novell Kerberos Schema Definitions"),
-
-       // RFC 2985 and RFC 3039 (partial)
-       dateOfBirth("1.3.6.1.5.5.7.9.1", "RFC 2985"),
-       /** */
-       placeOfBirth("1.3.6.1.5.5.7.9.2", "RFC 2985"),
-       /** */
-       gender("1.3.6.1.5.5.7.9.3", "RFC 2985"),
-       /** */
-       countryOfCitizenship("1.3.6.1.5.5.7.9.4", "RFC 2985"),
-       /** */
-       countryOfResidence("1.3.6.1.5.5.7.9.5", "RFC 2985"),
-       //
-       ;
-
-       public final static String DN = "dn";
-
-//     private final static String LDAP_ = "ldap:";
-
-       private final String oid, spec;
-
-       LdapAttrs(String oid, String spec) {
-               this.oid = oid;
-               this.spec = spec;
-       }
-
-       @Override
-       public String getID() {
-               return oid;
-       }
-
-       @Override
-       public String getSpec() {
-               return spec;
-       }
-
-       public String getPrefix() {
-               return prefix();
-       }
-
-       public static String prefix() {
-               return "ldap";
-       }
-
-       public String property() {
-               return qualified();
-       }
-
-       public String qualified() {
-               String prefix = getPrefix();
-               return prefix != null ? prefix + ":" + name() : name();
-       }
-
-       public String getNamespace() {
-               return namespace();
-       }
-
-       public static String namespace() {
-               return "http://www.argeo.org/ns/ldap";
-       }
-
-       @Override
-       public final String toString() {
-               // must return the name
-               return name();
-       }
-
-}
diff --git a/org.argeo.util/src/org/argeo/naming/LdapObjs.csv b/org.argeo.util/src/org/argeo/naming/LdapObjs.csv
deleted file mode 100644 (file)
index 3d907cb..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-account,,,0.9.2342.19200300.100.4.5,,RFC 4524
-document,,,0.9.2342.19200300.100.4.6,,RFC 4524
-room,,,0.9.2342.19200300.100.4.7,,RFC 4524
-documentSeries,,,0.9.2342.19200300.100.4.9,,RFC 4524
-domain,,,0.9.2342.19200300.100.4.13,,RFC 4524
-rFC822localPart,,,0.9.2342.19200300.100.4.14,,RFC 4524
-domainRelatedObject,,,0.9.2342.19200300.100.4.17,,RFC 4524
-friendlyCountry,,,0.9.2342.19200300.100.4.18,,RFC 4524
-simpleSecurityObject,,,0.9.2342.19200300.100.4.19,,RFC 4524
-uidObject,,,1.3.6.1.1.3.1,,RFC 4519
-extensibleObject,,,1.3.6.1.4.1.1466.101.120.111,,RFC 4512
-dcObject,,,1.3.6.1.4.1.1466.344,,RFC 4519
-authPasswordObject,,,1.3.6.1.4.1.4203.1.4.7,,RFC 3112
-namedObject,,,1.3.6.1.4.1.5322.13.1.1,,draft-howard-namedobject
-inheritableLDAPSubEntry,,,1.3.6.1.4.1.7628.5.6.1.1,,draft-ietf-ldup-subentry
-top,,,2.5.6.0,,RFC 4512
-alias,,,2.5.6.1,,RFC 4512
-country,,,2.5.6.2,,RFC 4519
-locality,,,2.5.6.3,,RFC 4519
-organization,,,2.5.6.4,,RFC 4519
-organizationalUnit,,,2.5.6.5,,RFC 4519
-person,,,2.5.6.6,,RFC 4519
-organizationalPerson,,,2.5.6.7,,RFC 4519
-organizationalRole,,,2.5.6.8,,RFC 4519
-groupOfNames,,,2.5.6.9,,RFC 4519
-residentialPerson,,,2.5.6.10,,RFC 4519
-applicationProcess,,,2.5.6.11,,RFC 4519
-device,,,2.5.6.14,,RFC 4519
-strongAuthenticationUser,,,2.5.6.15,,RFC 4523
-certificationAuthority,,,2.5.6.16,,RFC 4523
-certificationAuthority-V2,,,2.5.6.16.2,,RFC 4523
-groupOfUniqueNames,,,2.5.6.17,,RFC 4519
-userSecurityInformation,,,2.5.6.18,,RFC 4523
-cRLDistributionPoint,,,2.5.6.19,,RFC 4523
-pkiUser,,,2.5.6.21,,RFC 4523
-pkiCA,,,2.5.6.22,,RFC 4523
-deltaCRL,,,2.5.6.23,,RFC 4523
-subschema,,,2.5.20.1,,RFC 4512
-ldapSubEntry,,,2.16.840.1.113719.2.142.6.1.1,,draft-ietf-ldup-subentry
-changeLogEntry,,,2.16.840.1.113730.3.2.1,,draft-good-ldap-changelog
-inetOrgPerson,,,2.16.840.1.113730.3.2.2,,RFC 2798
-referral,,,2.16.840.1.113730.3.2.6,,RFC 3296
diff --git a/org.argeo.util/src/org/argeo/naming/LdapObjs.java b/org.argeo.util/src/org/argeo/naming/LdapObjs.java
deleted file mode 100644 (file)
index 0611675..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.argeo.naming;
-
-/**
- * Standard LDAP object classes as per
- * <a href="https://www.ldap.com/ldap-oid-reference">https://www.ldap.com/ldap-
- * oid-reference</a>
- */
-public enum LdapObjs implements SpecifiedName {
-       account("0.9.2342.19200300.100.4.5", "RFC 4524"),
-       /** */
-       document("0.9.2342.19200300.100.4.6", "RFC 4524"),
-       /** */
-       room("0.9.2342.19200300.100.4.7", "RFC 4524"),
-       /** */
-       documentSeries("0.9.2342.19200300.100.4.9", "RFC 4524"),
-       /** */
-       domain("0.9.2342.19200300.100.4.13", "RFC 4524"),
-       /** */
-       rFC822localPart("0.9.2342.19200300.100.4.14", "RFC 4524"),
-       /** */
-       domainRelatedObject("0.9.2342.19200300.100.4.17", "RFC 4524"),
-       /** */
-       friendlyCountry("0.9.2342.19200300.100.4.18", "RFC 4524"),
-       /** */
-       simpleSecurityObject("0.9.2342.19200300.100.4.19", "RFC 4524"),
-       /** */
-       uidObject("1.3.6.1.1.3.1", "RFC 4519"),
-       /** */
-       extensibleObject("1.3.6.1.4.1.1466.101.120.111", "RFC 4512"),
-       /** */
-       dcObject("1.3.6.1.4.1.1466.344", "RFC 4519"),
-       /** */
-       authPasswordObject("1.3.6.1.4.1.4203.1.4.7", "RFC 3112"),
-       /** */
-       namedObject("1.3.6.1.4.1.5322.13.1.1", "draft-howard-namedobject"),
-       /** */
-       inheritableLDAPSubEntry("1.3.6.1.4.1.7628.5.6.1.1", "draft-ietf-ldup-subentry"),
-       /** */
-       top("2.5.6.0", "RFC 4512"),
-       /** */
-       alias("2.5.6.1", "RFC 4512"),
-       /** */
-       country("2.5.6.2", "RFC 4519"),
-       /** */
-       locality("2.5.6.3", "RFC 4519"),
-       /** */
-       organization("2.5.6.4", "RFC 4519"),
-       /** */
-       organizationalUnit("2.5.6.5", "RFC 4519"),
-       /** */
-       person("2.5.6.6", "RFC 4519"),
-       /** */
-       organizationalPerson("2.5.6.7", "RFC 4519"),
-       /** */
-       organizationalRole("2.5.6.8", "RFC 4519"),
-       /** */
-       groupOfNames("2.5.6.9", "RFC 4519"),
-       /** */
-       residentialPerson("2.5.6.10", "RFC 4519"),
-       /** */
-       applicationProcess("2.5.6.11", "RFC 4519"),
-       /** */
-       device("2.5.6.14", "RFC 4519"),
-       /** */
-       strongAuthenticationUser("2.5.6.15", "RFC 4523"),
-       /** */
-       certificationAuthority("2.5.6.16", "RFC 4523"),
-       // /** Should be certificationAuthority-V2 */
-       // certificationAuthority_V2("2.5.6.16.2", "RFC 4523") {
-       // },
-       /** */
-       groupOfUniqueNames("2.5.6.17", "RFC 4519"),
-       /** */
-       userSecurityInformation("2.5.6.18", "RFC 4523"),
-       /** */
-       cRLDistributionPoint("2.5.6.19", "RFC 4523"),
-       /** */
-       pkiUser("2.5.6.21", "RFC 4523"),
-       /** */
-       pkiCA("2.5.6.22", "RFC 4523"),
-       /** */
-       deltaCRL("2.5.6.23", "RFC 4523"),
-       /** */
-       subschema("2.5.20.1", "RFC 4512"),
-       /** */
-       ldapSubEntry("2.16.840.1.113719.2.142.6.1.1", "draft-ietf-ldup-subentry"),
-       /** */
-       changeLogEntry("2.16.840.1.113730.3.2.1", "draft-good-ldap-changelog"),
-       /** */
-       inetOrgPerson("2.16.840.1.113730.3.2.2", "RFC 2798"),
-       /** */
-       referral("2.16.840.1.113730.3.2.6", "RFC 3296");
-
-       private final static String LDAP_ = "ldap:";
-       private final String oid, spec;
-
-       private LdapObjs(String oid, String spec) {
-               this.oid = oid;
-               this.spec = spec;
-       }
-
-       public String getOid() {
-               return oid;
-       }
-
-       public String getSpec() {
-               return spec;
-       }
-
-       public String property() {
-               return new StringBuilder(LDAP_).append(name()).toString();
-       }
-
-}
diff --git a/org.argeo.util/src/org/argeo/naming/LdifParser.java b/org.argeo.util/src/org/argeo/naming/LdifParser.java
deleted file mode 100644 (file)
index cc19570..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.argeo.naming;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.List;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import javax.naming.InvalidNameException;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.BasicAttributes;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
-
-import org.argeo.osgi.useradmin.UserDirectoryException;
-
-/** Basic LDIF parser. */
-public class LdifParser {
-       private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
-
-       protected Attributes addAttributes(SortedMap<LdapName, Attributes> res, int lineNumber, LdapName currentDn,
-                       Attributes currentAttributes) {
-               try {
-                       Rdn nameRdn = currentDn.getRdn(currentDn.size() - 1);
-                       Attribute nameAttr = currentAttributes.get(nameRdn.getType());
-                       if (nameAttr == null)
-                               currentAttributes.put(nameRdn.getType(), nameRdn.getValue());
-                       else if (!nameAttr.get().equals(nameRdn.getValue()))
-                               throw new UserDirectoryException(
-                                               "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn
-                                                               + " (shortly before line " + lineNumber + " in LDIF file)");
-                       Attributes previous = res.put(currentDn, currentAttributes);
-                       return previous;
-               } catch (NamingException e) {
-                       throw new UserDirectoryException("Cannot add " + currentDn, e);
-               }
-       }
-
-       /** With UTF-8 charset */
-       public SortedMap<LdapName, Attributes> read(InputStream in) throws IOException {
-               try (Reader reader = new InputStreamReader(in, DEFAULT_CHARSET)) {
-                       return read(reader);
-               } finally {
-                       try {
-                               in.close();
-                       } catch (IOException e) {
-                               // silent
-                       }
-               }
-       }
-
-       /** Will close the reader. */
-       public SortedMap<LdapName, Attributes> read(Reader reader) throws IOException {
-               SortedMap<LdapName, Attributes> res = new TreeMap<LdapName, Attributes>();
-               try {
-                       List<String> lines = new ArrayList<>();
-                       try (BufferedReader br = new BufferedReader(reader)) {
-                               String line;
-                               while ((line = br.readLine()) != null) {
-                                       lines.add(line);
-                               }
-                       }
-                       if (lines.size() == 0)
-                               return res;
-                       // add an empty new line since the last line is not checked
-                       if (!lines.get(lines.size() - 1).equals(""))
-                               lines.add("");
-
-                       LdapName currentDn = null;
-                       Attributes currentAttributes = null;
-                       StringBuilder currentEntry = new StringBuilder();
-
-                       readLines: for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
-                               String line = lines.get(lineNumber);
-                               boolean isLastLine = false;
-                               if (lineNumber == lines.size() - 1)
-                                       isLastLine = true;
-                               if (line.startsWith(" ")) {
-                                       currentEntry.append(line.substring(1));
-                                       if (!isLastLine)
-                                               continue readLines;
-                               }
-
-                               if (currentEntry.length() != 0 || isLastLine) {
-                                       // read previous attribute
-                                       StringBuilder attrId = new StringBuilder(8);
-                                       boolean isBase64 = false;
-                                       readAttrId: for (int i = 0; i < currentEntry.length(); i++) {
-                                               char c = currentEntry.charAt(i);
-                                               if (c == ':') {
-                                                       if (i + 1 < currentEntry.length() && currentEntry.charAt(i + 1) == ':')
-                                                               isBase64 = true;
-                                                       currentEntry.delete(0, i + (isBase64 ? 2 : 1));
-                                                       break readAttrId;
-                                               } else {
-                                                       attrId.append(c);
-                                               }
-                                       }
-
-                                       String attributeId = attrId.toString();
-                                       // TODO should we really trim the end of the string as well?
-                                       String cleanValueStr = currentEntry.toString().trim();
-                                       Object attributeValue = isBase64 ? Base64.getDecoder().decode(cleanValueStr) : cleanValueStr;
-
-                                       // manage DN attributes
-                                       if (attributeId.equals(LdapAttrs.DN) || isLastLine) {
-                                               if (currentDn != null) {
-                                                       //
-                                                       // ADD
-                                                       //
-                                                       Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes);
-                                                       if (previous != null) {
-//                                                             log.warn("There was already an entry with DN " + currentDn
-//                                                                             + ", which has been discarded by a subsequent one.");
-                                                       }
-                                               }
-
-                                               if (attributeId.equals(LdapAttrs.DN))
-                                                       try {
-                                                               currentDn = new LdapName(attributeValue.toString());
-                                                               currentAttributes = new BasicAttributes(true);
-                                                       } catch (InvalidNameException e) {
-//                                                             log.error(attributeValue + " not a valid DN, skipping the entry.");
-                                                               currentDn = null;
-                                                               currentAttributes = null;
-                                                       }
-                                       }
-
-                                       // store attribute
-                                       if (currentAttributes != null) {
-                                               Attribute attribute = currentAttributes.get(attributeId);
-                                               if (attribute == null) {
-                                                       attribute = new BasicAttribute(attributeId);
-                                                       currentAttributes.put(attribute);
-                                               }
-                                               attribute.add(attributeValue);
-                                       }
-                                       currentEntry = new StringBuilder();
-                               }
-                               currentEntry.append(line);
-                       }
-               } finally {
-                       try {
-                               reader.close();
-                       } catch (IOException e) {
-                               // silent
-                       }
-               }
-               return res;
-       }
-}
\ No newline at end of file
diff --git a/org.argeo.util/src/org/argeo/naming/LdifWriter.java b/org.argeo.util/src/org/argeo/naming/LdifWriter.java
deleted file mode 100644 (file)
index 98d2df0..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.argeo.naming;
-
-import static org.argeo.naming.LdapAttrs.DN;
-import static org.argeo.naming.LdapAttrs.member;
-import static org.argeo.naming.LdapAttrs.objectClass;
-import static org.argeo.naming.LdapAttrs.uniqueMember;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
-
-import org.argeo.osgi.useradmin.UserDirectoryException;
-
-/** Basic LDIF writer */
-public class LdifWriter {
-       private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
-       private final Writer writer;
-
-       /** Writer must be closed by caller */
-       public LdifWriter(Writer writer) {
-               this.writer = writer;
-       }
-
-       /** Stream must be closed by caller */
-       public LdifWriter(OutputStream out) {
-               this(new OutputStreamWriter(out, DEFAULT_CHARSET));
-       }
-
-       public void writeEntry(LdapName name, Attributes attributes) throws IOException {
-               try {
-                       // check consistency
-                       Rdn nameRdn = name.getRdn(name.size() - 1);
-                       Attribute nameAttr = attributes.get(nameRdn.getType());
-                       if (!nameAttr.get().equals(nameRdn.getValue()))
-                               throw new UserDirectoryException(
-                                               "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + name);
-
-                       writer.append(DN + ": ").append(name.toString()).append('\n');
-                       Attribute objectClassAttr = attributes.get(objectClass.name());
-                       if (objectClassAttr != null)
-                               writeAttribute(objectClassAttr);
-                       attributes: for (NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMore();) {
-                               Attribute attribute = attrs.next();
-                               if (attribute.getID().equals(DN) || attribute.getID().equals(objectClass.name()))
-                                       continue attributes;// skip DN attribute
-                               if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name()))
-                                       continue attributes;// skip member and uniqueMember attributes, so that they are always written last
-                               writeAttribute(attribute);
-                       }
-                       // write member and uniqueMember attributes last
-                       for (NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMore();) {
-                               Attribute attribute = attrs.next();
-                               if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name()))
-                                       writeMemberAttribute(attribute);
-                       }
-                       writer.append('\n');
-                       writer.flush();
-               } catch (NamingException e) {
-                       throw new UserDirectoryException("Cannot write LDIF", e);
-               }
-       }
-
-       public void write(Map<LdapName, Attributes> entries) throws IOException {
-               for (LdapName dn : entries.keySet())
-                       writeEntry(dn, entries.get(dn));
-       }
-
-       protected void writeAttribute(Attribute attribute) throws NamingException, IOException {
-               for (NamingEnumeration<?> attrValues = attribute.getAll(); attrValues.hasMore();) {
-                       Object value = attrValues.next();
-                       if (value instanceof byte[]) {
-                               String encoded = Base64.getEncoder().encodeToString((byte[]) value);
-                               writer.append(attribute.getID()).append(":: ").append(encoded).append('\n');
-                       } else {
-                               writer.append(attribute.getID()).append(": ").append(value.toString()).append('\n');
-                       }
-               }
-       }
-
-       protected void writeMemberAttribute(Attribute attribute) throws NamingException, IOException {
-               // Note: duplicate entries will be swallowed
-               SortedSet<String> values = new TreeSet<>();
-               for (NamingEnumeration<?> attrValues = attribute.getAll(); attrValues.hasMore();) {
-                       String value = attrValues.next().toString();
-                       values.add(value);
-               }
-
-               for (String value : values) {
-                       writer.append(attribute.getID()).append(": ").append(value).append('\n');
-               }
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/naming/NamingUtils.java b/org.argeo.util/src/org/argeo/naming/NamingUtils.java
deleted file mode 100644 (file)
index 5a868dd..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.argeo.naming;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import java.time.OffsetDateTime;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeParseException;
-import java.time.temporal.ChronoField;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-public class NamingUtils {
-       /** As per https://tools.ietf.org/html/rfc4517#section-3.3.13 */
-       private final static DateTimeFormatter utcLdapDate = DateTimeFormatter.ofPattern("uuuuMMddHHmmssX")
-                       .withZone(ZoneOffset.UTC);
-
-       /** @return null if not parseable */
-       public static Instant ldapDateToInstant(String ldapDate) {
-               try {
-                       return OffsetDateTime.parse(ldapDate, utcLdapDate).toInstant();
-               } catch (DateTimeParseException e) {
-                       return null;
-               }
-       }
-
-       /** @return null if not parseable */
-       public static ZonedDateTime ldapDateToZonedDateTime(String ldapDate) {
-               try {
-                       return OffsetDateTime.parse(ldapDate, utcLdapDate).toZonedDateTime();
-               } catch (DateTimeParseException e) {
-                       return null;
-               }
-       }
-
-       public static Calendar ldapDateToCalendar(String ldapDate) {
-               OffsetDateTime instant = OffsetDateTime.parse(ldapDate, utcLdapDate);
-               GregorianCalendar calendar = new GregorianCalendar();
-               calendar.set(Calendar.DAY_OF_MONTH, instant.get(ChronoField.DAY_OF_MONTH));
-               calendar.set(Calendar.MONTH, instant.get(ChronoField.MONTH_OF_YEAR));
-               calendar.set(Calendar.YEAR, instant.get(ChronoField.YEAR));
-               return calendar;
-       }
-
-       public static String instantToLdapDate(ZonedDateTime instant) {
-               return utcLdapDate.format(instant.withZoneSameInstant(ZoneOffset.UTC));
-       }
-
-       public static String getQueryValue(Map<String, List<String>> query, String key) {
-               if (!query.containsKey(key))
-                       return null;
-               List<String> val = query.get(key);
-               if (val.size() == 1)
-                       return val.get(0);
-               else
-                       throw new IllegalArgumentException("There are " + val.size() + " value(s) for " + key);
-       }
-
-       public static Map<String, List<String>> queryToMap(URI uri) {
-               return queryToMap(uri.getQuery());
-       }
-
-       private static Map<String, List<String>> queryToMap(String queryPart) {
-               try {
-                       final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
-                       if (queryPart == null)
-                               return query_pairs;
-                       final String[] pairs = queryPart.split("&");
-                       for (String pair : pairs) {
-                               final int idx = pair.indexOf("=");
-                               final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8.name())
-                                               : pair;
-                               if (!query_pairs.containsKey(key)) {
-                                       query_pairs.put(key, new LinkedList<String>());
-                               }
-                               final String value = idx > 0 && pair.length() > idx + 1
-                                               ? URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8.name())
-                                               : null;
-                               query_pairs.get(key).add(value);
-                       }
-                       return query_pairs;
-               } catch (UnsupportedEncodingException e) {
-                       throw new IllegalArgumentException("Cannot convert " + queryPart + " to map", e);
-               }
-       }
-
-       private NamingUtils() {
-
-       }
-
-       public static void main(String args[]) {
-               ZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC);
-               String str = utcLdapDate.format(now);
-               System.out.println(str);
-               utcLdapDate.parse(str);
-               utcLdapDate.parse("19520512000000Z");
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/naming/SharedSecret.java b/org.argeo.util/src/org/argeo/naming/SharedSecret.java
deleted file mode 100644 (file)
index 369b411..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.argeo.naming;
-
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-
-public class SharedSecret extends AuthPassword {
-       public final static String X_SHARED_SECRET = "X-SharedSecret";
-       private final Instant expiry;
-
-       public SharedSecret(String authInfo, String authValue) {
-               super(authInfo, authValue);
-               expiry = null;
-       }
-
-       public SharedSecret(AuthPassword authPassword) {
-               super(authPassword);
-               String authInfo = getAuthInfo();
-               if (authInfo.length() == 16) {
-                       expiry = NamingUtils.ldapDateToInstant(authInfo);
-               } else {
-                       expiry = null;
-               }
-       }
-
-       public SharedSecret(ZonedDateTime expiryTimestamp, String value) {
-               super(NamingUtils.instantToLdapDate(expiryTimestamp), value);
-               expiry = expiryTimestamp.withZoneSameInstant(ZoneOffset.UTC).toInstant();
-       }
-
-       public SharedSecret(int hours, String value) {
-               this(ZonedDateTime.now().plusHours(hours), value);
-       }
-
-       @Override
-       protected String getExpectedAuthScheme() {
-               return X_SHARED_SECRET;
-       }
-
-       public boolean isExpired() {
-               if (expiry == null)
-                       return false;
-               return expiry.isBefore(Instant.now());
-       }
-
-}
diff --git a/org.argeo.util/src/org/argeo/naming/SpecifiedName.java b/org.argeo.util/src/org/argeo/naming/SpecifiedName.java
deleted file mode 100644 (file)
index 28cc2f9..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.argeo.naming;
-
-/**
- * A name which has been specified and for which an id has been defined
- * (typically an OID).
- */
-public interface SpecifiedName {
-       /** The name */
-       String name();
-
-       /** An RFC or the URLof some specification */
-       default String getSpec() {
-               return null;
-       }
-
-       /** Typically an OID */
-       default String getID() {
-               return getClass().getName() + "." + name();
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/naming/SrvRecord.java b/org.argeo.util/src/org/argeo/naming/SrvRecord.java
deleted file mode 100644 (file)
index 8ecc944..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.argeo.naming;
-
-class SrvRecord implements Comparable<SrvRecord> {
-       private final Integer priority;
-       private final Integer weight;
-       private final Integer port;
-       private final String hostname;
-
-       public SrvRecord(Integer priority, Integer weight, Integer port, String hostname) {
-               this.priority = priority;
-               this.weight = weight;
-               this.port = port;
-               this.hostname = hostname;
-       }
-
-       @Override
-       public int compareTo(SrvRecord other) {
-               // https: // en.wikipedia.org/wiki/SRV_record
-               if (priority != other.priority)
-                       return priority - other.priority;
-               if (weight != other.weight)
-                       return other.weight - other.weight;
-               String host = toHost(false);
-               String otherHost = other.toHost(false);
-               if (host.length() == otherHost.length())
-                       return host.compareTo(otherHost);
-               else
-                       return host.length() - otherHost.length();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (obj instanceof SrvRecord) {
-                       SrvRecord other = (SrvRecord) obj;
-                       return priority == other.priority && weight == other.weight && port == other.port
-                                       && hostname.equals(other.hostname);
-               }
-               return false;
-       }
-
-       @Override
-       public String toString() {
-               return priority + " " + weight;
-       }
-
-       public String toHost(boolean withPort) {
-               String hostStr = hostname;
-               if (hostname.charAt(hostname.length() - 1) == '.')
-                       hostStr = hostname.substring(0, hostname.length() - 1);
-               return hostStr + (withPort ? ":" + port : "");
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/naming/package-info.java b/org.argeo.util/src/org/argeo/naming/package-info.java
deleted file mode 100644 (file)
index 95e7de3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Generic naming and LDAP support. */
-package org.argeo.naming;
\ No newline at end of file
index 44b4299343daee5298ab3d26aff8f0940ee9927d..0fc4f32aa100a8107f195e13f9f4663ac8e2e781 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.osgi.metatype;
 
-import org.argeo.naming.SpecifiedName;
+import org.argeo.util.naming.SpecifiedName;
 import org.osgi.service.metatype.AttributeDefinition;
 
 public interface EnumAD extends SpecifiedName, AttributeDefinition {
index 7279877e0e8ec46690a7f95b72ba062b234f8a34..095439093cfb6a77476b21ed12331a87ceaf2430 100644 (file)
@@ -1,11 +1,11 @@
 package org.argeo.osgi.useradmin;
 
-import static org.argeo.naming.LdapAttrs.objectClass;
-import static org.argeo.naming.LdapObjs.extensibleObject;
-import static org.argeo.naming.LdapObjs.inetOrgPerson;
-import static org.argeo.naming.LdapObjs.organizationalPerson;
-import static org.argeo.naming.LdapObjs.person;
-import static org.argeo.naming.LdapObjs.top;
+import static org.argeo.util.naming.LdapAttrs.objectClass;
+import static org.argeo.util.naming.LdapObjs.extensibleObject;
+import static org.argeo.util.naming.LdapObjs.inetOrgPerson;
+import static org.argeo.util.naming.LdapObjs.organizationalPerson;
+import static org.argeo.util.naming.LdapObjs.person;
+import static org.argeo.util.naming.LdapObjs.top;
 
 import java.io.File;
 import java.net.URI;
@@ -28,8 +28,8 @@ import javax.naming.directory.BasicAttributes;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
-import org.argeo.naming.LdapAttrs;
 import org.argeo.osgi.transaction.WorkControl;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.framework.Filter;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
index d56c06ac0964b8295fcfc655c4dc15ba0cf478a6..a9bc9417f5d2e436ec8734b2969723c2e8191ad0 100644 (file)
@@ -13,8 +13,8 @@ import javax.naming.InvalidNameException;
 import javax.naming.NamingException;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.DnsBrowser;
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.DnsBrowser;
+import org.argeo.util.naming.LdapAttrs;
 
 /** Free IPA specific conventions. */
 public class IpaUtils {
index 3e869f3b0f0f6fd473bd5c0e1455094b3cbf2739..ed69eb16b09443409757a9c6584a4909a5dcfc66 100644 (file)
@@ -15,7 +15,7 @@ import javax.naming.directory.SearchResult;
 import javax.naming.ldap.InitialLdapContext;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 
 /** A synchronized wrapper for a single {@link InitialLdapContext}. */
 // TODO implement multiple contexts and connection pooling.
index cd28748f583c70cbd6553fde16bd3d3a092ed369..f8396085bd44849294254466956b417c3e16d8b0 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.osgi.useradmin;
 
-import static org.argeo.naming.LdapAttrs.objectClass;
+import static org.argeo.util.naming.LdapAttrs.objectClass;
 
 import java.util.ArrayList;
 import java.util.Dictionary;
index 354f8c0e224d333f2f55b3903178c1bc285614d6..15afe08b1fbfbced1f9c2f6e58d07f0fa0f1ca8a 100644 (file)
@@ -5,7 +5,7 @@ import java.util.Collections;
 import java.util.Dictionary;
 import java.util.List;
 
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
index b3e7f5955579bac5c53dc57c1b8453f0307fa01e..6e8ad27116de610b151b2faaa7e2ef42b61dba48 100644 (file)
@@ -22,9 +22,9 @@ import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttribute;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.AuthPassword;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.SharedSecret;
+import org.argeo.util.naming.AuthPassword;
+import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.SharedSecret;
 
 /** Directory user implementation */
 class LdifUser implements DirectoryUser {
index c32bbc53fa9236f3f81211dfb8d6730a63ba746d..8b1206a72b1655b38c6f111e8bd335dc954222ff 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.osgi.useradmin;
 
-import static org.argeo.naming.LdapAttrs.objectClass;
-import static org.argeo.naming.LdapObjs.inetOrgPerson;
+import static org.argeo.util.naming.LdapAttrs.objectClass;
+import static org.argeo.util.naming.LdapObjs.inetOrgPerson;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -25,8 +25,8 @@ import javax.naming.NamingEnumeration;
 import javax.naming.directory.Attributes;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.LdifParser;
-import org.argeo.naming.LdifWriter;
+import org.argeo.util.naming.LdifParser;
+import org.argeo.util.naming.LdifWriter;
 import org.osgi.framework.Filter;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
index fe1ca7643f1a4ecf1596beeb870e9efdc21f7a2d..dd16e1a3be30a9f048455b8cdca58a01fe2d6288 100644 (file)
@@ -11,7 +11,7 @@ import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttributes;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.LdapAttrs;
+import org.argeo.util.naming.LdapAttrs;
 import org.osgi.framework.Filter;
 import org.osgi.service.useradmin.User;
 
index 83c1d76f68499a2cd1449f181f114f83acd5ac82..4b00e6c6ab6964a863c1b47aafd25c8bea0dd9a3 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.osgi.useradmin;
 
-import static org.argeo.naming.LdapAttrs.description;
-import static org.argeo.naming.LdapAttrs.owner;
+import static org.argeo.util.naming.LdapAttrs.description;
+import static org.argeo.util.naming.LdapAttrs.owner;
 
 import java.security.Principal;
 import java.time.Instant;
@@ -12,7 +12,7 @@ import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.security.auth.Subject;
 
-import org.argeo.naming.NamingUtils;
+import org.argeo.util.naming.NamingUtils;
 import org.osgi.service.useradmin.Group;
 
 /**
index ec41978dc3c441cb7f47ddc52cc392b902c23ca5..8941f98b4f92763a67f297fa56b4d30d7ae36488 100644 (file)
@@ -12,7 +12,7 @@ import java.util.Map;
 import javax.naming.Context;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.NamingUtils;
+import org.argeo.util.naming.NamingUtils;
 
 /** Properties used to configure user admins. */
 public enum UserAdminConf {
diff --git a/org.argeo.util/src/org/argeo/util/naming/AttributesDictionary.java b/org.argeo.util/src/org/argeo/util/naming/AttributesDictionary.java
new file mode 100644 (file)
index 0000000..7c645f3
--- /dev/null
@@ -0,0 +1,171 @@
+package org.argeo.util.naming;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+
+public class AttributesDictionary extends Dictionary<String, Object> {
+       private final Attributes attributes;
+
+       /** The provided attributes is wrapped, not copied. */
+       public AttributesDictionary(Attributes attributes) {
+               if (attributes == null)
+                       throw new IllegalArgumentException("Attributes cannot be null");
+               this.attributes = attributes;
+       }
+
+       @Override
+       public int size() {
+               return attributes.size();
+       }
+
+       @Override
+       public boolean isEmpty() {
+               return attributes.size() == 0;
+       }
+
+       @Override
+       public Enumeration<String> keys() {
+               NamingEnumeration<String> namingEnumeration = attributes.getIDs();
+               return new Enumeration<String>() {
+
+                       @Override
+                       public boolean hasMoreElements() {
+                               return namingEnumeration.hasMoreElements();
+                       }
+
+                       @Override
+                       public String nextElement() {
+                               return namingEnumeration.nextElement();
+                       }
+
+               };
+       }
+
+       @Override
+       public Enumeration<Object> elements() {
+               NamingEnumeration<String> namingEnumeration = attributes.getIDs();
+               return new Enumeration<Object>() {
+
+                       @Override
+                       public boolean hasMoreElements() {
+                               return namingEnumeration.hasMoreElements();
+                       }
+
+                       @Override
+                       public Object nextElement() {
+                               String key = namingEnumeration.nextElement();
+                               return get(key);
+                       }
+
+               };
+       }
+
+       @Override
+       /** @returns a <code>String</code> or <code>String[]</code> */
+       public Object get(Object key) {
+               try {
+                       if (key == null)
+                               throw new IllegalArgumentException("Key cannot be null");
+                       Attribute attr = attributes.get(key.toString());
+                       if (attr == null)
+                               return null;
+                       if (attr.size() == 0)
+                               throw new IllegalStateException("There must be at least one value");
+                       else if (attr.size() == 1) {
+                               return attr.get().toString();
+                       } else {// multiple
+                               String[] res = new String[attr.size()];
+                               for (int i = 0; i < attr.size(); i++) {
+                                       Object value = attr.get();
+                                       if (value == null)
+                                               throw new RuntimeException("Values cannot be null");
+                                       res[i] = attr.get(i).toString();
+                               }
+                               return res;
+                       }
+               } catch (NamingException e) {
+                       throw new RuntimeException("Cannot get value for " + key, e);
+               }
+       }
+
+       @Override
+       public Object put(String key, Object value) {
+               if (key == null)
+                       throw new IllegalArgumentException("Key cannot be null");
+               if (value == null)
+                       throw new IllegalArgumentException("Value cannot be null");
+
+               Object oldValue = get(key);
+               Attribute attr = attributes.get(key);
+               if (attr == null) {
+                       attr = new BasicAttribute(key);
+                       attributes.put(attr);
+               }
+
+               if (value instanceof String[]) {
+                       String[] values = (String[]) value;
+                       // clean additional values
+                       for (int i = values.length; i < attr.size(); i++)
+                               attr.remove(i);
+                       // set values
+                       for (int i = 0; i < values.length; i++) {
+                               attr.set(i, values[i]);
+                       }
+               } else {
+                       if (attr.size() > 1)
+                               throw new IllegalArgumentException("Attribute " + key + " is multi-valued");
+                       if (attr.size() == 1) {
+                               try {
+                                       if (!attr.get(0).equals(value))
+                                               attr.set(0, value.toString());
+                               } catch (NamingException e) {
+                                       throw new RuntimeException("Cannot check existing value", e);
+                               }
+                       } else {
+                               attr.add(value.toString());
+                       }
+               }
+               return oldValue;
+       }
+
+       @Override
+       public Object remove(Object key) {
+               if (key == null)
+                       throw new IllegalArgumentException("Key cannot be null");
+               Object oldValue = get(key);
+               if (oldValue == null)
+                       return null;
+               return attributes.remove(key.toString());
+       }
+
+       /**
+        * Copy the <b>content</b> of an {@link Attributes} to the provided
+        * {@link Dictionary}.
+        */
+       public static void copy(Attributes attributes, Dictionary<String, Object> dictionary) {
+               AttributesDictionary ad = new AttributesDictionary(attributes);
+               Enumeration<String> keys = ad.keys();
+               while (keys.hasMoreElements()) {
+                       String key = keys.nextElement();
+                       dictionary.put(key, ad.get(key));
+               }
+       }
+
+       /**
+        * Copy a {@link Dictionary} into an {@link Attributes}.
+        */
+       public static void copy(Dictionary<String, Object> dictionary, Attributes attributes) {
+               AttributesDictionary ad = new AttributesDictionary(attributes);
+               Enumeration<String> keys = dictionary.keys();
+               while (keys.hasMoreElements()) {
+                       String key = keys.nextElement();
+                       ad.put(key, dictionary.get(key));
+               }
+       }
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/AuthPassword.java b/org.argeo.util/src/org/argeo/util/naming/AuthPassword.java
new file mode 100644 (file)
index 0000000..973b90f
--- /dev/null
@@ -0,0 +1,140 @@
+package org.argeo.util.naming;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.StringTokenizer;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.argeo.osgi.useradmin.UserDirectoryException;
+
+/** LDAP authPassword field according to RFC 3112 */
+public class AuthPassword implements CallbackHandler {
+       private final String authScheme;
+       private final String authInfo;
+       private final String authValue;
+
+       public AuthPassword(String value) {
+               StringTokenizer st = new StringTokenizer(value, "$");
+               // TODO make it more robust, deal with bad formatting
+               this.authScheme = st.nextToken().trim();
+               this.authInfo = st.nextToken().trim();
+               this.authValue = st.nextToken().trim();
+
+               String expectedAuthScheme = getExpectedAuthScheme();
+               if (expectedAuthScheme != null && !authScheme.equals(expectedAuthScheme))
+                       throw new IllegalArgumentException(
+                                       "Auth scheme " + authScheme + " is not compatible with " + expectedAuthScheme);
+       }
+
+       protected AuthPassword(String authInfo, String authValue) {
+               this.authScheme = getExpectedAuthScheme();
+               if (authScheme == null)
+                       throw new IllegalArgumentException("Expected auth scheme cannot be null");
+               this.authInfo = authInfo;
+               this.authValue = authValue;
+       }
+
+       protected AuthPassword(AuthPassword authPassword) {
+               this.authScheme = authPassword.getAuthScheme();
+               this.authInfo = authPassword.getAuthInfo();
+               this.authValue = authPassword.getAuthValue();
+       }
+
+       protected String getExpectedAuthScheme() {
+               return null;
+       }
+
+       protected boolean matchAuthValue(Object object) {
+               return authValue.equals(object.toString());
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (!(obj instanceof AuthPassword))
+                       return false;
+               AuthPassword authPassword = (AuthPassword) obj;
+               return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo)
+                               && authValue.equals(authValue);
+       }
+
+       public boolean keyEquals(AuthPassword authPassword) {
+               return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo);
+       }
+
+       @Override
+       public int hashCode() {
+               return authValue.hashCode();
+       }
+
+       @Override
+       public String toString() {
+               return toAuthPassword();
+       }
+
+       public final String toAuthPassword() {
+               return getAuthScheme() + '$' + authInfo + '$' + authValue;
+       }
+
+       public String getAuthScheme() {
+               return authScheme;
+       }
+
+       public String getAuthInfo() {
+               return authInfo;
+       }
+
+       public String getAuthValue() {
+               return authValue;
+       }
+
+       public static AuthPassword matchAuthValue(Attributes attributes, char[] value) {
+               try {
+                       Attribute authPassword = attributes.get(LdapAttrs.authPassword.name());
+                       if (authPassword != null) {
+                               NamingEnumeration<?> values = authPassword.getAll();
+                               while (values.hasMore()) {
+                                       Object val = values.next();
+                                       AuthPassword token = new AuthPassword(val.toString());
+                                       String auth;
+                                       if (Arrays.binarySearch(value, '$') >= 0) {
+                                               auth = token.authInfo + '$' + token.authValue;
+                                       } else {
+                                               auth = token.authValue;
+                                       }
+                                       if (Arrays.equals(auth.toCharArray(), value))
+                                               return token;
+                                       // if (token.matchAuthValue(value))
+                                       // return token;
+                               }
+                       }
+                       return null;
+               } catch (NamingException e) {
+                       throw new UserDirectoryException("Cannot check attribute", e);
+               }
+       }
+
+       public static boolean remove(Attributes attributes, AuthPassword value) {
+               Attribute authPassword = attributes.get(LdapAttrs.authPassword.name());
+               return authPassword.remove(value.toAuthPassword());
+       }
+
+       @Override
+       public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+               for (Callback callback : callbacks) {
+                       if (callback instanceof NameCallback)
+                               ((NameCallback) callback).setName(toAuthPassword());
+                       else if (callback instanceof PasswordCallback)
+                               ((PasswordCallback) callback).setPassword(getAuthValue().toCharArray());
+               }
+       }
+
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/Distinguished.java b/org.argeo.util/src/org/argeo/util/naming/Distinguished.java
new file mode 100644 (file)
index 0000000..6aefc16
--- /dev/null
@@ -0,0 +1,36 @@
+package org.argeo.util.naming;
+
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+
+/**
+ * An object that can be identified with an X.500 distinguished name.
+ * 
+ * @see https://tools.ietf.org/html/rfc1779
+ */
+public interface Distinguished {
+       /** The related distinguished name. */
+       String dn();
+
+       /** The related distinguished name as an {@link LdapName}. */
+       default LdapName distinguishedName() {
+               try {
+                       return new LdapName(dn());
+               } catch (InvalidNameException e) {
+                       throw new IllegalArgumentException("Distinguished name " + dn() + " is not properly formatted.", e);
+               }
+       }
+
+       /** List all DNs of an enumeration as strings. */
+       static Set<String> enumToDns(EnumSet<? extends Distinguished> enumSet) {
+               Set<String> res = new TreeSet<>();
+               for (Enum<? extends Distinguished> enm : enumSet) {
+                       res.add(((Distinguished) enm).dn());
+               }
+               return res;
+       }
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/DnsBrowser.java b/org.argeo.util/src/org/argeo/util/naming/DnsBrowser.java
new file mode 100644 (file)
index 0000000..1a67eea
--- /dev/null
@@ -0,0 +1,179 @@
+package org.argeo.util.naming;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.naming.Binding;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+
+public class DnsBrowser implements Closeable {
+       private final DirContext initialCtx;
+
+       public DnsBrowser() throws NamingException {
+               this(null);
+       }
+
+       public DnsBrowser(String dnsServerUrls) throws NamingException {
+               Hashtable<String, Object> env = new Hashtable<>();
+               env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
+               if (dnsServerUrls != null)
+                       env.put("java.naming.provider.url", dnsServerUrls);
+               initialCtx = new InitialDirContext(env);
+       }
+
+       public Map<String, List<String>> getAllRecords(String name) throws NamingException {
+               Map<String, List<String>> res = new TreeMap<>();
+               Attributes attrs = initialCtx.getAttributes(name);
+               NamingEnumeration<String> ids = attrs.getIDs();
+               while (ids.hasMore()) {
+                       String recordType = ids.next();
+                       List<String> lst = new ArrayList<String>();
+                       res.put(recordType, lst);
+                       Attribute attr = attrs.get(recordType);
+                       addValues(attr, lst);
+               }
+               return Collections.unmodifiableMap(res);
+       }
+
+       /**
+        * Return a single record (typically A, AAAA, etc. or null if not available.
+        * Will fail if multiple records.
+        */
+       public String getRecord(String name, String recordType) throws NamingException {
+               Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType });
+               if (attrs.size() == 0)
+                       return null;
+               Attribute attr = attrs.get(recordType);
+               if (attr.size() > 1)
+                       throw new IllegalArgumentException("Multiple record type " + recordType);
+               assert attr.size() != 0;
+               Object value = attr.get();
+               assert value != null;
+               return value.toString();
+       }
+
+       /**
+        * Return records of a given type.
+        */
+       public List<String> getRecords(String name, String recordType) throws NamingException {
+               List<String> res = new ArrayList<String>();
+               Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType });
+               Attribute attr = attrs.get(recordType);
+               addValues(attr, res);
+               return res;
+       }
+
+       /** Ordered, with preferred first. */
+       public List<String> getSrvRecordsAsHosts(String name, boolean withPort) throws NamingException {
+               List<String> raw = getRecords(name, "SRV");
+               if (raw.size() == 0)
+                       return null;
+               SortedSet<SrvRecord> res = new TreeSet<>();
+               for (int i = 0; i < raw.size(); i++) {
+                       String record = raw.get(i);
+                       String[] arr = record.split(" ");
+                       Integer priority = Integer.parseInt(arr[0]);
+                       Integer weight = Integer.parseInt(arr[1]);
+                       Integer port = Integer.parseInt(arr[2]);
+                       String hostname = arr[3];
+                       SrvRecord order = new SrvRecord(priority, weight, port, hostname);
+                       res.add(order);
+               }
+               List<String> lst = new ArrayList<>();
+               for (SrvRecord order : res) {
+                       lst.add(order.toHost(withPort));
+               }
+               return Collections.unmodifiableList(lst);
+       }
+
+       private void addValues(Attribute attr, List<String> lst) throws NamingException {
+               NamingEnumeration<?> values = attr.getAll();
+               while (values.hasMore()) {
+                       Object value = values.next();
+                       if (value != null) {
+                               if (value instanceof byte[]) {
+                                       String str = Base64.getEncoder().encodeToString((byte[]) value);
+                                       lst.add(str);
+                               } else
+                                       lst.add(value.toString());
+                       }
+               }
+
+       }
+
+       public List<String> listEntries(String name) throws NamingException {
+               List<String> res = new ArrayList<String>();
+               NamingEnumeration<Binding> ne = initialCtx.listBindings(name);
+               while (ne.hasMore()) {
+                       Binding b = ne.next();
+                       res.add(b.getName());
+               }
+               return Collections.unmodifiableList(res);
+       }
+
+       @Override
+       public void close() throws IOException {
+               destroy();
+       }
+
+       public void destroy() {
+               try {
+                       initialCtx.close();
+               } catch (NamingException e) {
+                       // silent
+               }
+       }
+
+       public static void main(String[] args) {
+               if (args.length == 0) {
+                       printUsage(System.err);
+                       System.exit(1);
+               }
+               try (DnsBrowser dnsBrowser = new DnsBrowser()) {
+                       String hostname = args[0];
+                       String recordType = args.length > 1 ? args[1] : "A";
+                       if (recordType.equals("*")) {
+                               Map<String, List<String>> records = dnsBrowser.getAllRecords(hostname);
+                               for (String type : records.keySet()) {
+                                       for (String record : records.get(type)) {
+                                               String typeLabel;
+                                               if ("44".equals(type))
+                                                       typeLabel = "SSHFP";
+                                               else if ("46".equals(type))
+                                                       typeLabel = "RRSIG";
+                                               else if ("48".equals(type))
+                                                       typeLabel = "DNSKEY";
+                                               else
+                                                       typeLabel = type;
+                                               System.out.println(typeLabel + "\t" + record);
+                                       }
+                               }
+                       } else {
+                               System.out.println(dnsBrowser.getRecord(hostname, recordType));
+                       }
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public static void printUsage(PrintStream out) {
+               out.println("java org.argeo.naming.DnsBrowser <hostname> [<record type> | *]");
+       }
+
+}
\ No newline at end of file
diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.csv b/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.csv
new file mode 100644 (file)
index 0000000..676d727
--- /dev/null
@@ -0,0 +1,129 @@
+uid,,,0.9.2342.19200300.100.1.1,,RFC 4519
+mail,,,0.9.2342.19200300.100.1.3,,RFC 4524
+info,,,0.9.2342.19200300.100.1.4,,RFC 4524
+drink,,,0.9.2342.19200300.100.1.5,,RFC 4524
+roomNumber,,,0.9.2342.19200300.100.1.6,,RFC 4524
+photo,,,0.9.2342.19200300.100.1.7,,RFC 2798
+userClass,,,0.9.2342.19200300.100.1.8,,RFC 4524
+host,,,0.9.2342.19200300.100.1.9,,RFC 4524
+manager,,,0.9.2342.19200300.100.1.10,,RFC 4524
+documentIdentifier,,,0.9.2342.19200300.100.1.11,,RFC 4524
+documentTitle,,,0.9.2342.19200300.100.1.12,,RFC 4524
+documentVersion,,,0.9.2342.19200300.100.1.13,,RFC 4524
+documentAuthor,,,0.9.2342.19200300.100.1.14,,RFC 4524
+documentLocation,,,0.9.2342.19200300.100.1.15,,RFC 4524
+homePhone,,,0.9.2342.19200300.100.1.20,,RFC 4524
+secretary,,,0.9.2342.19200300.100.1.21,,RFC 4524
+dc,,,0.9.2342.19200300.100.1.25,,RFC 4519
+associatedDomain,,,0.9.2342.19200300.100.1.37,,RFC 4524
+associatedName,,,0.9.2342.19200300.100.1.38,,RFC 4524
+homePostalAddress,,,0.9.2342.19200300.100.1.39,,RFC 4524
+personalTitle,,,0.9.2342.19200300.100.1.40,,RFC 4524
+mobile,,,0.9.2342.19200300.100.1.41,,RFC 4524
+pager,,,0.9.2342.19200300.100.1.42,,RFC 4524
+co,,,0.9.2342.19200300.100.1.43,,RFC 4524
+uniqueIdentifier,,,0.9.2342.19200300.100.1.44,,RFC 4524
+organizationalStatus,,,0.9.2342.19200300.100.1.45,,RFC 4524
+buildingName,,,0.9.2342.19200300.100.1.48,,RFC 4524
+audio,,,0.9.2342.19200300.100.1.55,,RFC 2798
+documentPublisher,,,0.9.2342.19200300.100.1.56,,RFC 4524
+jpegPhoto,,,0.9.2342.19200300.100.1.60,,RFC 2798
+vendorName,,,1.3.6.1.1.4,,RFC 3045
+vendorVersion,,,1.3.6.1.1.5,,RFC 3045
+entryUUID,,,1.3.6.1.1.16.4,,RFC 4530
+entryDN,,,1.3.6.1.1.20,,RFC 5020
+labeledURI,,,1.3.6.1.4.1.250.1.57,,RFC 2798
+numSubordinates,,,1.3.6.1.4.1.453.16.2.103,,draft-ietf-boreham-numsubordinates
+namingContexts,,,1.3.6.1.4.1.1466.101.120.5,,RFC 4512
+altServer,,,1.3.6.1.4.1.1466.101.120.6,,RFC 4512
+supportedExtension,,,1.3.6.1.4.1.1466.101.120.7,,RFC 4512
+supportedControl,,,1.3.6.1.4.1.1466.101.120.13,,RFC 4512
+supportedSASLMechanisms,,,1.3.6.1.4.1.1466.101.120.14,,RFC 4512
+supportedLDAPVersion,,,1.3.6.1.4.1.1466.101.120.15,,RFC 4512
+ldapSyntaxes,,,1.3.6.1.4.1.1466.101.120.16,,RFC 4512
+supportedAuthPasswordSchemes,,,1.3.6.1.4.1.4203.1.3.3,,RFC 3112
+authPassword,,,1.3.6.1.4.1.4203.1.3.4,,RFC 3112
+supportedFeatures,,,1.3.6.1.4.1.4203.1.3.5,,RFC 4512
+inheritable,,,1.3.6.1.4.1.7628.5.4.1,,draft-ietf-ldup-subentry
+blockInheritance,,,1.3.6.1.4.1.7628.5.4.2,,draft-ietf-ldup-subentry
+objectClass,,,2.5.4.0,,RFC 4512
+aliasedObjectName,,,2.5.4.1,,RFC 4512
+cn,,,2.5.4.3,,RFC 4519
+sn,,,2.5.4.4,,RFC 4519
+serialNumber,,,2.5.4.5,,RFC 4519
+c,,,2.5.4.6,,RFC 4519
+l,,,2.5.4.7,,RFC 4519
+st,,,2.5.4.8,,RFC 4519
+street,,,2.5.4.9,,RFC 4519
+o,,,2.5.4.10,,RFC 4519
+ou,,,2.5.4.11,,RFC 4519
+title,,,2.5.4.12,,RFC 4519
+description,,,2.5.4.13,,RFC 4519
+searchGuide,,,2.5.4.14,,RFC 4519
+businessCategory,,,2.5.4.15,,RFC 4519
+postalAddress,,,2.5.4.16,,RFC 4519
+postalCode,,,2.5.4.17,,RFC 4519
+postOfficeBox,,,2.5.4.18,,RFC 4519
+physicalDeliveryOfficeName,,,2.5.4.19,,RFC 4519
+telephoneNumber,,,2.5.4.20,,RFC 4519
+telexNumber,,,2.5.4.21,,RFC 4519
+teletexTerminalIdentifier,,,2.5.4.22,,RFC 4519
+facsimileTelephoneNumber,,,2.5.4.23,,RFC 4519
+x121Address,,,2.5.4.24,,RFC 4519
+internationalISDNNumber,,,2.5.4.25,,RFC 4519
+registeredAddress,,,2.5.4.26,,RFC 4519
+destinationIndicator,,,2.5.4.27,,RFC 4519
+preferredDeliveryMethod,,,2.5.4.28,,RFC 4519
+member,,,2.5.4.31,,RFC 4519
+owner,,,2.5.4.32,,RFC 4519
+roleOccupant,,,2.5.4.33,,RFC 4519
+seeAlso,,,2.5.4.34,,RFC 4519
+userPassword,,,2.5.4.35,,RFC 4519
+userCertificate,,,2.5.4.36,,RFC 4523
+cACertificate,,,2.5.4.37,,RFC 4523
+authorityRevocationList,,,2.5.4.38,,RFC 4523
+certificateRevocationList,,,2.5.4.39,,RFC 4523
+crossCertificatePair,,,2.5.4.40,,RFC 4523
+name,,,2.5.4.41,,RFC 4519
+givenName,,,2.5.4.42,,RFC 4519
+initials,,,2.5.4.43,,RFC 4519
+generationQualifier,,,2.5.4.44,,RFC 4519
+x500UniqueIdentifier,,,2.5.4.45,,RFC 4519
+dnQualifier,,,2.5.4.46,,RFC 4519
+enhancedSearchGuide,,,2.5.4.47,,RFC 4519
+distinguishedName,,,2.5.4.49,,RFC 4519
+uniqueMember,,,2.5.4.50,,RFC 4519
+houseIdentifier,,,2.5.4.51,,RFC 4519
+supportedAlgorithms,,,2.5.4.52,,RFC 4523
+deltaRevocationList,,,2.5.4.53,,RFC 4523
+createTimestamp,,,2.5.18.1,,RFC 4512
+modifyTimestamp,,,2.5.18.2,,RFC 4512
+creatorsName,,,2.5.18.3,,RFC 4512
+modifiersName,,,2.5.18.4,,RFC 4512
+subschemaSubentry,,,2.5.18.10,,RFC 4512
+dITStructureRules,,,2.5.21.1,,RFC 4512
+dITContentRules,,,2.5.21.2,,RFC 4512
+matchingRules,,,2.5.21.4,,RFC 4512
+attributeTypes,,,2.5.21.5,,RFC 4512
+objectClasses,,,2.5.21.6,,RFC 4512
+nameForms,,,2.5.21.7,,RFC 4512
+matchingRuleUse,,,2.5.21.8,,RFC 4512
+structuralObjectClass,,,2.5.21.9,,RFC 4512
+governingStructureRule,,,2.5.21.10,,RFC 4512
+carLicense,,,2.16.840.1.113730.3.1.1,,RFC 2798
+departmentNumber,,,2.16.840.1.113730.3.1.2,,RFC 2798
+employeeNumber,,,2.16.840.1.113730.3.1.3,,RFC 2798
+employeeType,,,2.16.840.1.113730.3.1.4,,RFC 2798
+changeNumber,,,2.16.840.1.113730.3.1.5,,draft-good-ldap-changelog
+targetDN,,,2.16.840.1.113730.3.1.6,,draft-good-ldap-changelog
+changeType,,,2.16.840.1.113730.3.1.7,,draft-good-ldap-changelog
+changes,,,2.16.840.1.113730.3.1.8,,draft-good-ldap-changelog
+newRDN,,,2.16.840.1.113730.3.1.9,,draft-good-ldap-changelog
+deleteOldRDN,,,2.16.840.1.113730.3.1.10,,draft-good-ldap-changelog
+newSuperior,,,2.16.840.1.113730.3.1.11,,draft-good-ldap-changelog
+ref,,,2.16.840.1.113730.3.1.34,,RFC 3296
+changelog,,,2.16.840.1.113730.3.1.35,,draft-good-ldap-changelog
+preferredLanguage,,,2.16.840.1.113730.3.1.39,,RFC 2798
+userSMIMECertificate,,,2.16.840.1.113730.3.1.40,,RFC 2798
+userPKCS12,,,2.16.840.1.113730.3.1.216,,RFC 2798
+displayName,,,2.16.840.1.113730.3.1.241,,RFC 2798
diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.java b/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.java
new file mode 100644 (file)
index 0000000..7dcba09
--- /dev/null
@@ -0,0 +1,341 @@
+package org.argeo.util.naming;
+
+/**
+ * Standard LDAP attributes as per:<br>
+ * - <a href= "https://www.ldap.com/ldap-oid-reference">Standard LDAP</a><br>
+ * - <a href=
+ * "https://github.com/krb5/krb5/blob/master/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema">Kerberos
+ * LDAP (partial)</a>
+ */
+public enum LdapAttrs implements SpecifiedName {
+       /** */
+       uid("0.9.2342.19200300.100.1.1", "RFC 4519"),
+       /** */
+       mail("0.9.2342.19200300.100.1.3", "RFC 4524"),
+       /** */
+       info("0.9.2342.19200300.100.1.4", "RFC 4524"),
+       /** */
+       drink("0.9.2342.19200300.100.1.5", "RFC 4524"),
+       /** */
+       roomNumber("0.9.2342.19200300.100.1.6", "RFC 4524"),
+       /** */
+       photo("0.9.2342.19200300.100.1.7", "RFC 2798"),
+       /** */
+       userClass("0.9.2342.19200300.100.1.8", "RFC 4524"),
+       /** */
+       host("0.9.2342.19200300.100.1.9", "RFC 4524"),
+       /** */
+       manager("0.9.2342.19200300.100.1.10", "RFC 4524"),
+       /** */
+       documentIdentifier("0.9.2342.19200300.100.1.11", "RFC 4524"),
+       /** */
+       documentTitle("0.9.2342.19200300.100.1.12", "RFC 4524"),
+       /** */
+       documentVersion("0.9.2342.19200300.100.1.13", "RFC 4524"),
+       /** */
+       documentAuthor("0.9.2342.19200300.100.1.14", "RFC 4524"),
+       /** */
+       documentLocation("0.9.2342.19200300.100.1.15", "RFC 4524"),
+       /** */
+       homePhone("0.9.2342.19200300.100.1.20", "RFC 4524"),
+       /** */
+       secretary("0.9.2342.19200300.100.1.21", "RFC 4524"),
+       /** */
+       dc("0.9.2342.19200300.100.1.25", "RFC 4519"),
+       /** */
+       associatedDomain("0.9.2342.19200300.100.1.37", "RFC 4524"),
+       /** */
+       associatedName("0.9.2342.19200300.100.1.38", "RFC 4524"),
+       /** */
+       homePostalAddress("0.9.2342.19200300.100.1.39", "RFC 4524"),
+       /** */
+       personalTitle("0.9.2342.19200300.100.1.40", "RFC 4524"),
+       /** */
+       mobile("0.9.2342.19200300.100.1.41", "RFC 4524"),
+       /** */
+       pager("0.9.2342.19200300.100.1.42", "RFC 4524"),
+       /** */
+       co("0.9.2342.19200300.100.1.43", "RFC 4524"),
+       /** */
+       uniqueIdentifier("0.9.2342.19200300.100.1.44", "RFC 4524"),
+       /** */
+       organizationalStatus("0.9.2342.19200300.100.1.45", "RFC 4524"),
+       /** */
+       buildingName("0.9.2342.19200300.100.1.48", "RFC 4524"),
+       /** */
+       audio("0.9.2342.19200300.100.1.55", "RFC 2798"),
+       /** */
+       documentPublisher("0.9.2342.19200300.100.1.56", "RFC 4524"),
+       /** */
+       jpegPhoto("0.9.2342.19200300.100.1.60", "RFC 2798"),
+       /** */
+       vendorName("1.3.6.1.1.4", "RFC 3045"),
+       /** */
+       vendorVersion("1.3.6.1.1.5", "RFC 3045"),
+       /** */
+       entryUUID("1.3.6.1.1.16.4", "RFC 4530"),
+       /** */
+       entryDN("1.3.6.1.1.20", "RFC 5020"),
+       /** */
+       labeledURI("1.3.6.1.4.1.250.1.57", "RFC 2798"),
+       /** */
+       numSubordinates("1.3.6.1.4.1.453.16.2.103", "draft-ietf-boreham-numsubordinates"),
+       /** */
+       namingContexts("1.3.6.1.4.1.1466.101.120.5", "RFC 4512"),
+       /** */
+       altServer("1.3.6.1.4.1.1466.101.120.6", "RFC 4512"),
+       /** */
+       supportedExtension("1.3.6.1.4.1.1466.101.120.7", "RFC 4512"),
+       /** */
+       supportedControl("1.3.6.1.4.1.1466.101.120.13", "RFC 4512"),
+       /** */
+       supportedSASLMechanisms("1.3.6.1.4.1.1466.101.120.14", "RFC 4512"),
+       /** */
+       supportedLDAPVersion("1.3.6.1.4.1.1466.101.120.15", "RFC 4512"),
+       /** */
+       ldapSyntaxes("1.3.6.1.4.1.1466.101.120.16", "RFC 4512"),
+       /** */
+       supportedAuthPasswordSchemes("1.3.6.1.4.1.4203.1.3.3", "RFC 3112"),
+       /** */
+       authPassword("1.3.6.1.4.1.4203.1.3.4", "RFC 3112"),
+       /** */
+       supportedFeatures("1.3.6.1.4.1.4203.1.3.5", "RFC 4512"),
+       /** */
+       inheritable("1.3.6.1.4.1.7628.5.4.1", "draft-ietf-ldup-subentry"),
+       /** */
+       blockInheritance("1.3.6.1.4.1.7628.5.4.2", "draft-ietf-ldup-subentry"),
+       /** */
+       objectClass("2.5.4.0", "RFC 4512"),
+       /** */
+       aliasedObjectName("2.5.4.1", "RFC 4512"),
+       /** */
+       cn("2.5.4.3", "RFC 4519"),
+       /** */
+       sn("2.5.4.4", "RFC 4519"),
+       /** */
+       serialNumber("2.5.4.5", "RFC 4519"),
+       /** */
+       c("2.5.4.6", "RFC 4519"),
+       /** */
+       l("2.5.4.7", "RFC 4519"),
+       /** */
+       st("2.5.4.8", "RFC 4519"),
+       /** */
+       street("2.5.4.9", "RFC 4519"),
+       /** */
+       o("2.5.4.10", "RFC 4519"),
+       /** */
+       ou("2.5.4.11", "RFC 4519"),
+       /** */
+       title("2.5.4.12", "RFC 4519"),
+       /** */
+       description("2.5.4.13", "RFC 4519"),
+       /** */
+       searchGuide("2.5.4.14", "RFC 4519"),
+       /** */
+       businessCategory("2.5.4.15", "RFC 4519"),
+       /** */
+       postalAddress("2.5.4.16", "RFC 4519"),
+       /** */
+       postalCode("2.5.4.17", "RFC 4519"),
+       /** */
+       postOfficeBox("2.5.4.18", "RFC 4519"),
+       /** */
+       physicalDeliveryOfficeName("2.5.4.19", "RFC 4519"),
+       /** */
+       telephoneNumber("2.5.4.20", "RFC 4519"),
+       /** */
+       telexNumber("2.5.4.21", "RFC 4519"),
+       /** */
+       teletexTerminalIdentifier("2.5.4.22", "RFC 4519"),
+       /** */
+       facsimileTelephoneNumber("2.5.4.23", "RFC 4519"),
+       /** */
+       x121Address("2.5.4.24", "RFC 4519"),
+       /** */
+       internationalISDNNumber("2.5.4.25", "RFC 4519"),
+       /** */
+       registeredAddress("2.5.4.26", "RFC 4519"),
+       /** */
+       destinationIndicator("2.5.4.27", "RFC 4519"),
+       /** */
+       preferredDeliveryMethod("2.5.4.28", "RFC 4519"),
+       /** */
+       member("2.5.4.31", "RFC 4519"),
+       /** */
+       owner("2.5.4.32", "RFC 4519"),
+       /** */
+       roleOccupant("2.5.4.33", "RFC 4519"),
+       /** */
+       seeAlso("2.5.4.34", "RFC 4519"),
+       /** */
+       userPassword("2.5.4.35", "RFC 4519"),
+       /** */
+       userCertificate("2.5.4.36", "RFC 4523"),
+       /** */
+       cACertificate("2.5.4.37", "RFC 4523"),
+       /** */
+       authorityRevocationList("2.5.4.38", "RFC 4523"),
+       /** */
+       certificateRevocationList("2.5.4.39", "RFC 4523"),
+       /** */
+       crossCertificatePair("2.5.4.40", "RFC 4523"),
+       /** */
+       name("2.5.4.41", "RFC 4519"),
+       /** */
+       givenName("2.5.4.42", "RFC 4519"),
+       /** */
+       initials("2.5.4.43", "RFC 4519"),
+       /** */
+       generationQualifier("2.5.4.44", "RFC 4519"),
+       /** */
+       x500UniqueIdentifier("2.5.4.45", "RFC 4519"),
+       /** */
+       dnQualifier("2.5.4.46", "RFC 4519"),
+       /** */
+       enhancedSearchGuide("2.5.4.47", "RFC 4519"),
+       /** */
+       distinguishedName("2.5.4.49", "RFC 4519"),
+       /** */
+       uniqueMember("2.5.4.50", "RFC 4519"),
+       /** */
+       houseIdentifier("2.5.4.51", "RFC 4519"),
+       /** */
+       supportedAlgorithms("2.5.4.52", "RFC 4523"),
+       /** */
+       deltaRevocationList("2.5.4.53", "RFC 4523"),
+       /** */
+       createTimestamp("2.5.18.1", "RFC 4512"),
+       /** */
+       modifyTimestamp("2.5.18.2", "RFC 4512"),
+       /** */
+       creatorsName("2.5.18.3", "RFC 4512"),
+       /** */
+       modifiersName("2.5.18.4", "RFC 4512"),
+       /** */
+       subschemaSubentry("2.5.18.10", "RFC 4512"),
+       /** */
+       dITStructureRules("2.5.21.1", "RFC 4512"),
+       /** */
+       dITContentRules("2.5.21.2", "RFC 4512"),
+       /** */
+       matchingRules("2.5.21.4", "RFC 4512"),
+       /** */
+       attributeTypes("2.5.21.5", "RFC 4512"),
+       /** */
+       objectClasses("2.5.21.6", "RFC 4512"),
+       /** */
+       nameForms("2.5.21.7", "RFC 4512"),
+       /** */
+       matchingRuleUse("2.5.21.8", "RFC 4512"),
+       /** */
+       structuralObjectClass("2.5.21.9", "RFC 4512"),
+       /** */
+       governingStructureRule("2.5.21.10", "RFC 4512"),
+       /** */
+       carLicense("2.16.840.1.113730.3.1.1", "RFC 2798"),
+       /** */
+       departmentNumber("2.16.840.1.113730.3.1.2", "RFC 2798"),
+       /** */
+       employeeNumber("2.16.840.1.113730.3.1.3", "RFC 2798"),
+       /** */
+       employeeType("2.16.840.1.113730.3.1.4", "RFC 2798"),
+       /** */
+       changeNumber("2.16.840.1.113730.3.1.5", "draft-good-ldap-changelog"),
+       /** */
+       targetDN("2.16.840.1.113730.3.1.6", "draft-good-ldap-changelog"),
+       /** */
+       changeType("2.16.840.1.113730.3.1.7", "draft-good-ldap-changelog"),
+       /** */
+       changes("2.16.840.1.113730.3.1.8", "draft-good-ldap-changelog"),
+       /** */
+       newRDN("2.16.840.1.113730.3.1.9", "draft-good-ldap-changelog"),
+       /** */
+       deleteOldRDN("2.16.840.1.113730.3.1.10", "draft-good-ldap-changelog"),
+       /** */
+       newSuperior("2.16.840.1.113730.3.1.11", "draft-good-ldap-changelog"),
+       /** */
+       ref("2.16.840.1.113730.3.1.34", "RFC 3296"),
+       /** */
+       changelog("2.16.840.1.113730.3.1.35", "draft-good-ldap-changelog"),
+       /** */
+       preferredLanguage("2.16.840.1.113730.3.1.39", "RFC 2798"),
+       /** */
+       userSMIMECertificate("2.16.840.1.113730.3.1.40", "RFC 2798"),
+       /** */
+       userPKCS12("2.16.840.1.113730.3.1.216", "RFC 2798"),
+       /** */
+       displayName("2.16.840.1.113730.3.1.241", "RFC 2798"),
+
+       // Sun memberOf
+       memberOf("1.2.840.113556.1.2.102", "389 DS memberOf"),
+
+       // KERBEROS (partial)
+       krbPrincipalName("2.16.840.1.113719.1.301.6.8.1", "Novell Kerberos Schema Definitions"),
+
+       // RFC 2985 and RFC 3039 (partial)
+       dateOfBirth("1.3.6.1.5.5.7.9.1", "RFC 2985"),
+       /** */
+       placeOfBirth("1.3.6.1.5.5.7.9.2", "RFC 2985"),
+       /** */
+       gender("1.3.6.1.5.5.7.9.3", "RFC 2985"),
+       /** */
+       countryOfCitizenship("1.3.6.1.5.5.7.9.4", "RFC 2985"),
+       /** */
+       countryOfResidence("1.3.6.1.5.5.7.9.5", "RFC 2985"),
+       //
+       ;
+
+       public final static String DN = "dn";
+
+//     private final static String LDAP_ = "ldap:";
+
+       private final String oid, spec;
+
+       LdapAttrs(String oid, String spec) {
+               this.oid = oid;
+               this.spec = spec;
+       }
+
+       @Override
+       public String getID() {
+               return oid;
+       }
+
+       @Override
+       public String getSpec() {
+               return spec;
+       }
+
+       public String getPrefix() {
+               return prefix();
+       }
+
+       public static String prefix() {
+               return "ldap";
+       }
+
+       public String property() {
+               return qualified();
+       }
+
+       public String qualified() {
+               String prefix = getPrefix();
+               return prefix != null ? prefix + ":" + name() : name();
+       }
+
+       public String getNamespace() {
+               return namespace();
+       }
+
+       public static String namespace() {
+               return "http://www.argeo.org/ns/ldap";
+       }
+
+       @Override
+       public final String toString() {
+               // must return the name
+               return name();
+       }
+
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapObjs.csv b/org.argeo.util/src/org/argeo/util/naming/LdapObjs.csv
new file mode 100644 (file)
index 0000000..3d907cb
--- /dev/null
@@ -0,0 +1,42 @@
+account,,,0.9.2342.19200300.100.4.5,,RFC 4524
+document,,,0.9.2342.19200300.100.4.6,,RFC 4524
+room,,,0.9.2342.19200300.100.4.7,,RFC 4524
+documentSeries,,,0.9.2342.19200300.100.4.9,,RFC 4524
+domain,,,0.9.2342.19200300.100.4.13,,RFC 4524
+rFC822localPart,,,0.9.2342.19200300.100.4.14,,RFC 4524
+domainRelatedObject,,,0.9.2342.19200300.100.4.17,,RFC 4524
+friendlyCountry,,,0.9.2342.19200300.100.4.18,,RFC 4524
+simpleSecurityObject,,,0.9.2342.19200300.100.4.19,,RFC 4524
+uidObject,,,1.3.6.1.1.3.1,,RFC 4519
+extensibleObject,,,1.3.6.1.4.1.1466.101.120.111,,RFC 4512
+dcObject,,,1.3.6.1.4.1.1466.344,,RFC 4519
+authPasswordObject,,,1.3.6.1.4.1.4203.1.4.7,,RFC 3112
+namedObject,,,1.3.6.1.4.1.5322.13.1.1,,draft-howard-namedobject
+inheritableLDAPSubEntry,,,1.3.6.1.4.1.7628.5.6.1.1,,draft-ietf-ldup-subentry
+top,,,2.5.6.0,,RFC 4512
+alias,,,2.5.6.1,,RFC 4512
+country,,,2.5.6.2,,RFC 4519
+locality,,,2.5.6.3,,RFC 4519
+organization,,,2.5.6.4,,RFC 4519
+organizationalUnit,,,2.5.6.5,,RFC 4519
+person,,,2.5.6.6,,RFC 4519
+organizationalPerson,,,2.5.6.7,,RFC 4519
+organizationalRole,,,2.5.6.8,,RFC 4519
+groupOfNames,,,2.5.6.9,,RFC 4519
+residentialPerson,,,2.5.6.10,,RFC 4519
+applicationProcess,,,2.5.6.11,,RFC 4519
+device,,,2.5.6.14,,RFC 4519
+strongAuthenticationUser,,,2.5.6.15,,RFC 4523
+certificationAuthority,,,2.5.6.16,,RFC 4523
+certificationAuthority-V2,,,2.5.6.16.2,,RFC 4523
+groupOfUniqueNames,,,2.5.6.17,,RFC 4519
+userSecurityInformation,,,2.5.6.18,,RFC 4523
+cRLDistributionPoint,,,2.5.6.19,,RFC 4523
+pkiUser,,,2.5.6.21,,RFC 4523
+pkiCA,,,2.5.6.22,,RFC 4523
+deltaCRL,,,2.5.6.23,,RFC 4523
+subschema,,,2.5.20.1,,RFC 4512
+ldapSubEntry,,,2.16.840.1.113719.2.142.6.1.1,,draft-ietf-ldup-subentry
+changeLogEntry,,,2.16.840.1.113730.3.2.1,,draft-good-ldap-changelog
+inetOrgPerson,,,2.16.840.1.113730.3.2.2,,RFC 2798
+referral,,,2.16.840.1.113730.3.2.6,,RFC 3296
diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapObjs.java b/org.argeo.util/src/org/argeo/util/naming/LdapObjs.java
new file mode 100644 (file)
index 0000000..c616d14
--- /dev/null
@@ -0,0 +1,114 @@
+package org.argeo.util.naming;
+
+/**
+ * Standard LDAP object classes as per
+ * <a href="https://www.ldap.com/ldap-oid-reference">https://www.ldap.com/ldap-
+ * oid-reference</a>
+ */
+public enum LdapObjs implements SpecifiedName {
+       account("0.9.2342.19200300.100.4.5", "RFC 4524"),
+       /** */
+       document("0.9.2342.19200300.100.4.6", "RFC 4524"),
+       /** */
+       room("0.9.2342.19200300.100.4.7", "RFC 4524"),
+       /** */
+       documentSeries("0.9.2342.19200300.100.4.9", "RFC 4524"),
+       /** */
+       domain("0.9.2342.19200300.100.4.13", "RFC 4524"),
+       /** */
+       rFC822localPart("0.9.2342.19200300.100.4.14", "RFC 4524"),
+       /** */
+       domainRelatedObject("0.9.2342.19200300.100.4.17", "RFC 4524"),
+       /** */
+       friendlyCountry("0.9.2342.19200300.100.4.18", "RFC 4524"),
+       /** */
+       simpleSecurityObject("0.9.2342.19200300.100.4.19", "RFC 4524"),
+       /** */
+       uidObject("1.3.6.1.1.3.1", "RFC 4519"),
+       /** */
+       extensibleObject("1.3.6.1.4.1.1466.101.120.111", "RFC 4512"),
+       /** */
+       dcObject("1.3.6.1.4.1.1466.344", "RFC 4519"),
+       /** */
+       authPasswordObject("1.3.6.1.4.1.4203.1.4.7", "RFC 3112"),
+       /** */
+       namedObject("1.3.6.1.4.1.5322.13.1.1", "draft-howard-namedobject"),
+       /** */
+       inheritableLDAPSubEntry("1.3.6.1.4.1.7628.5.6.1.1", "draft-ietf-ldup-subentry"),
+       /** */
+       top("2.5.6.0", "RFC 4512"),
+       /** */
+       alias("2.5.6.1", "RFC 4512"),
+       /** */
+       country("2.5.6.2", "RFC 4519"),
+       /** */
+       locality("2.5.6.3", "RFC 4519"),
+       /** */
+       organization("2.5.6.4", "RFC 4519"),
+       /** */
+       organizationalUnit("2.5.6.5", "RFC 4519"),
+       /** */
+       person("2.5.6.6", "RFC 4519"),
+       /** */
+       organizationalPerson("2.5.6.7", "RFC 4519"),
+       /** */
+       organizationalRole("2.5.6.8", "RFC 4519"),
+       /** */
+       groupOfNames("2.5.6.9", "RFC 4519"),
+       /** */
+       residentialPerson("2.5.6.10", "RFC 4519"),
+       /** */
+       applicationProcess("2.5.6.11", "RFC 4519"),
+       /** */
+       device("2.5.6.14", "RFC 4519"),
+       /** */
+       strongAuthenticationUser("2.5.6.15", "RFC 4523"),
+       /** */
+       certificationAuthority("2.5.6.16", "RFC 4523"),
+       // /** Should be certificationAuthority-V2 */
+       // certificationAuthority_V2("2.5.6.16.2", "RFC 4523") {
+       // },
+       /** */
+       groupOfUniqueNames("2.5.6.17", "RFC 4519"),
+       /** */
+       userSecurityInformation("2.5.6.18", "RFC 4523"),
+       /** */
+       cRLDistributionPoint("2.5.6.19", "RFC 4523"),
+       /** */
+       pkiUser("2.5.6.21", "RFC 4523"),
+       /** */
+       pkiCA("2.5.6.22", "RFC 4523"),
+       /** */
+       deltaCRL("2.5.6.23", "RFC 4523"),
+       /** */
+       subschema("2.5.20.1", "RFC 4512"),
+       /** */
+       ldapSubEntry("2.16.840.1.113719.2.142.6.1.1", "draft-ietf-ldup-subentry"),
+       /** */
+       changeLogEntry("2.16.840.1.113730.3.2.1", "draft-good-ldap-changelog"),
+       /** */
+       inetOrgPerson("2.16.840.1.113730.3.2.2", "RFC 2798"),
+       /** */
+       referral("2.16.840.1.113730.3.2.6", "RFC 3296");
+
+       private final static String LDAP_ = "ldap:";
+       private final String oid, spec;
+
+       private LdapObjs(String oid, String spec) {
+               this.oid = oid;
+               this.spec = spec;
+       }
+
+       public String getOid() {
+               return oid;
+       }
+
+       public String getSpec() {
+               return spec;
+       }
+
+       public String property() {
+               return new StringBuilder(LDAP_).append(name()).toString();
+       }
+
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/LdifParser.java b/org.argeo.util/src/org/argeo/util/naming/LdifParser.java
new file mode 100644 (file)
index 0000000..d68173a
--- /dev/null
@@ -0,0 +1,161 @@
+package org.argeo.util.naming;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+
+import org.argeo.osgi.useradmin.UserDirectoryException;
+
+/** Basic LDIF parser. */
+public class LdifParser {
+       private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+
+       protected Attributes addAttributes(SortedMap<LdapName, Attributes> res, int lineNumber, LdapName currentDn,
+                       Attributes currentAttributes) {
+               try {
+                       Rdn nameRdn = currentDn.getRdn(currentDn.size() - 1);
+                       Attribute nameAttr = currentAttributes.get(nameRdn.getType());
+                       if (nameAttr == null)
+                               currentAttributes.put(nameRdn.getType(), nameRdn.getValue());
+                       else if (!nameAttr.get().equals(nameRdn.getValue()))
+                               throw new UserDirectoryException(
+                                               "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn
+                                                               + " (shortly before line " + lineNumber + " in LDIF file)");
+                       Attributes previous = res.put(currentDn, currentAttributes);
+                       return previous;
+               } catch (NamingException e) {
+                       throw new UserDirectoryException("Cannot add " + currentDn, e);
+               }
+       }
+
+       /** With UTF-8 charset */
+       public SortedMap<LdapName, Attributes> read(InputStream in) throws IOException {
+               try (Reader reader = new InputStreamReader(in, DEFAULT_CHARSET)) {
+                       return read(reader);
+               } finally {
+                       try {
+                               in.close();
+                       } catch (IOException e) {
+                               // silent
+                       }
+               }
+       }
+
+       /** Will close the reader. */
+       public SortedMap<LdapName, Attributes> read(Reader reader) throws IOException {
+               SortedMap<LdapName, Attributes> res = new TreeMap<LdapName, Attributes>();
+               try {
+                       List<String> lines = new ArrayList<>();
+                       try (BufferedReader br = new BufferedReader(reader)) {
+                               String line;
+                               while ((line = br.readLine()) != null) {
+                                       lines.add(line);
+                               }
+                       }
+                       if (lines.size() == 0)
+                               return res;
+                       // add an empty new line since the last line is not checked
+                       if (!lines.get(lines.size() - 1).equals(""))
+                               lines.add("");
+
+                       LdapName currentDn = null;
+                       Attributes currentAttributes = null;
+                       StringBuilder currentEntry = new StringBuilder();
+
+                       readLines: for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
+                               String line = lines.get(lineNumber);
+                               boolean isLastLine = false;
+                               if (lineNumber == lines.size() - 1)
+                                       isLastLine = true;
+                               if (line.startsWith(" ")) {
+                                       currentEntry.append(line.substring(1));
+                                       if (!isLastLine)
+                                               continue readLines;
+                               }
+
+                               if (currentEntry.length() != 0 || isLastLine) {
+                                       // read previous attribute
+                                       StringBuilder attrId = new StringBuilder(8);
+                                       boolean isBase64 = false;
+                                       readAttrId: for (int i = 0; i < currentEntry.length(); i++) {
+                                               char c = currentEntry.charAt(i);
+                                               if (c == ':') {
+                                                       if (i + 1 < currentEntry.length() && currentEntry.charAt(i + 1) == ':')
+                                                               isBase64 = true;
+                                                       currentEntry.delete(0, i + (isBase64 ? 2 : 1));
+                                                       break readAttrId;
+                                               } else {
+                                                       attrId.append(c);
+                                               }
+                                       }
+
+                                       String attributeId = attrId.toString();
+                                       // TODO should we really trim the end of the string as well?
+                                       String cleanValueStr = currentEntry.toString().trim();
+                                       Object attributeValue = isBase64 ? Base64.getDecoder().decode(cleanValueStr) : cleanValueStr;
+
+                                       // manage DN attributes
+                                       if (attributeId.equals(LdapAttrs.DN) || isLastLine) {
+                                               if (currentDn != null) {
+                                                       //
+                                                       // ADD
+                                                       //
+                                                       Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes);
+                                                       if (previous != null) {
+//                                                             log.warn("There was already an entry with DN " + currentDn
+//                                                                             + ", which has been discarded by a subsequent one.");
+                                                       }
+                                               }
+
+                                               if (attributeId.equals(LdapAttrs.DN))
+                                                       try {
+                                                               currentDn = new LdapName(attributeValue.toString());
+                                                               currentAttributes = new BasicAttributes(true);
+                                                       } catch (InvalidNameException e) {
+//                                                             log.error(attributeValue + " not a valid DN, skipping the entry.");
+                                                               currentDn = null;
+                                                               currentAttributes = null;
+                                                       }
+                                       }
+
+                                       // store attribute
+                                       if (currentAttributes != null) {
+                                               Attribute attribute = currentAttributes.get(attributeId);
+                                               if (attribute == null) {
+                                                       attribute = new BasicAttribute(attributeId);
+                                                       currentAttributes.put(attribute);
+                                               }
+                                               attribute.add(attributeValue);
+                                       }
+                                       currentEntry = new StringBuilder();
+                               }
+                               currentEntry.append(line);
+                       }
+               } finally {
+                       try {
+                               reader.close();
+                       } catch (IOException e) {
+                               // silent
+                       }
+               }
+               return res;
+       }
+}
\ No newline at end of file
diff --git a/org.argeo.util/src/org/argeo/util/naming/LdifWriter.java b/org.argeo.util/src/org/argeo/util/naming/LdifWriter.java
new file mode 100644 (file)
index 0000000..457380b
--- /dev/null
@@ -0,0 +1,106 @@
+package org.argeo.util.naming;
+
+import static org.argeo.util.naming.LdapAttrs.DN;
+import static org.argeo.util.naming.LdapAttrs.member;
+import static org.argeo.util.naming.LdapAttrs.objectClass;
+import static org.argeo.util.naming.LdapAttrs.uniqueMember;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+
+import org.argeo.osgi.useradmin.UserDirectoryException;
+
+/** Basic LDIF writer */
+public class LdifWriter {
+       private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+       private final Writer writer;
+
+       /** Writer must be closed by caller */
+       public LdifWriter(Writer writer) {
+               this.writer = writer;
+       }
+
+       /** Stream must be closed by caller */
+       public LdifWriter(OutputStream out) {
+               this(new OutputStreamWriter(out, DEFAULT_CHARSET));
+       }
+
+       public void writeEntry(LdapName name, Attributes attributes) throws IOException {
+               try {
+                       // check consistency
+                       Rdn nameRdn = name.getRdn(name.size() - 1);
+                       Attribute nameAttr = attributes.get(nameRdn.getType());
+                       if (!nameAttr.get().equals(nameRdn.getValue()))
+                               throw new UserDirectoryException(
+                                               "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + name);
+
+                       writer.append(DN + ": ").append(name.toString()).append('\n');
+                       Attribute objectClassAttr = attributes.get(objectClass.name());
+                       if (objectClassAttr != null)
+                               writeAttribute(objectClassAttr);
+                       attributes: for (NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMore();) {
+                               Attribute attribute = attrs.next();
+                               if (attribute.getID().equals(DN) || attribute.getID().equals(objectClass.name()))
+                                       continue attributes;// skip DN attribute
+                               if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name()))
+                                       continue attributes;// skip member and uniqueMember attributes, so that they are always written last
+                               writeAttribute(attribute);
+                       }
+                       // write member and uniqueMember attributes last
+                       for (NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMore();) {
+                               Attribute attribute = attrs.next();
+                               if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name()))
+                                       writeMemberAttribute(attribute);
+                       }
+                       writer.append('\n');
+                       writer.flush();
+               } catch (NamingException e) {
+                       throw new UserDirectoryException("Cannot write LDIF", e);
+               }
+       }
+
+       public void write(Map<LdapName, Attributes> entries) throws IOException {
+               for (LdapName dn : entries.keySet())
+                       writeEntry(dn, entries.get(dn));
+       }
+
+       protected void writeAttribute(Attribute attribute) throws NamingException, IOException {
+               for (NamingEnumeration<?> attrValues = attribute.getAll(); attrValues.hasMore();) {
+                       Object value = attrValues.next();
+                       if (value instanceof byte[]) {
+                               String encoded = Base64.getEncoder().encodeToString((byte[]) value);
+                               writer.append(attribute.getID()).append(":: ").append(encoded).append('\n');
+                       } else {
+                               writer.append(attribute.getID()).append(": ").append(value.toString()).append('\n');
+                       }
+               }
+       }
+
+       protected void writeMemberAttribute(Attribute attribute) throws NamingException, IOException {
+               // Note: duplicate entries will be swallowed
+               SortedSet<String> values = new TreeSet<>();
+               for (NamingEnumeration<?> attrValues = attribute.getAll(); attrValues.hasMore();) {
+                       String value = attrValues.next().toString();
+                       values.add(value);
+               }
+
+               for (String value : values) {
+                       writer.append(attribute.getID()).append(": ").append(value).append('\n');
+               }
+       }
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/NamingUtils.java b/org.argeo.util/src/org/argeo/util/naming/NamingUtils.java
new file mode 100644 (file)
index 0000000..ff4ed31
--- /dev/null
@@ -0,0 +1,106 @@
+package org.argeo.util.naming;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class NamingUtils {
+       /** As per https://tools.ietf.org/html/rfc4517#section-3.3.13 */
+       private final static DateTimeFormatter utcLdapDate = DateTimeFormatter.ofPattern("uuuuMMddHHmmssX")
+                       .withZone(ZoneOffset.UTC);
+
+       /** @return null if not parseable */
+       public static Instant ldapDateToInstant(String ldapDate) {
+               try {
+                       return OffsetDateTime.parse(ldapDate, utcLdapDate).toInstant();
+               } catch (DateTimeParseException e) {
+                       return null;
+               }
+       }
+
+       /** @return null if not parseable */
+       public static ZonedDateTime ldapDateToZonedDateTime(String ldapDate) {
+               try {
+                       return OffsetDateTime.parse(ldapDate, utcLdapDate).toZonedDateTime();
+               } catch (DateTimeParseException e) {
+                       return null;
+               }
+       }
+
+       public static Calendar ldapDateToCalendar(String ldapDate) {
+               OffsetDateTime instant = OffsetDateTime.parse(ldapDate, utcLdapDate);
+               GregorianCalendar calendar = new GregorianCalendar();
+               calendar.set(Calendar.DAY_OF_MONTH, instant.get(ChronoField.DAY_OF_MONTH));
+               calendar.set(Calendar.MONTH, instant.get(ChronoField.MONTH_OF_YEAR));
+               calendar.set(Calendar.YEAR, instant.get(ChronoField.YEAR));
+               return calendar;
+       }
+
+       public static String instantToLdapDate(ZonedDateTime instant) {
+               return utcLdapDate.format(instant.withZoneSameInstant(ZoneOffset.UTC));
+       }
+
+       public static String getQueryValue(Map<String, List<String>> query, String key) {
+               if (!query.containsKey(key))
+                       return null;
+               List<String> val = query.get(key);
+               if (val.size() == 1)
+                       return val.get(0);
+               else
+                       throw new IllegalArgumentException("There are " + val.size() + " value(s) for " + key);
+       }
+
+       public static Map<String, List<String>> queryToMap(URI uri) {
+               return queryToMap(uri.getQuery());
+       }
+
+       private static Map<String, List<String>> queryToMap(String queryPart) {
+               try {
+                       final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
+                       if (queryPart == null)
+                               return query_pairs;
+                       final String[] pairs = queryPart.split("&");
+                       for (String pair : pairs) {
+                               final int idx = pair.indexOf("=");
+                               final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8.name())
+                                               : pair;
+                               if (!query_pairs.containsKey(key)) {
+                                       query_pairs.put(key, new LinkedList<String>());
+                               }
+                               final String value = idx > 0 && pair.length() > idx + 1
+                                               ? URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8.name())
+                                               : null;
+                               query_pairs.get(key).add(value);
+                       }
+                       return query_pairs;
+               } catch (UnsupportedEncodingException e) {
+                       throw new IllegalArgumentException("Cannot convert " + queryPart + " to map", e);
+               }
+       }
+
+       private NamingUtils() {
+
+       }
+
+       public static void main(String args[]) {
+               ZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC);
+               String str = utcLdapDate.format(now);
+               System.out.println(str);
+               utcLdapDate.parse(str);
+               utcLdapDate.parse("19520512000000Z");
+       }
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/NodeOID.java b/org.argeo.util/src/org/argeo/util/naming/NodeOID.java
new file mode 100644 (file)
index 0000000..d72c31e
--- /dev/null
@@ -0,0 +1,11 @@
+package org.argeo.util.naming;
+
+interface NodeOID {
+       String BASE = "1.3.6.1.4.1" + ".48308" + ".1";
+
+       // ATTRIBUTE TYPES
+       String ATTRIBUTE_TYPES = BASE + ".4";
+
+       // OBJECT CLASSES
+       String OBJECT_CLASSES = BASE + ".6";
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/SharedSecret.java b/org.argeo.util/src/org/argeo/util/naming/SharedSecret.java
new file mode 100644 (file)
index 0000000..7f05754
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.util.naming;
+
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+public class SharedSecret extends AuthPassword {
+       public final static String X_SHARED_SECRET = "X-SharedSecret";
+       private final Instant expiry;
+
+       public SharedSecret(String authInfo, String authValue) {
+               super(authInfo, authValue);
+               expiry = null;
+       }
+
+       public SharedSecret(AuthPassword authPassword) {
+               super(authPassword);
+               String authInfo = getAuthInfo();
+               if (authInfo.length() == 16) {
+                       expiry = NamingUtils.ldapDateToInstant(authInfo);
+               } else {
+                       expiry = null;
+               }
+       }
+
+       public SharedSecret(ZonedDateTime expiryTimestamp, String value) {
+               super(NamingUtils.instantToLdapDate(expiryTimestamp), value);
+               expiry = expiryTimestamp.withZoneSameInstant(ZoneOffset.UTC).toInstant();
+       }
+
+       public SharedSecret(int hours, String value) {
+               this(ZonedDateTime.now().plusHours(hours), value);
+       }
+
+       @Override
+       protected String getExpectedAuthScheme() {
+               return X_SHARED_SECRET;
+       }
+
+       public boolean isExpired() {
+               if (expiry == null)
+                       return false;
+               return expiry.isBefore(Instant.now());
+       }
+
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/SpecifiedName.java b/org.argeo.util/src/org/argeo/util/naming/SpecifiedName.java
new file mode 100644 (file)
index 0000000..22f2a2d
--- /dev/null
@@ -0,0 +1,20 @@
+package org.argeo.util.naming;
+
+/**
+ * A name which has been specified and for which an id has been defined
+ * (typically an OID).
+ */
+public interface SpecifiedName {
+       /** The name */
+       String name();
+
+       /** An RFC or the URLof some specification */
+       default String getSpec() {
+               return null;
+       }
+
+       /** Typically an OID */
+       default String getID() {
+               return getClass().getName() + "." + name();
+       }
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/SrvRecord.java b/org.argeo.util/src/org/argeo/util/naming/SrvRecord.java
new file mode 100644 (file)
index 0000000..f2476a9
--- /dev/null
@@ -0,0 +1,52 @@
+package org.argeo.util.naming;
+
+class SrvRecord implements Comparable<SrvRecord> {
+       private final Integer priority;
+       private final Integer weight;
+       private final Integer port;
+       private final String hostname;
+
+       public SrvRecord(Integer priority, Integer weight, Integer port, String hostname) {
+               this.priority = priority;
+               this.weight = weight;
+               this.port = port;
+               this.hostname = hostname;
+       }
+
+       @Override
+       public int compareTo(SrvRecord other) {
+               // https: // en.wikipedia.org/wiki/SRV_record
+               if (priority != other.priority)
+                       return priority - other.priority;
+               if (weight != other.weight)
+                       return other.weight - other.weight;
+               String host = toHost(false);
+               String otherHost = other.toHost(false);
+               if (host.length() == otherHost.length())
+                       return host.compareTo(otherHost);
+               else
+                       return host.length() - otherHost.length();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof SrvRecord) {
+                       SrvRecord other = (SrvRecord) obj;
+                       return priority == other.priority && weight == other.weight && port == other.port
+                                       && hostname.equals(other.hostname);
+               }
+               return false;
+       }
+
+       @Override
+       public String toString() {
+               return priority + " " + weight;
+       }
+
+       public String toHost(boolean withPort) {
+               String hostStr = hostname;
+               if (hostname.charAt(hostname.length() - 1) == '.')
+                       hostStr = hostname.substring(0, hostname.length() - 1);
+               return hostStr + (withPort ? ":" + port : "");
+       }
+}
diff --git a/org.argeo.util/src/org/argeo/util/naming/package-info.java b/org.argeo.util/src/org/argeo/util/naming/package-info.java
new file mode 100644 (file)
index 0000000..f62af36
--- /dev/null
@@ -0,0 +1,2 @@
+/** Generic naming and LDAP support. */
+package org.argeo.util.naming;
\ No newline at end of file
index 90dc8d42b6ec790d4a1fd5fbe8960c9e1be876c3..5bbe4bc4b721199acd5fdc50adac322d0ddaf640 100644 (file)
@@ -1,8 +1,7 @@
 Bundle-ActivationPolicy: lazy
 Service-Component: OSGI-INF/cms-admin-rap.xml
 
-Import-Package: org.argeo.api,\
-org.eclipse.swt,\
+Import-Package: org.eclipse.swt,\
 org.eclipse.swt.graphics,\
 org.eclipse.e4.ui.workbench,\
 org.eclipse.rap.rwt.client,\
index 3ee8df1ef76c27a9b44a672c16354d4b3fe0cf8a..ac9ab1dbef14a37e51cf563862e984fd88d97d54 100644 (file)
@@ -7,11 +7,10 @@ import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsImageManager;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.UxContext;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.swt.CmsSwtUtils;
@@ -33,7 +32,7 @@ import org.osgi.service.event.EventHandler;
 
 @SuppressWarnings("restriction")
 public class CmsLoginLifecycle implements CmsView {
-       private final static Log log = LogFactory.getLog(CmsLoginLifecycle.class);
+       private final static CmsLog log = CmsLog.getLog(CmsLoginLifecycle.class);
 
        private UxContext uxContext;
        private CmsImageManager imageManager;
@@ -68,7 +67,7 @@ public class CmsLoginLifecycle implements CmsView {
                loginShell.setSubject(subject);
                try {
                        // try pre-auth
-                       loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, loginShell);
+                       loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, loginShell);
                        loginContext.login();
                } catch (LoginException e) {
                        loginShell.createUi();
index 12c4f63368f79d1b44c581b2ead189a2f5e54aed..1bca333c99d5c5b7988883add6cbd2d9f8948424 100644 (file)
@@ -3,14 +3,13 @@ package org.argeo.cms.e4.rap;
 import java.util.Enumeration;
 
 import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.eclipse.rap.rwt.application.Application;
 import org.osgi.framework.Bundle;
 
 /** Simple RAP app which loads all e4xmi files. */
 public class SimpleRapE4App extends AbstractRapE4App {
-       private final static Log log = LogFactory.getLog(SimpleRapE4App.class);
+       private final static CmsLog log = CmsLog.getLog(SimpleRapE4App.class);
 
        private String baseE4xmi = "/e4xmi";
 
index 30b21b0191694004e292bf67bd60f80f210f2dc1..5b0b8b9f6aa41414ab71c821ed1df3c2a895328a 100644 (file)
@@ -1,6 +1,5 @@
 Import-Package:\
 org.eclipse.swt,\
-org.argeo.api,\
 org.argeo.eclipse.ui,\
 javax.jcr.nodetype,\
 javax.jcr.security,\
index 30cff8f8163c6396be6bf33c879d7f295c0df751..01ebb237e11eec0e8715e4659e61babd02af466a 100644 (file)
@@ -9,7 +9,7 @@ import javax.jcr.RepositoryException;
 import javax.script.Invocable;
 import javax.script.ScriptException;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.swt.Selected;
 import org.argeo.cms.ui.CmsUiProvider;
@@ -79,7 +79,7 @@ public class AppUi implements CmsUiProvider, Branding {
                        EntryPointFactory entryPointFactory = new EntryPointFactory() {
                                @Override
                                public EntryPoint create() {
-                                       SimpleErgonomics ergonomics = new SimpleErgonomics(repository, NodeConstants.SYS_WORKSPACE,
+                                       SimpleErgonomics ergonomics = new SimpleErgonomics(repository, CmsConstants.SYS_WORKSPACE,
                                                        "/home/root/argeo:keyring", AppUi.this, factoryProperties);
 //                                     CmsUiProvider header = app.getHeader();
 //                                     if (header != null)
index 9dd1509be96c465d59f6092276b0cfaa82140120..edf558e9c7dc99e1df18f6b2d14c6a28ebe3fc21 100644 (file)
@@ -20,11 +20,10 @@ import javax.script.ScriptEngine;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsTheme;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.CmsConstants;
+import org.argeo.cms.ui.CmsUiConstants;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.cms.web.BundleResourceLoader;
@@ -50,7 +49,7 @@ public class CmsScriptApp implements Branding {
 
        private ScriptEngine scriptEngine;
 
-       private final static Log log = LogFactory.getLog(CmsScriptApp.class);
+       private final static CmsLog log = CmsLog.getLog(CmsScriptApp.class);
 
        private String webPath;
        private String repo = "(cn=node)";
@@ -90,9 +89,9 @@ public class CmsScriptApp implements Branding {
                application.setExceptionHandler(new CmsExceptionHandler());
 
                // loading animated gif
-               application.addResource(CmsConstants.LOADING_IMAGE, createResourceLoader(CmsConstants.LOADING_IMAGE));
+               application.addResource(CmsUiConstants.LOADING_IMAGE, createResourceLoader(CmsUiConstants.LOADING_IMAGE));
                // empty image
-               application.addResource(CmsConstants.NO_IMAGE, createResourceLoader(CmsConstants.NO_IMAGE));
+               application.addResource(CmsUiConstants.NO_IMAGE, createResourceLoader(CmsUiConstants.NO_IMAGE));
 
                for (String resource : resources) {
                        application.addResource(resource, bundleRL);
index d7c1a63ce2c13d498f12ee90ed420673d315919b..499840a73894244c116619b30be6f070f16a2be1 100644 (file)
@@ -10,8 +10,7 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.eclipse.rap.rwt.application.Application;
 import org.eclipse.rap.rwt.application.ApplicationConfiguration;
@@ -23,7 +22,7 @@ public class CmsScriptRwtApplication implements ApplicationConfiguration {
        public final static String APP = "APP";
        public final static String BC = "BC";
 
-       private final Log log = LogFactory.getLog(CmsScriptRwtApplication.class);
+       private final CmsLog log = CmsLog.getLog(CmsScriptRwtApplication.class);
 
        BundleContext bundleContext;
        Repository repository;
index 7813156ec92ccd13334c71a3435480449ee749cb..a550953718fe28f7e45f270f0c0e048b65ed7da9 100644 (file)
@@ -2,8 +2,7 @@ package org.argeo.cms.ui.script;
 
 import javax.jcr.Repository;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -11,7 +10,7 @@ import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.ServiceTracker;
 
 public class ScriptAppActivator implements BundleActivator {
-       private final static Log log = LogFactory.getLog(ScriptAppActivator.class);
+       private final static CmsLog log = CmsLog.getLog(ScriptAppActivator.class);
 
        @Override
        public void start(BundleContext context) throws Exception {
index bf68fc29984817b3dd1321f7a9fa1c3d45d41206..0c870e1e884987d1ba0e5b9d75ef19c7c1a328ba 100644 (file)
@@ -8,15 +8,14 @@ import javax.script.Invocable;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.osgi.framework.BundleContext;
 
 class ScriptUi implements CmsUiProvider {
-       private final static Log log = LogFactory.getLog(ScriptUi.class);
+       private final static CmsLog log = CmsLog.getLog(ScriptUi.class);
 
        private boolean development = true;
        private ScriptEngine scriptEngine;
index 7b7bddc5c5d13b603f010266eb91f612cb72927e..947a4d11a903f1b420027b5fd490581d63f6934b 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.web;
 
-import static org.argeo.naming.SharedSecret.X_SHARED_SECRET;
+import static org.argeo.util.naming.SharedSecret.X_SHARED_SECRET;
 
 import java.io.IOException;
 import java.security.PrivilegedAction;
@@ -21,10 +21,9 @@ import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsAuth;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.RemoteAuthCallback;
@@ -35,8 +34,8 @@ import org.argeo.cms.swt.CmsStyles;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.eclipse.ui.specific.UiContext;
 import org.argeo.jcr.JcrUtils;
-import org.argeo.naming.AuthPassword;
-import org.argeo.naming.SharedSecret;
+import org.argeo.util.naming.AuthPassword;
+import org.argeo.util.naming.SharedSecret;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.rap.rwt.application.AbstractEntryPoint;
 import org.eclipse.rap.rwt.client.WebClient;
@@ -53,7 +52,7 @@ import org.eclipse.swt.widgets.Shell;
 public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implements CmsView {
        private static final long serialVersionUID = 906558779562569784L;
 
-       private final Log log = LogFactory.getLog(AbstractCmsEntryPoint.class);
+       private final CmsLog log = CmsLog.getLog(AbstractCmsEntryPoint.class);
 
        // private final Subject subject;
        private LoginContext loginContext;
@@ -85,13 +84,13 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                // Initial login
                LoginContext lc;
                try {
-                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
+                       lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER,
                                        new RemoteAuthCallbackHandler(new ServletHttpRequest(UiContext.getHttpRequest()),
                                                        new ServletHttpResponse(UiContext.getHttpResponse())));
                        lc.login();
                } catch (LoginException e) {
                        try {
-                               lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
+                               lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS);
                                lc.login();
                        } catch (LoginException e1) {
                                throw new CmsException("Cannot log in as anonymous", e1);
@@ -197,7 +196,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                try {
                        CurrentUser.logoutCmsSession(loginContext.getSubject());
                        loginContext.logout();
-                       LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
+                       LoginContext anonymousLc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS);
                        anonymousLc.login();
                        authChange(anonymousLc);
                } catch (LoginException e) {
@@ -302,7 +301,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                                                }
                                        }
                                };
-                               LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, token);
+                               LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, token);
                                lc.login();
                                authChange(lc);// sets the node as well
                                // } else {
index e5b6c7efca1e37b6d76b1ffb5086a5505047e84f..4008b49eb58d5f776b4081d599dab1c294e39f16 100644 (file)
@@ -5,12 +5,11 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsApp;
 import org.argeo.api.cms.CmsAppListener;
 import org.argeo.api.cms.CmsTheme;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.util.LangUtils;
 import org.eclipse.rap.rwt.RWT;
@@ -27,7 +26,7 @@ import org.osgi.service.event.EventAdmin;
 
 /** An RWT web app integrating with a {@link CmsApp}. */
 public class CmsWebApp implements ApplicationConfiguration, ExceptionHandler, CmsAppListener {
-       private final static Log log = LogFactory.getLog(CmsWebApp.class);
+       private final static CmsLog log = CmsLog.getLog(CmsWebApp.class);
 
        private BundleContext bundleContext;
        private CmsApp cmsApp;
index b0d1e842df7451fa03abbd87dbf57fb69e7543ca..afc07c5b0681dfa61cfd057ed3ead7ad1ffcc25e 100644 (file)
@@ -12,14 +12,13 @@ import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsApp;
+import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsImageManager;
 import org.argeo.api.cms.CmsSession;
 import org.argeo.api.cms.CmsUi;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.UxContext;
 import org.argeo.cms.LocaleUtils;
 import org.argeo.cms.auth.CurrentUser;
@@ -50,7 +49,7 @@ import org.osgi.service.event.EventAdmin;
 @SuppressWarnings("restriction")
 public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationListener {
        private static final long serialVersionUID = 7733510691684570402L;
-       private final static Log log = LogFactory.getLog(CmsWebEntryPoint.class);
+       private final static CmsLog log = CmsLog.getLog(CmsWebEntryPoint.class);
 
        private EventAdmin eventAdmin;
 
@@ -85,13 +84,13 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL
                // Initial login
                LoginContext lc;
                try {
-                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
+                       lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER,
                                        new RemoteAuthCallbackHandler(new ServletHttpRequest(UiContext.getHttpRequest()),
                                                        new ServletHttpResponse(UiContext.getHttpResponse())));
                        lc.login();
                } catch (LoginException e) {
                        try {
-                               lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
+                               lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS);
                                lc.login();
                        } catch (LoginException e1) {
                                throw new IllegalStateException("Cannot log in as anonymous", e1);
@@ -156,7 +155,7 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL
                try {
                        CurrentUser.logoutCmsSession(loginContext.getSubject());
                        loginContext.logout();
-                       LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
+                       LoginContext anonymousLc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS);
                        anonymousLc.login();
                        authChange(anonymousLc);
                } catch (LoginException e) {
index 4cd6874d0f35a6d59f0ab66ed79361337f7f3392..f063117ae625ca0415db3ce535c61bee294059e2 100644 (file)
@@ -20,12 +20,11 @@ import javax.jcr.Session;
 import javax.jcr.security.Privilege;
 import javax.jcr.version.VersionManager;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.ui.CmsConstants;
+import org.argeo.cms.ui.CmsUiConstants;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.LifeCycleUiProvider;
 import org.argeo.cms.ui.util.CmsUiUtils;
@@ -53,8 +52,8 @@ import org.osgi.framework.ServiceRegistration;
 
 /** A basic generic app based on {@link SimpleErgonomics}. */
 @Deprecated
-public class SimpleApp implements CmsConstants, ApplicationConfiguration {
-       private final static Log log = LogFactory.getLog(SimpleApp.class);
+public class SimpleApp implements CmsUiConstants, ApplicationConfiguration {
+       private final static CmsLog log = CmsLog.getLog(SimpleApp.class);
 
        private String contextName = null;
 
@@ -68,8 +67,8 @@ public class SimpleApp implements CmsConstants, ApplicationConfiguration {
        private Repository repository;
        private String workspace = null;
        private String jcrBasePath = "/";
-       private List<String> roPrincipals = Arrays.asList(NodeConstants.ROLE_ANONYMOUS, NodeConstants.ROLE_USER);
-       private List<String> rwPrincipals = Arrays.asList(NodeConstants.ROLE_USER);
+       private List<String> roPrincipals = Arrays.asList(CmsConstants.ROLE_ANONYMOUS, CmsConstants.ROLE_USER);
+       private List<String> rwPrincipals = Arrays.asList(CmsConstants.ROLE_USER);
 
        private CmsUiProvider header;
        private Map<String, CmsUiProvider> pages = new LinkedHashMap<String, CmsUiProvider>();
index 6e1165cf32777b3083f6f854c9f900ce80616a0d..26ca3705f24b6131881536df151d4fc062b7f117 100644 (file)
@@ -7,9 +7,8 @@ import javax.jcr.Node;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.UxContext;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.swt.CmsStyles;
@@ -31,7 +30,7 @@ import org.eclipse.swt.widgets.Control;
 public class SimpleErgonomics extends AbstractCmsEntryPoint {
        private static final long serialVersionUID = 8743413921359548523L;
 
-       private final static Log log = LogFactory.getLog(SimpleErgonomics.class);
+       private final static CmsLog log = CmsLog.getLog(SimpleErgonomics.class);
 
        private boolean uiInitialized = false;
        private Composite headerArea;
index a28b13fc6ce322cfd97936fe3cf2bde8ef9f7be1..ea2ebdfb44b5df142102f13a37b23c2656a7c573 100644 (file)
@@ -1,14 +1,13 @@
 package org.argeo.cms.web;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.api.cms.CmsTheme;
+import org.argeo.api.cms.CmsLog;
 import org.eclipse.rap.rwt.application.Application;
 import org.eclipse.rap.rwt.service.ResourceLoader;
 
 /** Web specific utilities around theming. */
 public class WebThemeUtils {
-       private final static Log log = LogFactory.getLog(WebThemeUtils.class);
+       private final static CmsLog log = CmsLog.getLog(WebThemeUtils.class);
 
        public static void apply(Application application, CmsTheme theme) {
                ResourceLoader resourceLoader = new CmsThemeResourceLoader(theme);
index dca5b91893177b14b01454d1ec15cce4f1e9b835..ff79c8041156aa6010641c0b307ab5fe48c2a62c 100644 (file)
@@ -2,7 +2,6 @@ Bundle-SymbolicName: org.argeo.cms.e4.rcp;singleton=true
 
 Require-Bundle: org.eclipse.core.runtime
 
-Import-Package: org.argeo.api,\
-!org.eclipse.core.runtime,\
+Import-Package: !org.eclipse.core.runtime,\
 org.eclipse.swt,\
 *
index 9cf4c8c6be1ecdb1a868f4c2f5a6856c260f6310..5cc6a839453bacea1144dce120f79f5a2cd2e155 100644 (file)
@@ -7,7 +7,7 @@ import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsImageManager;
 import org.argeo.api.cms.CmsView;
 import org.argeo.api.cms.UxContext;
@@ -39,7 +39,7 @@ public class CmsE4Application implements IApplication, CmsView {
                loginShell.setSubject(subject);
                try {
                        // try pre-auth
-                       loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, loginShell);
+                       loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, loginShell);
                        loginContext.login();
                } catch (LoginException e) {
                        e.printStackTrace();
index c3704d8bfc91d6c0b133fb57fd25ab6f270da6da..72b00d2cdc080abd94db1a6d268730b0fa029969 100644 (file)
@@ -2,7 +2,6 @@
 Service-Component: OSGI-INF/cmsRcpApp.xml
 
 Import-Package:\
-org.argeo.api,\
 org.argeo.cms.auth,\
 org.eclipse.swt,\
 org.eclipse.swt.graphics,\
index c2f3d65a6d8fb5c6d858eb5902d63100a89a3276..8614d70b58a97bfd1a3da75b49dc88347602b03d 100644 (file)
@@ -11,15 +11,14 @@ import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
 import org.argeo.api.cms.CmsApp;
+import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsImageManager;
 import org.argeo.api.cms.CmsSession;
 import org.argeo.api.cms.CmsTheme;
 import org.argeo.api.cms.CmsUi;
 import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.UxContext;
 import org.argeo.cms.osgi.CmsOsgiUtils;
 import org.argeo.cms.swt.CmsSwtUtils;
@@ -38,7 +37,7 @@ import org.osgi.service.event.EventAdmin;
 /** Runs a {@link CmsApp} as an SWT desktop application. */
 @SuppressWarnings("restriction")
 public class CmsRcpApp implements CmsView {
-       private final static Log log = LogFactory.getLog(CmsRcpApp.class);
+       private final static CmsLog log = CmsLog.getLog(CmsRcpApp.class);
 
        private BundleContext bundleContext = FrameworkUtil.getBundle(CmsRcpApp.class).getBundleContext();
 
@@ -107,7 +106,7 @@ public class CmsRcpApp implements CmsView {
                        try {
                                // try pre-auth
 //                             loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, loginShell);
-                               loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_SINGLE_USER);
+                               loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_SINGLE_USER);
                                loginContext.login();
                        } catch (LoginException e) {
                                throw new IllegalStateException("Could not log in.", e);
@@ -129,7 +128,7 @@ public class CmsRcpApp implements CmsView {
                                ui = cmsApp.initUi(parent);
                                if (ui instanceof Composite)
                                        ((Composite) ui).setLayoutData(CmsSwtUtils.fillAll());
-                               //ui.setLayoutData(CmsUiUtils.fillAll());
+                               // ui.setLayoutData(CmsUiUtils.fillAll());
                                // we need ui to be set before refresh so that CmsView can store UI context data
                                // in it.
                                cmsApp.refreshUi(ui, null);