Move JCR to another repository
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 15 Oct 2022 09:39:06 +0000 (11:39 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 15 Oct 2022 09:39:06 +0000 (11:39 +0200)
319 files changed:
.gitignore
Makefile
jcr/org.argeo.cms.jcr.ui/.classpath [deleted file]
jcr/org.argeo.cms.jcr.ui/.project [deleted file]
jcr/org.argeo.cms.jcr.ui/META-INF/.gitignore [deleted file]
jcr/org.argeo.cms.jcr.ui/bnd.bnd [deleted file]
jcr/org.argeo.cms.jcr.ui/build.properties [deleted file]
jcr/org.argeo.cms.jcr.ui/icons/loading.gif [deleted file]
jcr/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png [deleted file]
jcr/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/CmsUiConstants.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/CmsUiProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/LifeCycleUiProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/AbstractFormPart.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormColors.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormFonts.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormToolkit.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormUtil.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormColors.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormPart.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IManagedForm.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IPartSelectionListener.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/ManagedForm.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormEditor.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormPage.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/IFormPage.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditableLink.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditableMultiStringProperty.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditablePropertyDate.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditablePropertyString.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormConstants.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormEditorHeader.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormStyle.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormUtils.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/MarkupValidatorCopy.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FileDrop.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FsStyles.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/Activator.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/JcrContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/JcrFileUploadReceiver.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/SimpleEditableImage.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/FullVersioningTreeContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrBrowserUtils.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrDClickListener.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrImages.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/OsgiRepositoryRegister.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertiesContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/RepositoryRegister.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/VersionLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/MaintainedRepositoryElem.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/SingleJcrNodeElem.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/WorkspaceElem.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsLink.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsPane.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/MenuLink.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleCmsHeader.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleDynamicPages.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleStaticPage.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleStyle.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/StyleSheetResourceLoader.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SystemNotifications.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenu.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenuLink.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/VerticalMenu.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/ItemPart.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/JcrVersionCmsEditable.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/NodePart.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/PropertyPart.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/Section.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/SectionPart.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/EditableImage.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/EditableText.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/Img.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/JcrComposite.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/StyledControl.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/TextStyles.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/JcrUiUtils.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeColumnLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeElement.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeElementComparer.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodesWrapper.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/QueryTableContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/RowColumnLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/SimpleNodeContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/VersionColumnLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/VersionHistoryContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/WrappedNode.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/JcrColumnDefinition.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/NodeViewerComparator.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/RowViewerComparator.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrNodeLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrRowLabelProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/package-info.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/JcrFileProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/JcrItemsComparator.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/NodeViewerComparer.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/SingleSessionFileProvider.java [deleted file]
jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/.classpath [deleted file]
jcr/org.argeo.cms.jcr/.project [deleted file]
jcr/org.argeo.cms.jcr/.settings/org.eclipse.jdt.core.prefs [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/dataServletContext.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/filesServlet.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/filesServletContext.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/jcrContentProvider.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/jcrFsProvider.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/jcrRepositoryFactory.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/jcrServletContext.xml [deleted file]
jcr/org.argeo.cms.jcr/OSGI-INF/repositoryContextsFactory.xml [deleted file]
jcr/org.argeo.cms.jcr/bnd.bnd [deleted file]
jcr/org.argeo.cms.jcr/build.properties [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/CustomRepositoryConfigurationParser.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JackrabbitType.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/LocalFsDataStore.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-h2.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-h2_postgresql.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-localfs.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-memory.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_cluster.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_cluster_ds.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_ds.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionAdapter.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionNamespaceContext.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/argeo.cnd [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/dn.cnd [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrFsProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsPaths.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrRepositoryFactory.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeKeyRing.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/DataServletContext.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrReadServlet.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrServletContext.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrWriteServlet.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/protectedHandlers.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/webdav-config.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/ldap.cnd [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/node.cnd [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitAdminLoginModule.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryFactory.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryService.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryServiceFactory.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/JackrabbitClient.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/NonSerialBasicAuthCache.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/AbstractJackrabbitFsProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/DavexFsProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/JackrabbitMemoryFsProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/fs-memory.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-h2.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-localfs.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-memory.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-postgresql-ds.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-postgresql.xml [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/Bin.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/CollectionNodeIterator.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/Jcr.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrAuthorizations.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrCallback.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrException.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrMonitor.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrRepositoryWrapper.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUrlStreamHandler.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxApi.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxName.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxType.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/PropertyDiff.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/SimplePrincipal.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/VersionDiff.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/BinaryChannel.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFsException.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrPath.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/NodeFileAttributes.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/Text.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/WorkspaceFileStore.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/jcrx.cnd [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxy.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/xml/JcrXmlUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/jcr/xml/removePrefixes.xsl [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/BackupContentHandler.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/internal/Activator.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/package-info.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAccessControlProvider.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAccessManager.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAuthContext.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/package-info.java [deleted file]
swt/org.argeo.cms.e4/bnd.bnd
swt/org.argeo.cms.e4/e4xmi/cms-devops.e4xmi
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/addons/AuthAddon.java
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/EclipseJcrMonitor.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/GenericPropertyPage.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrE4DClickListener.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrNodeEditor.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/SimplePart.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddFolderNode.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/DeleteNodes.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/Refresh.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/RenameNode.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/package-info.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/package-info.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/Browse.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/ConnectivityDeploymentUi.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/LogDeploymentUi.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/MaintenanceStyles.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/NonAdminPage.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/SecurityDeploymentUi.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/package-info.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/CmsWorkbenchStyles.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/SecurityAdminImages.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UiAdminUtils.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UiUserAdminListener.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/DeleteGroups.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/DeleteUsers.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/package-info.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/package-info.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/DomainNameLP.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserAdminAbstractLP.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserDragListener.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserNameLP.java [deleted file]
swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/package-info.java [deleted file]
swt/rcp/org.argeo.cms.e4.rcp/argeo-companion.e4xmi

index c306476f0ea5396b0638b3f42c036df17ba18d31..11caf4780ec37c342050325a30d1e9e7701105f2 100644 (file)
@@ -1,7 +1,4 @@
 **/bin/
-**/target/
-**/generated/
 **/MANIFEST.MF
-/build/
 /sdk.mk
 /output/
index 7914476982d2dc3a9f5b1f4d3452dd0d578a0133..406f96a56be839032425f1825d61ff9e3f507c48 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,8 +28,6 @@ swt/rap/org.argeo.swt.specific.rap \
 swt/rap/org.argeo.cms.swt.rap \
 swt/rap/org.argeo.cms.swt.rap.cli \
 swt/rap/org.argeo.cms.e4.rap \
-jcr/org.argeo.cms.jcr \
-jcr/org.argeo.cms.jcr.ui \
 
 DEP_CATEGORIES = \
 org.argeo.tp \
@@ -39,7 +37,6 @@ osgi/api/org.argeo.tp.osgi \
 osgi/equinox/org.argeo.tp.eclipse \
 swt/rap/org.argeo.tp.swt \
 swt/rap/org.argeo.tp.swt.workbench \
-org.argeo.tp.jcr \
 $(A2_CATEGORY) \
 swt/$(A2_CATEGORY) \
 swt/rap/$(A2_CATEGORY) \
diff --git a/jcr/org.argeo.cms.jcr.ui/.classpath b/jcr/org.argeo.cms.jcr.ui/.classpath
deleted file mode 100644 (file)
index 81fe078..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
-       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/jcr/org.argeo.cms.jcr.ui/.project b/jcr/org.argeo.cms.jcr.ui/.project
deleted file mode 100644 (file)
index 645296b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>org.argeo.cms.jcr.ui</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.ManifestBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.SchemaBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.pde.PluginNature</nature>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-       </natures>
-</projectDescription>
diff --git a/jcr/org.argeo.cms.jcr.ui/META-INF/.gitignore b/jcr/org.argeo.cms.jcr.ui/META-INF/.gitignore
deleted file mode 100644 (file)
index 4854a41..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/MANIFEST.MF
diff --git a/jcr/org.argeo.cms.jcr.ui/bnd.bnd b/jcr/org.argeo.cms.jcr.ui/bnd.bnd
deleted file mode 100644 (file)
index c3c609c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-Bundle-Activator: org.argeo.cms.ui.internal.Activator
-Bundle-ActivationPolicy: lazy
-
-Import-Package: org.eclipse.swt,\
-org.eclipse.jface.window,\
-org.eclipse.core.commands,\
-javax.jcr.security,\
-org.eclipse.rap.fileupload;version="[2.1,4)",\
-org.eclipse.rap.rwt;version="[2.1,4)",\
-org.eclipse.rap.rwt.application;version="[2.1,4)",\
-org.eclipse.rap.rwt.client;version="[2.1,4)",\
-org.eclipse.rap.rwt.client.service;version="[2.1,4)",\
-org.eclipse.rap.rwt.service;version="[2.1,4)",\
-org.eclipse.rap.rwt.widgets;version="[2.1,4)",\
-org.osgi.*;version=0.0.0,\
-javax.servlet.*;version="[3,5)",\
-*
-
-## TODO: in order to enable single sourcing, we have introduced dummy RAP packages 
-# in the RCP specific bundle org.argeo.eclipse.ui.rap.
-# this was working with RAP 2.x but since we upgrade Rap to 3.1.x, 
-# there is a version range issue cause org.argeo.eclipse.ui.rap bundle is still in 2.x
-# We enable large RAP version range as a workaround that must be fixed 
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/build.properties b/jcr/org.argeo.cms.jcr.ui/build.properties
deleted file mode 100644 (file)
index c6baffa..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
-               .,\
-               icons/
diff --git a/jcr/org.argeo.cms.jcr.ui/icons/loading.gif b/jcr/org.argeo.cms.jcr.ui/icons/loading.gif
deleted file mode 100644 (file)
index 3288d10..0000000
Binary files a/jcr/org.argeo.cms.jcr.ui/icons/loading.gif and /dev/null differ
diff --git a/jcr/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png b/jcr/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png
deleted file mode 100644 (file)
index 0396506..0000000
Binary files a/jcr/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png and /dev/null differ
diff --git a/jcr/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png b/jcr/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png
deleted file mode 100644 (file)
index 8e3abb5..0000000
Binary files a/jcr/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png and /dev/null differ
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/CmsUiConstants.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/CmsUiConstants.java
deleted file mode 100644 (file)
index fd1dda5..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.argeo.cms.ui;
-
-/** 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";
-
-       // MISCEALLENEOUS
-       String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm";
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/CmsUiProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/CmsUiProvider.java
deleted file mode 100644 (file)
index 5f2377b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.argeo.cms.ui;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.acr.Content;
-import org.argeo.cms.jcr.acr.JcrContent;
-import org.argeo.cms.swt.acr.SwtUiProvider;
-import org.argeo.jcr.JcrException;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** Stateless factory building an SWT user interface given a JCR context. */
-public interface CmsUiProvider extends SwtUiProvider {
-       /**
-        * Initialises a user interface.
-        * 
-        * @param parent  the parent composite
-        * @param context a context node (holding the JCR underlying session), or null
-        */
-       default Control createUi(Composite parent, Node context) throws RepositoryException {
-               // does nothing by default
-               return null;
-       }
-
-       default Control createUiPart(Composite parent, Node context) {
-               try {
-                       return createUi(parent, context);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot create UI for context " + context, e);
-               }
-       }
-
-       @Override
-       default Control createUiPart(Composite parent, Content context) {
-               if (context == null)
-                       return createUiPart(parent, (Node) null);
-               if (context instanceof JcrContent) {
-                       Node node = ((JcrContent) context).getJcrNode();
-                       return createUiPart(parent, node);
-               } else {
-//                     CmsLog.getLog(CmsUiProvider.class)
-//                                     .warn("In " + getClass() + ", content " + context + " is not compatible with JCR.");
-//                     return createUiPart(parent, (Node) null);
-
-                       throw new IllegalArgumentException(
-                                       "In " + getClass() + ", content " + context + " is not compatible with JCR");
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/LifeCycleUiProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/LifeCycleUiProvider.java
deleted file mode 100644 (file)
index 5d77c15..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.argeo.cms.ui;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-/** CmsUiProvider notified of initialisation with a system session. */
-public interface LifeCycleUiProvider extends CmsUiProvider {
-       public void init(Session adminSession) throws RepositoryException;
-
-       public void destroy();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/AbstractFormPart.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/AbstractFormPart.java
deleted file mode 100644 (file)
index 4ce4688..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-/**
- * AbstractFormPart implements IFormPart interface and can be used as a
- * convenient base class for concrete form parts. If a method contains
- * code that must be called, look for instructions to call 'super'
- * when overriding.
- * 
- * @see org.eclipse.ui.forms.widgets.Section
- * @since 1.0
- */
-public abstract class AbstractFormPart implements IFormPart {
-       private IManagedForm managedForm;
-       private boolean dirty = false;
-       private boolean stale = true;
-       /**
-        * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
-        */
-       public void initialize(IManagedForm form) {
-               this.managedForm = form;
-       }
-       /**
-        * Returns the form that manages this part.
-        * 
-        * @return the managed form
-        */
-       public IManagedForm getManagedForm() {
-               return managedForm;
-       }
-       /**
-        * Disposes the part. Subclasses should override to release any system
-        * resources.
-        */
-       public void dispose() {
-       }
-       /**
-        * Commits the part. Subclasses should call 'super' when overriding.
-        * 
-        * @param onSave
-        *            <code>true</code> if the request to commit has arrived as a
-        *            result of the 'save' action.
-        */
-       public void commit(boolean onSave) {
-               dirty = false;
-       }
-       /**
-        * Sets the overall form input. Subclases may elect to override the method
-        * and adjust according to the form input.
-        * 
-        * @param input
-        *            the form input object
-        * @return <code>false</code>
-        */
-       public boolean setFormInput(Object input) {
-               return false;
-       }
-       /**
-        * Instructs the part to grab keyboard focus.
-        */
-       public void setFocus() {
-       }
-       /**
-        * Refreshes the section after becoming stale (falling behind data in the
-        * model). Subclasses must call 'super' when overriding this method.
-        */
-       public void refresh() {
-               stale = false;
-               // since we have refreshed, any changes we had in the
-               // part are gone and we are not dirty
-               dirty = false;
-       }
-       /**
-        * Marks the part dirty. Subclasses should call this method as a result of
-        * user interaction with the widgets in the section.
-        */
-       public void markDirty() {
-               dirty = true;
-               managedForm.dirtyStateChanged();
-       }
-       /**
-        * Tests whether the part is dirty i.e. its widgets have state that is
-        * newer than the data in the model.
-        * 
-        * @return <code>true</code> if the part is dirty, <code>false</code>
-        *         otherwise.
-        */
-       public boolean isDirty() {
-               return dirty;
-       }
-       /**
-        * Tests whether the part is stale i.e. its widgets have state that is
-        * older than the data in the model.
-        * 
-        * @return <code>true</code> if the part is stale, <code>false</code>
-        *         otherwise.
-        */
-       public boolean isStale() {
-               return stale;
-       }
-       /**
-        * Marks the part stale. Subclasses should call this method as a result of
-        * model notification that indicates that the content of the section is no
-        * longer in sync with the model.
-        */
-       public void markStale() {
-               stale = true;
-               managedForm.staleStateChanged();
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormColors.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormColors.java
deleted file mode 100644 (file)
index 32b031b..0000000
+++ /dev/null
@@ -1,730 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.resource.LocalResourceManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.RGB;
-//import org.eclipse.swt.internal.graphics.Graphics;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * Manages colors that will be applied to forms and form widgets. The colors are
- * chosen to make the widgets look correct in the editor area. If a different
- * set of colors is needed, subclass this class and override 'initialize' and/or
- * 'initializeColors'.
- * 
- * @since 1.0
- */
-public class FormColors {
-       /**
-        * Key for the form title foreground color.
-        * 
-        * @deprecated use <code>IFormColors.TITLE</code>.
-        */
-       public static final String TITLE = IFormColors.TITLE;
-
-       /**
-        * Key for the tree/table border color.
-        * 
-        * @deprecated use <code>IFormColors.BORDER</code>
-        */
-       public static final String BORDER = IFormColors.BORDER;
-
-       /**
-        * Key for the section separator color.
-        * 
-        * @deprecated use <code>IFormColors.SEPARATOR</code>.
-        */
-       public static final String SEPARATOR = IFormColors.SEPARATOR;
-
-       /**
-        * Key for the section title bar background.
-        * 
-        * @deprecated use <code>IFormColors.TB_BG
-        */
-       public static final String TB_BG = IFormColors.TB_BG;
-
-       /**
-        * Key for the section title bar foreground.
-        * 
-        * @deprecated use <code>IFormColors.TB_FG</code>
-        */
-       public static final String TB_FG = IFormColors.TB_FG;
-
-       /**
-        * Key for the section title bar gradient.
-        * 
-        * @deprecated use <code>IFormColors.TB_GBG</code>
-        */
-       public static final String TB_GBG = IFormColors.TB_GBG;
-
-       /**
-        * Key for the section title bar border.
-        * 
-        * @deprecated use <code>IFormColors.TB_BORDER</code>.
-        */
-       public static final String TB_BORDER = IFormColors.TB_BORDER;
-
-       /**
-        * Key for the section toggle color. Since 3.1, this color is used for all
-        * section styles.
-        * 
-        * @deprecated use <code>IFormColors.TB_TOGGLE</code>.
-        */
-       public static final String TB_TOGGLE = IFormColors.TB_TOGGLE;
-
-       /**
-        * Key for the section toggle hover color.
-        * 
-        * @deprecated use <code>IFormColors.TB_TOGGLE_HOVER</code>.
-        */
-       public static final String TB_TOGGLE_HOVER = IFormColors.TB_TOGGLE_HOVER;
-
-       protected Map colorRegistry = new HashMap(10);
-
-       private LocalResourceManager resources;
-
-       protected Color background;
-
-       protected Color foreground;
-
-       private boolean shared;
-
-       protected Display display;
-
-       protected Color border;
-
-       /**
-        * Creates form colors using the provided display.
-        * 
-        * @param display
-        *            the display to use
-        */
-       public FormColors(Display display) {
-               this.display = display;
-               initialize();
-       }
-
-       /**
-        * Returns the display used to create colors.
-        * 
-        * @return the display
-        */
-       public Display getDisplay() {
-               return display;
-       }
-
-       /**
-        * Initializes the colors. Subclasses can override this method to change the
-        * way colors are created. Alternatively, only the color table can be
-        * modified by overriding <code>initializeColorTable()</code>.
-        * 
-        * @see #initializeColorTable
-        */
-       protected void initialize() {
-               background = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
-               foreground = display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
-               initializeColorTable();
-               updateBorderColor();
-       }
-
-       /**
-        * Allocates colors for the following keys: BORDER, SEPARATOR and
-        * TITLE. Subclasses can override to allocate these colors differently.
-        */
-       protected void initializeColorTable() {
-               createTitleColor();
-               createColor(IFormColors.SEPARATOR, getColor(IFormColors.TITLE).getRGB());
-               RGB black = getSystemColor(SWT.COLOR_BLACK);
-               RGB borderRGB = getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT);
-               createColor(IFormColors.BORDER, blend(borderRGB, black, 80));
-       }
-
-       /**
-        * Allocates colors for the section tool bar (all the keys that start with
-        * TB). Since these colors are only needed when TITLE_BAR style is used with
-        * the Section widget, they are not needed all the time and are allocated on
-        * demand. Consequently, this method will do nothing if the colors have been
-        * already initialized. Call this method prior to using colors with the TB
-        * keys to ensure they are available.
-        */
-       public void initializeSectionToolBarColors() {
-               if (colorRegistry.containsKey(IFormColors.TB_BG))
-                       return;
-               createTitleBarGradientColors();
-               createTitleBarOutlineColors();
-               createTwistieColors();
-       }
-
-       /**
-        * Allocates additional colors for the form header, namely background
-        * gradients, bottom separator keylines and DND highlights. Since these
-        * colors are only needed for clients that want to use these particular
-        * style of header rendering, they are not needed all the time and are
-        * allocated on demand. Consequently, this method will do nothing if the
-        * colors have been already initialized. Call this method prior to using
-        * color keys with the H_ prefix to ensure they are available.
-        */
-       protected void initializeFormHeaderColors() {
-               if (colorRegistry.containsKey(IFormColors.H_BOTTOM_KEYLINE2))
-                       return;
-               createFormHeaderColors();
-       }
-
-       /**
-        * Returns the RGB value of the system color represented by the code
-        * argument, as defined in <code>SWT</code> class.
-        * 
-        * @param code
-        *            the system color constant as defined in <code>SWT</code>
-        *            class.
-        * @return the RGB value of the system color
-        */
-       public RGB getSystemColor(int code) {
-               return getDisplay().getSystemColor(code).getRGB();
-       }
-
-       /**
-        * Creates the color for the specified key using the provided RGB object.
-        * The color object will be returned and also put into the registry. When
-        * the class is disposed, the color will be disposed with it.
-        * 
-        * @param key
-        *            the unique color key
-        * @param rgb
-        *            the RGB object
-        * @return the allocated color object
-        */
-       public Color createColor(String key, RGB rgb) {
-               // RAP [rh] changes due to missing Color constructor
-//             Color c = getResourceManager().createColor(rgb);
-//             Color prevC = (Color) colorRegistry.get(key);
-//             if (prevC != null && !prevC.isDisposed())
-//                     getResourceManager().destroyColor(prevC.getRGB());
-//             Color c = Graphics.getColor(rgb);
-               Color c = new Color(display, rgb);
-               colorRegistry.put(key, c);        
-               return c;
-       }
-
-       /**
-        * Creates a color that can be used for areas of the form that is inactive.
-        * These areas can contain images, links, controls and other content but are
-        * considered auxilliary to the main content area.
-        * 
-        * <p>
-        * The color should not be disposed because it is managed by this class.
-        * 
-        * @return the inactive form color
-        */
-       public Color getInactiveBackground() {
-               String key = "__ncbg__"; //$NON-NLS-1$
-               Color color = getColor(key);
-               if (color == null) {
-                       RGB sel = getSystemColor(SWT.COLOR_LIST_SELECTION);
-                       // a blend of 95% white and 5% list selection system color
-                       RGB ncbg = blend(sel, getSystemColor(SWT.COLOR_WHITE), 5);
-                       color = createColor(key, ncbg);
-               }
-               return color;
-       }
-
-       /**
-        * Creates the color for the specified key using the provided RGB values.
-        * The color object will be returned and also put into the registry. If
-        * there is already another color object under the same key in the registry,
-        * the existing object will be disposed. When the class is disposed, the
-        * color will be disposed with it.
-        * 
-        * @param key
-        *            the unique color key
-        * @param r
-        *            red value
-        * @param g
-        *            green value
-        * @param b
-        *            blue value
-        * @return the allocated color object
-        */
-       public Color createColor(String key, int r, int g, int b) {
-               return createColor(key, new RGB(r,g,b));
-       }
-
-       /**
-        * Computes the border color relative to the background. Allocated border
-        * color is designed to work well with white. Otherwise, stanard widget
-        * background color will be used.
-        */
-       protected void updateBorderColor() {
-               if (isWhiteBackground())
-                       border = getColor(IFormColors.BORDER);
-               else {
-                       border = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
-                       Color bg = getImpliedBackground();
-                       if (border.getRed() == bg.getRed()
-                                       && border.getGreen() == bg.getGreen()
-                                       && border.getBlue() == bg.getBlue())
-                               border = display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW);
-               }
-       }
-
-       /**
-        * Sets the background color. All the toolkits that use this class will
-        * share the same background.
-        * 
-        * @param bg
-        *            background color
-        */
-       public void setBackground(Color bg) {
-               this.background = bg;
-               updateBorderColor();
-               updateFormHeaderColors();
-       }
-
-       /**
-        * Sets the foreground color. All the toolkits that use this class will
-        * share the same foreground.
-        * 
-        * @param fg
-        *            foreground color
-        */
-       public void setForeground(Color fg) {
-               this.foreground = fg;
-       }
-
-       /**
-        * Returns the current background color.
-        * 
-        * @return the background color
-        */
-       public Color getBackground() {
-               return background;
-       }
-
-       /**
-        * Returns the current foreground color.
-        * 
-        * @return the foreground color
-        */
-       public Color getForeground() {
-               return foreground;
-       }
-
-       /**
-        * Returns the computed border color. Border color depends on the background
-        * and is recomputed whenever the background changes.
-        * 
-        * @return the current border color
-        */
-       public Color getBorderColor() {
-               return border;
-       }
-
-       /**
-        * Tests if the background is white. White background has RGB value
-        * 255,255,255.
-        * 
-        * @return <samp>true</samp> if background is white, <samp>false</samp>
-        *         otherwise.
-        */
-       public boolean isWhiteBackground() {
-               Color bg = getImpliedBackground();
-               return bg.getRed() == 255 && bg.getGreen() == 255
-                               && bg.getBlue() == 255;
-       }
-
-       /**
-        * Returns the color object for the provided key or <samp>null </samp> if
-        * not in the registry.
-        * 
-        * @param key
-        *            the color key
-        * @return color object if found, or <samp>null </samp> if not.
-        */
-       public Color getColor(String key) {
-               if (key.startsWith(IFormColors.TB_PREFIX))
-                       initializeSectionToolBarColors();
-               else if (key.startsWith(IFormColors.H_PREFIX))
-                       initializeFormHeaderColors();
-               return (Color) colorRegistry.get(key);
-       }
-
-       /**
-        * Disposes all the colors in the registry.
-        */
-       public void dispose() {
-               if (resources != null)
-                       resources.dispose();
-               resources = null;
-               colorRegistry = null;
-       }
-
-       /**
-        * Marks the colors shared. This prevents toolkits that share this object
-        * from disposing it.
-        */
-       public void markShared() {
-               this.shared = true;
-       }
-
-       /**
-        * Tests if the colors are shared.
-        * 
-        * @return <code>true</code> if shared, <code>false</code> otherwise.
-        */
-       public boolean isShared() {
-               return shared;
-       }
-
-       /**
-        * Blends c1 and c2 based in the provided ratio.
-        * 
-        * @param c1
-        *            first color
-        * @param c2
-        *            second color
-        * @param ratio
-        *            percentage of the first color in the blend (0-100)
-        * @return the RGB value of the blended color
-        */
-       public static RGB blend(RGB c1, RGB c2, int ratio) {
-               int r = blend(c1.red, c2.red, ratio);
-               int g = blend(c1.green, c2.green, ratio);
-               int b = blend(c1.blue, c2.blue, ratio);
-               return new RGB(r, g, b);
-       }
-
-       /**
-        * Tests the source RGB for range.
-        * 
-        * @param rgb
-        *            the tested RGB
-        * @param from
-        *            range start (excluding the value itself)
-        * @param to
-        *            range end (excluding the value itself)
-        * @return <code>true</code> if at least one of the primary colors in the
-        *         source RGB are within the provided range, <code>false</code>
-        *         otherwise.
-        */
-       public static boolean testAnyPrimaryColor(RGB rgb, int from, int to) {
-               if (testPrimaryColor(rgb.red, from, to))
-                       return true;
-               if (testPrimaryColor(rgb.green, from, to))
-                       return true;
-               if (testPrimaryColor(rgb.blue, from, to))
-                       return true;
-               return false;
-       }
-
-       /**
-        * Tests the source RGB for range.
-        * 
-        * @param rgb
-        *            the tested RGB
-        * @param from
-        *            range start (excluding the value itself)
-        * @param to
-        *            tange end (excluding the value itself)
-        * @return <code>true</code> if at least two of the primary colors in the
-        *         source RGB are within the provided range, <code>false</code>
-        *         otherwise.
-        */
-       public static boolean testTwoPrimaryColors(RGB rgb, int from, int to) {
-               int total = 0;
-               if (testPrimaryColor(rgb.red, from, to))
-                       total++;
-               if (testPrimaryColor(rgb.green, from, to))
-                       total++;
-               if (testPrimaryColor(rgb.blue, from, to))
-                       total++;
-               return total >= 2;
-       }
-
-       /**
-        * Blends two primary color components based on the provided ratio.
-        * 
-        * @param v1
-        *            first component
-        * @param v2
-        *            second component
-        * @param ratio
-        *            percentage of the first component in the blend
-        * @return
-        */
-       private static int blend(int v1, int v2, int ratio) {
-               int b = (ratio * v1 + (100 - ratio) * v2) / 100;
-               return Math.min(255, b);
-       }
-
-       private Color getImpliedBackground() {
-               if (getBackground() != null)
-                       return getBackground();
-               return getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
-       }
-
-       private static boolean testPrimaryColor(int value, int from, int to) {
-               return value > from && value < to;
-       }
-
-       private void createTitleColor() {
-               /*
-                * RGB rgb = getSystemColor(SWT.COLOR_LIST_SELECTION); // test too light
-                * if (testTwoPrimaryColors(rgb, 120, 151)) rgb = blend(rgb, BLACK, 80);
-                * else if (testTwoPrimaryColors(rgb, 150, 256)) rgb = blend(rgb, BLACK,
-                * 50); createColor(TITLE, rgb);
-                */
-               RGB bg = getImpliedBackground().getRGB();
-               RGB listSelection = getSystemColor(SWT.COLOR_LIST_SELECTION);
-               RGB listForeground = getSystemColor(SWT.COLOR_LIST_FOREGROUND);
-               RGB rgb = listSelection;
-
-               // Group 1
-               // Rule: If at least 2 of the LIST_SELECTION RGB values are equal to or
-               // between 0 and 120, then use 100% LIST_SELECTION as it is (no
-               // additions)
-               // Examples: XP Default, Win Classic Standard, Win High Con White, Win
-               // Classic Marine
-               if (testTwoPrimaryColors(listSelection, -1, 121))
-                       rgb = listSelection;
-               // Group 2
-               // When LIST_BACKGROUND = white (255, 255, 255) or not black, text
-               // colour = LIST_SELECTION @ 100% Opacity + 50% LIST_FOREGROUND over
-               // LIST_BACKGROUND
-               // Rule: If at least 2 of the LIST_SELECTION RGB values are equal to or
-               // between 121 and 255, then add 50% LIST_FOREGROUND to LIST_SELECTION
-               // foreground colour
-               // Examples: Win Vista, XP Silver, XP Olive , Win Classic Plum, OSX
-               // Aqua, OSX Graphite, Linux GTK
-               else if (testTwoPrimaryColors(listSelection, 120, 256)
-                               || (bg.red == 0 && bg.green == 0 && bg.blue == 0))
-                       rgb = blend(listSelection, listForeground, 50);
-               // Group 3
-               // When LIST_BACKGROUND = black (0, 0, 0), text colour = LIST_SELECTION
-               // @ 100% Opacity + 50% LIST_FOREGROUND over LIST_BACKGROUND
-               // Rule: If LIST_BACKGROUND = 0, 0, 0, then add 50% LIST_FOREGROUND to
-               // LIST_SELECTION foreground colour
-               // Examples: Win High Con Black, Win High Con #1, Win High Con #2
-               // (covered in the second part of the OR clause above)
-               createColor(IFormColors.TITLE, rgb);
-       }
-
-       private void createTwistieColors() {
-               RGB rgb = getColor(IFormColors.TITLE).getRGB();
-               RGB white = getSystemColor(SWT.COLOR_WHITE);
-               createColor(TB_TOGGLE, rgb);
-               rgb = blend(rgb, white, 60);
-               createColor(TB_TOGGLE_HOVER, rgb);
-       }
-
-       private void createTitleBarGradientColors() {
-               RGB tbBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
-               RGB bg = getImpliedBackground().getRGB();
-
-               // Group 1
-               // Rule: If at least 2 of the RGB values are equal to or between 180 and
-               // 255, then apply specified opacity for Group 1
-               // Examples: Vista, XP Silver, Wn High Con #2
-               // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
-               // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
-               if (testTwoPrimaryColors(tbBg, 179, 256))
-                       tbBg = blend(tbBg, bg, 30);
-
-               // Group 2
-               // Rule: If at least 2 of the RGB values are equal to or between 121 and
-               // 179, then apply specified opacity for Group 2
-               // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
-               // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND
-               // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
-               else if (testTwoPrimaryColors(tbBg, 120, 180))
-                       tbBg = blend(tbBg, bg, 20);
-
-               // Group 3
-               // Rule: Everything else
-               // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
-               // Aqua, Wn High Con White, Wn High Con #1
-               // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND
-               // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
-               else {
-                       tbBg = blend(tbBg, bg, 10);
-               }
-
-               createColor(IFormColors.TB_BG, tbBg);
-               
-               // for backward compatibility
-               createColor(TB_GBG, tbBg);
-       }
-
-       private void createTitleBarOutlineColors() {
-               // title bar outline - border color
-               RGB tbBorder = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
-               RGB bg = getImpliedBackground().getRGB();
-               // Group 1
-               // Rule: If at least 2 of the RGB values are equal to or between 180 and
-               // 255, then apply specified opacity for Group 1
-               // Examples: Vista, XP Silver, Wn High Con #2
-               // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND
-               if (testTwoPrimaryColors(tbBorder, 179, 256))
-                       tbBorder = blend(tbBorder, bg, 70);
-
-               // Group 2
-               // Rule: If at least 2 of the RGB values are equal to or between 121 and
-               // 179, then apply specified opacity for Group 2
-               // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
-
-               // Keyline = TITLE_BACKGROUND @ 50% Opacity over LIST_BACKGROUND
-               else if (testTwoPrimaryColors(tbBorder, 120, 180))
-                       tbBorder = blend(tbBorder, bg, 50);
-
-               // Group 3
-               // Rule: Everything else
-               // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
-               // Aqua, Wn High Con White, Wn High Con #1
-
-               // Keyline = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
-               else {
-                       tbBorder = blend(tbBorder, bg, 30);
-               }
-               createColor(FormColors.TB_BORDER, tbBorder);
-       }
-
-       private void updateFormHeaderColors() {
-               if (colorRegistry.containsKey(IFormColors.H_GRADIENT_END)) {
-                       disposeIfFound(IFormColors.H_GRADIENT_END);
-                       disposeIfFound(IFormColors.H_GRADIENT_START);
-                       disposeIfFound(IFormColors.H_BOTTOM_KEYLINE1);
-                       disposeIfFound(IFormColors.H_BOTTOM_KEYLINE2);
-                       disposeIfFound(IFormColors.H_HOVER_LIGHT);
-                       disposeIfFound(IFormColors.H_HOVER_FULL);
-                       initializeFormHeaderColors();
-               }
-       }
-
-       private void disposeIfFound(String key) {
-               Color color = getColor(key);
-               if (color != null) {
-                       colorRegistry.remove(key);
-               // RAP [rh] changes due to missing Color#dispose()                      
-//                     color.dispose();
-               }
-       }
-
-       private void createFormHeaderColors() {
-               createFormHeaderGradientColors();
-               createFormHeaderKeylineColors();
-               createFormHeaderDNDColors();
-       }
-
-       private void createFormHeaderGradientColors() {
-               RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
-               Color bgColor = getImpliedBackground();
-               RGB bg = bgColor.getRGB();
-               RGB bottom, top;
-               // Group 1
-               // Rule: If at least 2 of the RGB values are equal to or between 180 and
-               // 255, then apply specified opacity for Group 1
-               // Examples: Vista, XP Silver, Wn High Con #2
-               // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
-               // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
-               if (testTwoPrimaryColors(titleBg, 179, 256)) {
-                       bottom = blend(titleBg, bg, 30);
-                       top = bg;
-               }
-
-               // Group 2
-               // Rule: If at least 2 of the RGB values are equal to or between 121 and
-               // 179, then apply specified opacity for Group 2
-               // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
-               // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND
-               // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
-               else if (testTwoPrimaryColors(titleBg, 120, 180)) {
-                       bottom = blend(titleBg, bg, 20);
-                       top = bg;
-               }
-
-               // Group 3
-               // Rule: If at least 2 of the RGB values are equal to or between 0 and
-               // 120, then apply specified opacity for Group 3
-               // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
-               // Aqua, Wn High Con White, Wn High Con #1
-               // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND
-               // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
-               else {
-                       bottom = blend(titleBg, bg, 10);
-                       top = bg;
-               }
-               createColor(IFormColors.H_GRADIENT_END, top);
-               createColor(IFormColors.H_GRADIENT_START, bottom);
-       }
-
-       private void createFormHeaderKeylineColors() {
-               RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
-               Color bgColor = getImpliedBackground();
-               RGB bg = bgColor.getRGB();
-               RGB keyline2;
-               // H_BOTTOM_KEYLINE1
-               createColor(IFormColors.H_BOTTOM_KEYLINE1, new RGB(255, 255, 255));
-
-               // H_BOTTOM_KEYLINE2
-               // Group 1
-               // Rule: If at least 2 of the RGB values are equal to or between 180 and
-               // 255, then apply specified opacity for Group 1
-               // Examples: Vista, XP Silver, Wn High Con #2
-               // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND
-               if (testTwoPrimaryColors(titleBg, 179, 256))
-                       keyline2 = blend(titleBg, bg, 70);
-
-               // Group 2
-               // Rule: If at least 2 of the RGB values are equal to or between 121 and
-               // 179, then apply specified opacity for Group 2
-               // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
-               // Keyline = TITLE_BACKGROUND @ 50% Opacity over LIST_BACKGROUND
-               else if (testTwoPrimaryColors(titleBg, 120, 180))
-                       keyline2 = blend(titleBg, bg, 50);
-
-               // Group 3
-               // Rule: If at least 2 of the RGB values are equal to or between 0 and
-               // 120, then apply specified opacity for Group 3
-               // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
-               // Aqua, Wn High Con White, Wn High Con #1
-
-               // Keyline = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
-               else
-                       keyline2 = blend(titleBg, bg, 30);
-               // H_BOTTOM_KEYLINE2
-               createColor(IFormColors.H_BOTTOM_KEYLINE2, keyline2);
-       }
-
-       private void createFormHeaderDNDColors() {
-               RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT);
-               Color bgColor = getImpliedBackground();
-               RGB bg = bgColor.getRGB();
-               RGB light, full;
-               // ALL Themes
-               //
-               // Light Highlight
-               // When *near* the 'hot' area
-               // Rule: If near the title in the 'hot' area, show background highlight
-               // TITLE_BACKGROUND_GRADIENT @ 40%
-               light = blend(titleBg, bg, 40);
-               // Full Highlight
-               // When *on* the title area (regions 1 and 2)
-               // Rule: If near the title in the 'hot' area, show background highlight
-               // TITLE_BACKGROUND_GRADIENT @ 60%
-               full = blend(titleBg, bg, 60);
-               // H_DND_LIGHT
-               // H_DND_FULL
-               createColor(IFormColors.H_HOVER_LIGHT, light);
-               createColor(IFormColors.H_HOVER_FULL, full);
-       }
-       
-       private LocalResourceManager getResourceManager() {
-               if (resources == null)
-                       resources = new LocalResourceManager(JFaceResources.getResources());
-               return resources;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormFonts.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormFonts.java
deleted file mode 100644 (file)
index 9e931ba..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-import java.util.HashMap;
-
-import org.eclipse.jface.resource.DeviceResourceException;
-import org.eclipse.jface.resource.FontDescriptor;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.resource.LocalResourceManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Device;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-//import org.eclipse.swt.internal.graphics.Graphics;
-import org.eclipse.swt.widgets.Display;
-
-public class FormFonts {
-       private static FormFonts instance;
-
-       public static FormFonts getInstance() {
-               if (instance == null)
-                       instance = new FormFonts();
-               return instance;
-       }
-
-       private LocalResourceManager resources;
-       private HashMap descriptors;
-
-       private FormFonts() {
-       }
-
-       private class BoldFontDescriptor extends FontDescriptor {
-               private FontData[] fFontData;
-
-               BoldFontDescriptor(Font font) {
-                       // RAP [if] Changes due to different way of creating fonts
-                       // fFontData = font.getFontData();
-                       // for (int i = 0; i < fFontData.length; i++) {
-                       // fFontData[i].setStyle(fFontData[i].getStyle() | SWT.BOLD);
-                       // }
-                       FontData fontData = font.getFontData()[0];
-                       // Font boldFont = Graphics.getFont( fontData.getName(),
-                       // fontData.getHeight(),
-                       // fontData.getStyle() | SWT.BOLD );
-                       Font boldFont = new Font(Display.getCurrent(), fontData.getName(), fontData.getHeight(),
-                                       fontData.getStyle() | SWT.BOLD);
-                       fFontData = boldFont.getFontData();
-               }
-
-               public boolean equals(Object obj) {
-                       if (obj instanceof BoldFontDescriptor) {
-                               BoldFontDescriptor desc = (BoldFontDescriptor) obj;
-                               if (desc.fFontData.length != fFontData.length)
-                                       return false;
-                               for (int i = 0; i < fFontData.length; i++)
-                                       if (!fFontData[i].equals(desc.fFontData[i]))
-                                               return false;
-                               return true;
-                       }
-                       return false;
-               }
-
-               public int hashCode() {
-                       int hash = 0;
-                       for (int i = 0; i < fFontData.length; i++)
-                               hash = hash * 7 + fFontData[i].hashCode();
-                       return hash;
-               }
-
-               public Font createFont(Device device) throws DeviceResourceException {
-                       // RAP [if] Changes due to different way of creating fonts
-                       return new Font(device, fFontData[0]);
-                       // return Graphics.getFont( fFontData[ 0 ] );
-               }
-
-               public void destroyFont(Font previouslyCreatedFont) {
-                       // RAP [if] unnecessary
-                       // previouslyCreatedFont.dispose();
-               }
-       }
-
-       public Font getBoldFont(Display display, Font font) {
-               checkHashMaps();
-               BoldFontDescriptor desc = new BoldFontDescriptor(font);
-               Font result = getResourceManager().createFont(desc);
-               descriptors.put(result, desc);
-               return result;
-       }
-
-       public boolean markFinished(Font boldFont) {
-               checkHashMaps();
-               BoldFontDescriptor desc = (BoldFontDescriptor) descriptors.get(boldFont);
-               if (desc != null) {
-                       getResourceManager().destroyFont(desc);
-                       if (getResourceManager().find(desc) == null) {
-                               descriptors.remove(boldFont);
-                               validateHashMaps();
-                       }
-                       return true;
-
-               }
-               // if the image was not found, dispose of it for the caller
-               // RAP [if] unnecessary
-               // boldFont.dispose();
-               return false;
-       }
-
-       private LocalResourceManager getResourceManager() {
-               if (resources == null)
-                       resources = new LocalResourceManager(JFaceResources.getResources());
-               return resources;
-       }
-
-       private void checkHashMaps() {
-               if (descriptors == null)
-                       descriptors = new HashMap();
-       }
-
-       private void validateHashMaps() {
-               if (descriptors.size() == 0)
-                       descriptors = null;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormToolkit.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormToolkit.java
deleted file mode 100644 (file)
index 9927104..0000000
+++ /dev/null
@@ -1,913 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-//import org.eclipse.swt.custom.CCombo;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.FocusAdapter;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-// RAP [rh] Paint events missing
-//import org.eclipse.swt.events.PaintEvent;
-//import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-//RAP [rh] GC missing
-//import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Point;
-//import org.eclipse.swt.graphics.RGB;
-//import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-//import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-//import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.Widget;
-//import org.eclipse.ui.forms.FormColors;
-//import org.eclipse.ui.forms.HyperlinkGroup;
-//import org.eclipse.ui.forms.IFormColors;
-//import org.eclipse.ui.internal.forms.widgets.FormFonts;
-//import org.eclipse.ui.internal.forms.widgets.FormUtil;
-
-/**
- * The toolkit is responsible for creating SWT controls adapted to work in
- * Eclipse forms. In addition to changing their presentation properties (fonts,
- * colors etc.), various listeners are attached to make them behave correctly in
- * the form context.
- * <p>
- * In addition to being the control factory, the toolkit is also responsible for
- * painting flat borders for select controls, managing hyperlink groups and
- * control colors.
- * <p>
- * The toolkit creates some of the most common controls used to populate Eclipse
- * forms. Controls that must be created using their constructors,
- * <code>adapt()</code> method is available to change its properties in the
- * same way as with the supported toolkit controls.
- * <p>
- * Typically, one toolkit object is created per workbench part (for example, an
- * editor or a form wizard). The toolkit is disposed when the part is disposed.
- * To conserve resources, it is possible to create one color object for the
- * entire plug-in and share it between several toolkits. The plug-in is
- * responsible for disposing the colors (disposing the toolkit that uses shared
- * color object will not dispose the colors).
- * <p>
- * FormToolkit is normally instantiated, but can also be subclassed if some of
- * the methods needs to be modified. In those cases, <code>super</code> must
- * be called to preserve normal behaviour.
- *
- * @since 1.0
- */
-public class FormToolkit {
-       public static final String KEY_DRAW_BORDER = "FormWidgetFactory.drawBorder"; //$NON-NLS-1$
-
-       public static final String TREE_BORDER = "treeBorder"; //$NON-NLS-1$
-
-       public static final String TEXT_BORDER = "textBorder"; //$NON-NLS-1$
-
-       private int borderStyle = SWT.NULL;
-
-       private FormColors colors;
-
-       private int orientation = Window.getDefaultOrientation();
-
-       // private KeyListener deleteListener;
-       // RAP [rh] Paint events missing
-//     private BorderPainter borderPainter;
-
-       private BoldFontHolder boldFontHolder;
-
-//     private HyperlinkGroup hyperlinkGroup;
-       
-       private boolean isDisposed = false;
-
-       /* default */
-       VisibilityHandler visibilityHandler;
-
-       /* default */
-       KeyboardHandler keyboardHandler;
-
-       // RAP [rh] Paint events missing
-//     private class BorderPainter implements PaintListener {
-//             public void paintControl(PaintEvent event) {
-//                     Composite composite = (Composite) event.widget;
-//                     Control[] children = composite.getChildren();
-//                     for (int i = 0; i < children.length; i++) {
-//                             Control c = children[i];
-//                             boolean inactiveBorder = false;
-//                             boolean textBorder = false;
-//                             if (!c.isVisible())
-//                                     continue;
-//                             /*
-//                              * if (c.getEnabled() == false && !(c instanceof CCombo))
-//                              * continue;
-//                              */
-//                             if (c instanceof Hyperlink)
-//                                     continue;
-//                             Object flag = c.getData(KEY_DRAW_BORDER);
-//                             if (flag != null) {
-//                                     if (flag.equals(Boolean.FALSE))
-//                                             continue;
-//                                     if (flag.equals(TREE_BORDER))
-//                                             inactiveBorder = true;
-//                                     else if (flag.equals(TEXT_BORDER))
-//                                             textBorder = true;
-//                             }
-//                             if (getBorderStyle() == SWT.BORDER) {
-//                                     if (!inactiveBorder && !textBorder) {
-//                                             continue;
-//                                     }
-//                                     if (c instanceof Text || c instanceof Table
-//                                                     || c instanceof Tree)
-//                                             continue;
-//                             }
-//                             if (!inactiveBorder
-//                                             && (c instanceof Text || c instanceof CCombo || textBorder)) {
-//                                     Rectangle b = c.getBounds();
-//                                     GC gc = event.gc;
-//                                     gc.setForeground(c.getBackground());
-//                                     gc.drawRectangle(b.x - 1, b.y - 1, b.width + 1,
-//                                                     b.height + 1);
-//                                     // gc.setForeground(getBorderStyle() == SWT.BORDER ? colors
-//                                     // .getBorderColor() : colors.getForeground());
-//                                     gc.setForeground(colors.getBorderColor());
-//                                     if (c instanceof CCombo)
-//                                             gc.drawRectangle(b.x - 1, b.y - 1, b.width + 1,
-//                                                             b.height + 1);
-//                                     else
-//                                             gc.drawRectangle(b.x - 1, b.y - 2, b.width + 1,
-//                                                             b.height + 3);
-//                             } else if (inactiveBorder || c instanceof Table
-//                                             || c instanceof Tree) {
-//                                     Rectangle b = c.getBounds();
-//                                     GC gc = event.gc;
-//                                     gc.setForeground(colors.getBorderColor());
-//                                     gc.drawRectangle(b.x - 1, b.y - 1, b.width + 1,
-//                                                     b.height + 1);
-//                             }
-//                     }
-//             }
-//     }
-
-       private static class VisibilityHandler extends FocusAdapter {
-               public void focusGained(FocusEvent e) {
-                       Widget w = e.widget;
-                       if (w instanceof Control) {
-                               FormUtil.ensureVisible((Control) w);
-                       }
-               }
-       }
-
-       private static class KeyboardHandler extends KeyAdapter {
-               public void keyPressed(KeyEvent e) {
-                       Widget w = e.widget;
-                       if (w instanceof Control) {
-                               if (e.doit)
-                                       FormUtil.processKey(e.keyCode, (Control) w);
-                       }
-               }
-       }
-
-       private class BoldFontHolder {
-               private Font normalFont;
-
-               private Font boldFont;
-
-               public BoldFontHolder() {
-               }
-
-               public Font getBoldFont(Font font) {
-                       createBoldFont(font);
-                       return boldFont;
-               }
-
-               private void createBoldFont(Font font) {
-                       if (normalFont == null || !normalFont.equals(font)) {
-                               normalFont = font;
-                               dispose();
-                       }
-                       if (boldFont == null) {
-                               boldFont = FormFonts.getInstance().getBoldFont(colors.getDisplay(),
-                                               normalFont);
-                       }
-               }
-
-               public void dispose() {
-                       if (boldFont != null) {
-                               FormFonts.getInstance().markFinished(boldFont);
-                               boldFont = null;
-                       }
-               }
-       }
-
-       /**
-        * Creates a toolkit that is self-sufficient (will manage its own colors).
-        * <p>
-        * Clients that call this method must call {@link #dispose()} when they
-        * are finished using the toolkit.
-        *
-        */
-       public FormToolkit(Display display) {
-               this(new FormColors(display));
-       }
-
-       /**
-        * Creates a toolkit that will use the provided (shared) colors. The toolkit
-        * will dispose the colors if and only if they are <b>not</b> marked as
-        * shared via the <code>markShared()</code> method.
-        * <p>
-        * Clients that call this method must call {@link #dispose()} when they
-        * are finished using the toolkit.
-        *
-        * @param colors
-        *            the shared colors
-        */
-       public FormToolkit(FormColors colors) {
-               this.colors = colors;
-               initialize();
-       }
-
-       /**
-        * Creates a button as a part of the form.
-        *
-        * @param parent
-        *            the button parent
-        * @param text
-        *            an optional text for the button (can be <code>null</code>)
-        * @param style
-        *            the button style (for example, <code>SWT.PUSH</code>)
-        * @return the button widget
-        */
-       public Button createButton(Composite parent, String text, int style) {
-               Button button = new Button(parent, style | SWT.FLAT | orientation);
-               if (text != null)
-                       button.setText(text);
-               adapt(button, true, true);
-               return button;
-       }
-
-       /**
-        * Creates the composite as a part of the form.
-        *
-        * @param parent
-        *            the composite parent
-        * @return the composite widget
-        */
-       public Composite createComposite(Composite parent) {
-               return createComposite(parent, SWT.NULL);
-       }
-
-       /**
-        * Creates the composite as part of the form using the provided style.
-        *
-        * @param parent
-        *            the composite parent
-        * @param style
-        *            the composite style
-        * @return the composite widget
-        */
-       public Composite createComposite(Composite parent, int style) {
-//             Composite composite = new LayoutComposite(parent, style | orientation);
-               Composite composite = new Composite(parent, style | orientation);
-               adapt(composite);
-               return composite;
-       }
-
-       /**
-        * Creats the composite that can server as a separator between various parts
-        * of a form. Separator height should be controlled by setting the height
-        * hint on the layout data for the composite.
-        *
-        * @param parent
-        *            the separator parent
-        * @return the separator widget
-        */
-// RAP [rh] createCompositeSeparator: currently no useful implementation possible, delete?
-       public Composite createCompositeSeparator(Composite parent) {
-               final Composite composite = new Composite(parent, orientation);
-// RAP [rh] GC and paint events missing
-//             composite.addListener(SWT.Paint, new Listener() {
-//                     public void handleEvent(Event e) {
-//                             if (composite.isDisposed())
-//                                     return;
-//                             Rectangle bounds = composite.getBounds();
-//                             GC gc = e.gc;
-//                             gc.setForeground(colors.getColor(IFormColors.SEPARATOR));
-//                             if (colors.getBackground() != null)
-//                                     gc.setBackground(colors.getBackground());
-//                             gc.fillGradientRectangle(0, 0, bounds.width, bounds.height,
-//                                             false);
-//                     }
-//             });
-//             if (parent instanceof Section)
-//                     ((Section) parent).setSeparatorControl(composite);
-               return composite;
-       }
-
-       /**
-        * Creates a label as a part of the form.
-        *
-        * @param parent
-        *            the label parent
-        * @param text
-        *            the label text
-        * @return the label widget
-        */
-       public Label createLabel(Composite parent, String text) {
-               return createLabel(parent, text, SWT.NONE);
-       }
-
-       /**
-        * Creates a label as a part of the form.
-        *
-        * @param parent
-        *            the label parent
-        * @param text
-        *            the label text
-        * @param style
-        *            the label style
-        * @return the label widget
-        */
-       public Label createLabel(Composite parent, String text, int style) {
-               Label label = new Label(parent, style | orientation);
-               if (text != null)
-                       label.setText(text);
-               adapt(label, false, false);
-               return label;
-       }
-
-       /**
-        * Creates a hyperlink as a part of the form. The hyperlink will be added to
-        * the hyperlink group that belongs to this toolkit.
-        *
-        * @param parent
-        *            the hyperlink parent
-        * @param text
-        *            the text of the hyperlink
-        * @param style
-        *            the hyperlink style
-        * @return the hyperlink widget
-        */
-//     public Hyperlink createHyperlink(Composite parent, String text, int style) {
-//             Hyperlink hyperlink = new Hyperlink(parent, style | orientation);
-//             if (text != null)
-//                     hyperlink.setText(text);
-//             hyperlink.addFocusListener(visibilityHandler);
-//             hyperlink.addKeyListener(keyboardHandler);
-//             hyperlinkGroup.add(hyperlink);
-//             return hyperlink;
-//     }
-
-       /**
-        * Creates an image hyperlink as a part of the form. The hyperlink will be
-        * added to the hyperlink group that belongs to this toolkit.
-        *
-        * @param parent
-        *            the hyperlink parent
-        * @param style
-        *            the hyperlink style
-        * @return the image hyperlink widget
-        */
-//     public ImageHyperlink createImageHyperlink(Composite parent, int style) {
-//             ImageHyperlink hyperlink = new ImageHyperlink(parent, style
-//                             | orientation);
-//             hyperlink.addFocusListener(visibilityHandler);
-//             hyperlink.addKeyListener(keyboardHandler);
-//             hyperlinkGroup.add(hyperlink);
-//             return hyperlink;
-//     }
-
-       /**
-        * Creates a rich text as a part of the form.
-        *
-        * @param parent
-        *            the rich text parent
-        * @param trackFocus
-        *            if <code>true</code>, the toolkit will monitor focus
-        *            transfers to ensure that the hyperlink in focus is visible in
-        *            the form.
-        * @return the rich text widget
-        * @since 1.2
-        */
-//     public FormText createFormText(Composite parent, boolean trackFocus) {
-//             FormText engine = new FormText(parent, SWT.WRAP | orientation);
-//             engine.marginWidth = 1;
-//             engine.marginHeight = 0;
-//             engine.setHyperlinkSettings(getHyperlinkGroup());
-//             adapt(engine, trackFocus, true);
-//             engine.setMenu(parent.getMenu());
-//             return engine;
-//     }
-
-       /**
-        * Adapts a control to be used in a form that is associated with this
-        * toolkit. This involves adjusting colors and optionally adding handlers to
-        * ensure focus tracking and keyboard management.
-        *
-        * @param control
-        *            a control to adapt
-        * @param trackFocus
-        *            if <code>true</code>, form will be scrolled horizontally
-        *            and/or vertically if needed to ensure that the control is
-        *            visible when it gains focus. Set it to <code>false</code> if
-        *            the control is not capable of gaining focus.
-        * @param trackKeyboard
-        *            if <code>true</code>, the control that is capable of
-        *            gaining focus will be tracked for certain keys that are
-        *            important to the underlying form (for example, PageUp,
-        *            PageDown, ScrollUp, ScrollDown etc.). Set it to
-        *            <code>false</code> if the control is not capable of gaining
-        *            focus or these particular key event are already used by the
-        *            control.
-        */
-       public void adapt(Control control, boolean trackFocus, boolean trackKeyboard) {
-               control.setBackground(colors.getBackground());
-               control.setForeground(colors.getForeground());
-//             if (control instanceof ExpandableComposite) {
-//                     ExpandableComposite ec = (ExpandableComposite) control;
-//                     if (ec.toggle != null) {
-//                             if (trackFocus)
-//                                     ec.toggle.addFocusListener(visibilityHandler);
-//                             if (trackKeyboard)
-//                                     ec.toggle.addKeyListener(keyboardHandler);
-//                     }
-//                     if (ec.textLabel != null) {
-//                             if (trackFocus)
-//                                     ec.textLabel.addFocusListener(visibilityHandler);
-//                             if (trackKeyboard)
-//                                     ec.textLabel.addKeyListener(keyboardHandler);
-//                     }
-//                     return;
-//             }
-               if (trackFocus)
-                       control.addFocusListener(visibilityHandler);
-               if (trackKeyboard)
-                       control.addKeyListener(keyboardHandler);
-       }
-
-       /**
-        * Adapts a composite to be used in a form associated with this toolkit.
-        *
-        * @param composite
-        *            the composite to adapt
-        */
-       public void adapt(Composite composite) {
-               composite.setBackground(colors.getBackground());
-               composite.addMouseListener(new MouseAdapter() {
-                       public void mouseDown(MouseEvent e) {
-                               ((Control) e.widget).setFocus();
-                       }
-               });
-               if (composite.getParent() != null)
-                       composite.setMenu(composite.getParent().getMenu());
-       }
-
-       /**
-        * A helper method that ensures the provided control is visible when
-        * ScrolledComposite is somewhere in the parent chain. If scroll bars are
-        * visible and the control is clipped, the client of the scrolled composite
-        * will be scrolled to reveal the control.
-        *
-        * @param c
-        *            the control to reveal
-        */
-       public static void ensureVisible(Control c) {
-               FormUtil.ensureVisible(c);
-       }
-
-       /**
-        * Creates a section as a part of the form.
-        *
-        * @param parent
-        *            the section parent
-        * @param sectionStyle
-        *            the section style
-        * @return the section widget
-        */
-//     public Section createSection(Composite parent, int sectionStyle) {
-//             Section section = new Section(parent, orientation, sectionStyle);
-//             section.setMenu(parent.getMenu());
-//             adapt(section, true, true);
-//             if (section.toggle != null) {
-//                     section.toggle.setHoverDecorationColor(colors
-//                                     .getColor(IFormColors.TB_TOGGLE_HOVER));
-//                     section.toggle.setDecorationColor(colors
-//                                     .getColor(IFormColors.TB_TOGGLE));
-//             }
-//             section.setFont(boldFontHolder.getBoldFont(parent.getFont()));
-//             if ((sectionStyle & Section.TITLE_BAR) != 0
-//                             || (sectionStyle & Section.SHORT_TITLE_BAR) != 0) {
-//                     colors.initializeSectionToolBarColors();
-//                     section.setTitleBarBackground(colors.getColor(IFormColors.TB_BG));
-//                     section.setTitleBarBorderColor(colors
-//                                     .getColor(IFormColors.TB_BORDER));
-//             }
-//             // call setTitleBarForeground regardless as it also sets the label color
-//             section.setTitleBarForeground(colors
-//                             .getColor(IFormColors.TB_TOGGLE));
-//             return section;
-//     }
-
-       /**
-        * Creates an expandable composite as a part of the form.
-        *
-        * @param parent
-        *            the expandable composite parent
-        * @param expansionStyle
-        *            the expandable composite style
-        * @return the expandable composite widget
-        */
-//     public ExpandableComposite createExpandableComposite(Composite parent,
-//                     int expansionStyle) {
-//             ExpandableComposite ec = new ExpandableComposite(parent, orientation,
-//                             expansionStyle);
-//             ec.setMenu(parent.getMenu());
-//             adapt(ec, true, true);
-//             ec.setFont(boldFontHolder.getBoldFont(ec.getFont()));
-//             return ec;
-//     }
-
-       /**
-        * Creates a separator label as a part of the form.
-        *
-        * @param parent
-        *            the separator parent
-        * @param style
-        *            the separator style
-        * @return the separator label
-        */
-       public Label createSeparator(Composite parent, int style) {
-               Label label = new Label(parent, SWT.SEPARATOR | style | orientation);
-               label.setBackground(colors.getBackground());
-               label.setForeground(colors.getBorderColor());
-               return label;
-       }
-
-       /**
-        * Creates a table as a part of the form.
-        *
-        * @param parent
-        *            the table parent
-        * @param style
-        *            the table style
-        * @return the table widget
-        */
-       public Table createTable(Composite parent, int style) {
-               Table table = new Table(parent, style | borderStyle | orientation);
-               adapt(table, false, false);
-               // hookDeleteListener(table);
-               return table;
-       }
-
-       /**
-        * Creates a text as a part of the form.
-        *
-        * @param parent
-        *            the text parent
-        * @param value
-        *            the text initial value
-        * @return the text widget
-        */
-       public Text createText(Composite parent, String value) {
-               return createText(parent, value, SWT.SINGLE);
-       }
-
-       /**
-        * Creates a text as a part of the form.
-        *
-        * @param parent
-        *            the text parent
-        * @param value
-        *            the text initial value
-        * @param style
-        *            the text style
-        * @return the text widget
-        */
-       public Text createText(Composite parent, String value, int style) {
-               Text text = new Text(parent, borderStyle | style | orientation);
-               if (value != null)
-                       text.setText(value);
-               text.setForeground(colors.getForeground());
-               text.setBackground(colors.getBackground());
-               text.addFocusListener(visibilityHandler);
-               return text;
-       }
-
-       /**
-        * Creates a tree widget as a part of the form.
-        *
-        * @param parent
-        *            the tree parent
-        * @param style
-        *            the tree style
-        * @return the tree widget
-        */
-       public Tree createTree(Composite parent, int style) {
-               Tree tree = new Tree(parent, borderStyle | style | orientation);
-               adapt(tree, false, false);
-               // hookDeleteListener(tree);
-               return tree;
-       }
-
-       /**
-        * Creates a scrolled form widget in the provided parent. If you do not
-        * require scrolling because there is already a scrolled composite up the
-        * parent chain, use 'createForm' instead.
-        *
-        * @param parent
-        *            the scrolled form parent
-        * @return the form that can scroll itself
-        * @see #createForm
-        */
-       public ScrolledComposite createScrolledForm(Composite parent) {
-               ScrolledComposite form = new ScrolledComposite(parent, SWT.V_SCROLL
-                               | SWT.H_SCROLL | orientation);
-               form.setExpandHorizontal(true);
-               form.setExpandVertical(true);
-               form.setBackground(colors.getBackground());
-               form.setForeground(colors.getColor(IFormColors.TITLE));
-               form.setFont(JFaceResources.getHeaderFont());
-               return form;
-       }
-
-       /**
-        * Creates a form widget in the provided parent. Note that this widget does
-        * not scroll its content, so make sure there is a scrolled composite up the
-        * parent chain. If you require scrolling, use 'createScrolledForm' instead.
-        *
-        * @param parent
-        *            the form parent
-        * @return the form that does not scroll
-        * @see #createScrolledForm
-        */
-//     public Form createForm(Composite parent) {
-//             Form formContent = new Form(parent, orientation);
-//             formContent.setBackground(colors.getBackground());
-//             formContent.setForeground(colors.getColor(IFormColors.TITLE));
-//             formContent.setFont(JFaceResources.getHeaderFont());
-//             return formContent;
-//     }
-
-       /**
-        * Takes advantage of the gradients and other capabilities to decorate the
-        * form heading using colors computed based on the current skin and
-        * operating system.
-        *
-        * @param form
-        *            the form to decorate
-        */
-
-//     public void decorateFormHeading(Form form) {
-//             Color top = colors.getColor(IFormColors.H_GRADIENT_END);
-//             Color bot = colors.getColor(IFormColors.H_GRADIENT_START);
-//             form.setTextBackground(new Color[] { top, bot }, new int[] { 100 },
-//                             true);
-//             form.setHeadColor(IFormColors.H_BOTTOM_KEYLINE1, colors
-//                             .getColor(IFormColors.H_BOTTOM_KEYLINE1));
-//             form.setHeadColor(IFormColors.H_BOTTOM_KEYLINE2, colors
-//                             .getColor(IFormColors.H_BOTTOM_KEYLINE2));
-//             form.setHeadColor(IFormColors.H_HOVER_LIGHT, colors
-//                             .getColor(IFormColors.H_HOVER_LIGHT));
-//             form.setHeadColor(IFormColors.H_HOVER_FULL, colors
-//                             .getColor(IFormColors.H_HOVER_FULL));
-//             form.setHeadColor(IFormColors.TB_TOGGLE, colors
-//                             .getColor(IFormColors.TB_TOGGLE));
-//             form.setHeadColor(IFormColors.TB_TOGGLE_HOVER, colors
-//                             .getColor(IFormColors.TB_TOGGLE_HOVER));
-//             form.setSeparatorVisible(true);
-//     }
-
-       /**
-        * Creates a scrolled page book widget as a part of the form.
-        *
-        * @param parent
-        *            the page book parent
-        * @param style
-        *            the text style
-        * @return the scrolled page book widget
-        */
-//     public ScrolledPageBook createPageBook(Composite parent, int style) {
-//             ScrolledPageBook book = new ScrolledPageBook(parent, style
-//                             | orientation);
-//             adapt(book, true, true);
-//             book.setMenu(parent.getMenu());
-//             return book;
-//     }
-
-       /**
-        * Disposes the toolkit.
-        */
-       public void dispose() {
-               if (isDisposed) {
-                       return;
-               }
-               isDisposed = true;
-               if (colors.isShared() == false) {
-                       colors.dispose();
-                       colors = null;
-               }
-               boldFontHolder.dispose();
-       }
-
-       /**
-        * Returns the hyperlink group that manages hyperlinks for this toolkit.
-        *
-        * @return the hyperlink group
-        */
-//     public HyperlinkGroup getHyperlinkGroup() {
-//             return hyperlinkGroup;
-//     }
-
-       /**
-        * Sets the background color for the entire toolkit. The method delegates
-        * the call to the FormColors object and also updates the hyperlink group so
-        * that hyperlinks and other objects are in sync.
-        *
-        * @param bg
-        *            the new background color
-        */
-       public void setBackground(Color bg) {
-//             hyperlinkGroup.setBackground(bg);
-               colors.setBackground(bg);
-       }
-
-       /**
-        * Refreshes the hyperlink colors by loading from JFace settings.
-        */
-//     public void refreshHyperlinkColors() {
-//             hyperlinkGroup.initializeDefaultForegrounds(colors.getDisplay());
-//     }
-
-// RAP [rh] paintBordersFor not useful as no GC to actually paint borders
-//     /**
-//      * Paints flat borders for widgets created by this toolkit within the
-//      * provided parent. Borders will not be painted if the global border style
-//      * is SWT.BORDER (i.e. if native borders are used). Call this method during
-//      * creation of a form composite to get the borders of its children painted.
-//      * Care should be taken when selection layout margins. At least one pixel
-//      * pargin width and height must be chosen to allow the toolkit to paint the
-//      * border on the parent around the widgets.
-//      * <p>
-//      * Borders are painted for some controls that are selected by the toolkit by
-//      * default. If a control needs a border but is not on its list, it is
-//      * possible to force border in the following way:
-//      *
-//      * <pre>
-//      *
-//      *
-//      *
-//      *             widget.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER);
-//      *
-//      *             or
-//      *
-//      *             widget.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-//      *
-//      *
-//      *
-//      * </pre>
-//      *
-//      * @param parent
-//      *            the parent that owns the children for which the border needs
-//      *            to be painted.
-//      */
-//     public void paintBordersFor(Composite parent) {
-//             // if (borderStyle == SWT.BORDER)
-//             // return;
-//             if (borderPainter == null)
-//                     borderPainter = new BorderPainter();
-//             parent.addPaintListener(borderPainter);
-//     }
-
-       /**
-        * Returns the colors used by this toolkit.
-        *
-        * @return the color object
-        */
-       public FormColors getColors() {
-               return colors;
-       }
-
-       /**
-        * Returns the border style used for various widgets created by this
-        * toolkit. The intent of the toolkit is to create controls with styles that
-        * yield a 'flat' appearance. On systems where the native borders are
-        * already flat, we set the style to SWT.BORDER and don't paint the borders
-        * ourselves. Otherwise, the style is set to SWT.NULL, and borders are
-        * painted by the toolkit.
-        *
-        * @return the global border style
-        */
-       public int getBorderStyle() {
-               return borderStyle;
-       }
-
-       /**
-        * Returns the margin required around the children whose border is being
-        * painted by the toolkit using {@link #paintBordersFor(Composite)}. Since
-        * the border is painted around the controls on the parent, a number of
-        * pixels needs to be reserved for this border. For windowing systems where
-        * the native border is used, this margin is 0.
-        *
-        * @return the margin in the parent when children have their border painted
-        */
-       public int getBorderMargin() {
-               return getBorderStyle() == SWT.BORDER ? 0 : 2;
-       }
-
-       /**
-        * Sets the border style to be used when creating widgets. The toolkit
-        * chooses the correct style based on the platform but this value can be
-        * changed using this method.
-        *
-        * @param style
-        *            <code>SWT.BORDER</code> or <code>SWT.NULL</code>
-        * @see #getBorderStyle
-        */
-       public void setBorderStyle(int style) {
-               this.borderStyle = style;
-       }
-
-       /**
-        * A utility method that ensures that the control is visible in the scrolled
-        * composite. The prerequisite for this method is that the control has a
-        * class that extends ScrolledComposite somewhere in the parent chain. If
-        * the control is partially or fully clipped, the composite is scrolled to
-        * set by setting the origin to the control origin.
-        *
-        * @param c
-        *            the control to make visible
-        * @param verticalOnly
-        *            if <code>true</code>, the scrolled composite will be
-        *            scrolled only vertically if needed. Otherwise, the scrolled
-        *            composite origin will be set to the control origin.
-        */
-       public static void setControlVisible(Control c, boolean verticalOnly) {
-               ScrolledComposite scomp = FormUtil.getScrolledComposite(c);
-               if (scomp == null)
-                       return;
-               Point location = FormUtil.getControlLocation(scomp, c);
-               scomp.setOrigin(location);
-       }
-
-       private void initialize() {
-               initializeBorderStyle();
-//             hyperlinkGroup = new HyperlinkGroup(colors.getDisplay());
-//             hyperlinkGroup.setBackground(colors.getBackground());
-               visibilityHandler = new VisibilityHandler();
-               keyboardHandler = new KeyboardHandler();
-               boldFontHolder = new BoldFontHolder();
-       }
-
-// RAP [rh] revise detection of border style: can't ask OS here
-       private void initializeBorderStyle() {
-//             String osname = System.getProperty("os.name"); //$NON-NLS-1$
-//             String osversion = System.getProperty("os.version"); //$NON-NLS-1$
-//             if (osname.startsWith("Windows") && "5.1".compareTo(osversion) <= 0) { //$NON-NLS-1$ //$NON-NLS-2$
-//                     // Skinned widgets used on newer Windows (e.g. XP (5.1), Vista
-//                     // (6.0))
-//                     // Check for Windows Classic. If not used, set the style to BORDER
-//                     RGB rgb = colors.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
-//                     if (rgb.red != 212 || rgb.green != 208 || rgb.blue != 200)
-//                             borderStyle = SWT.BORDER;
-//             } else if (osname.startsWith("Mac")) //$NON-NLS-1$
-//                     borderStyle = SWT.BORDER;
-
-               borderStyle = SWT.BORDER;
-       }
-
-       /**
-        * Returns the orientation that all the widgets created by this toolkit will
-        * inherit, if set. Can be <code>SWT.NULL</code>,
-        * <code>SWT.LEFT_TO_RIGHT</code> and <code>SWT.RIGHT_TO_LEFT</code>.
-        *
-        * @return orientation style for this toolkit, or <code>SWT.NULL</code> if
-        *         not set. The default orientation is inherited from the Window
-        *         default orientation.
-        * @see org.eclipse.jface.window.Window#getDefaultOrientation()
-        */
-
-       public int getOrientation() {
-               return orientation;
-       }
-
-       /**
-        * Sets the orientation that all the widgets created by this toolkit will
-        * inherit. Can be <code>SWT.NULL</code>, <code>SWT.LEFT_TO_RIGHT</code>
-        * and <code>SWT.RIGHT_TO_LEFT</code>.
-        *
-        * @param orientation
-        *            style for this toolkit.
-        */
-
-       public void setOrientation(int orientation) {
-               this.orientation = orientation;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormUtil.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormUtil.java
deleted file mode 100644 (file)
index 76e3f11..0000000
+++ /dev/null
@@ -1,522 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.MouseEvent;
-//import org.eclipse.swt.graphics.Device;
-import org.eclipse.swt.graphics.FontMetrics;
-import org.eclipse.swt.graphics.GC;
-//import org.eclipse.swt.graphics.Image;
-//import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Layout;
-//import org.eclipse.swt.widgets.ScrollBar;
-import org.eclipse.swt.widgets.Text;
-//import org.eclipse.ui.forms.widgets.ColumnLayout;
-//import org.eclipse.ui.forms.widgets.Form;
-//import org.eclipse.ui.forms.widgets.FormText;
-//import org.eclipse.ui.forms.widgets.FormToolkit;
-//import org.eclipse.ui.forms.widgets.ILayoutExtension;
-//
-//import com.ibm.icu.text.BreakIterator;
-
-public class FormUtil {
-       public static final String PLUGIN_ID = "org.eclipse.ui.forms"; //$NON-NLS-1$
-
-       static final int H_SCROLL_INCREMENT = 5;
-
-       static final int V_SCROLL_INCREMENT = 64;
-
-       public static final String DEBUG = PLUGIN_ID + "/debug"; //$NON-NLS-1$
-
-       public static final String DEBUG_TEXT = DEBUG + "/text"; //$NON-NLS-1$
-       public static final String DEBUG_TEXTSIZE = DEBUG + "/textsize"; //$NON-NLS-1$
-
-       public static final String DEBUG_FOCUS = DEBUG + "/focus"; //$NON-NLS-1$
-
-       public static final String FOCUS_SCROLLING = "focusScrolling"; //$NON-NLS-1$
-       
-       public static final String IGNORE_BODY = "__ignore_body__"; //$NON-NLS-1$
-
-       public static Text createText(Composite parent, String label,
-                       FormToolkit factory) {
-               return createText(parent, label, factory, 1);
-       }
-
-       public static Text createText(Composite parent, String label,
-                       FormToolkit factory, int span) {
-               factory.createLabel(parent, label);
-               Text text = factory.createText(parent, ""); //$NON-NLS-1$
-               int hfill = span == 1 ? GridData.FILL_HORIZONTAL
-                               : GridData.HORIZONTAL_ALIGN_FILL;
-               GridData gd = new GridData(hfill | GridData.VERTICAL_ALIGN_CENTER);
-               gd.horizontalSpan = span;
-               text.setLayoutData(gd);
-               return text;
-       }
-
-       public static Text createText(Composite parent, String label,
-                       FormToolkit factory, int span, int style) {
-               Label l = factory.createLabel(parent, label);
-               if ((style & SWT.MULTI) != 0) {
-                       GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
-                       l.setLayoutData(gd);
-               }
-               Text text = factory.createText(parent, "", style); //$NON-NLS-1$
-               int hfill = span == 1 ? GridData.FILL_HORIZONTAL
-                               : GridData.HORIZONTAL_ALIGN_FILL;
-               GridData gd = new GridData(hfill | GridData.VERTICAL_ALIGN_CENTER);
-               gd.horizontalSpan = span;
-               text.setLayoutData(gd);
-               return text;
-       }
-
-       public static Text createText(Composite parent, FormToolkit factory,
-                       int span) {
-               Text text = factory.createText(parent, ""); //$NON-NLS-1$
-               int hfill = span == 1 ? GridData.FILL_HORIZONTAL
-                               : GridData.HORIZONTAL_ALIGN_FILL;
-               GridData gd = new GridData(hfill | GridData.VERTICAL_ALIGN_CENTER);
-               gd.horizontalSpan = span;
-               text.setLayoutData(gd);
-               return text;
-       }
-
-       public static int computeMinimumWidth(GC gc, String text) {
-//             BreakIterator wb = BreakIterator.getWordInstance();
-//             wb.setText(text);
-//             int last = 0;
-//
-//             int width = 0;
-//
-//             for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) {
-//                     String word = text.substring(last, loc);
-//                     Point extent = gc.textExtent(word);
-//                     width = Math.max(width, extent.x);
-//                     last = loc;
-//             }
-//             String lastWord = text.substring(last);
-//             Point extent = gc.textExtent(lastWord);
-//             width = Math.max(width, extent.x);
-//             return width;
-               return 0;
-       }
-       
-       public static Point computeWrapSize(GC gc, String text, int wHint) {    
-//             BreakIterator wb = BreakIterator.getWordInstance();
-//             wb.setText(text);
-               FontMetrics fm = gc.getFontMetrics();
-               int lineHeight = fm.getHeight();
-               
-               int saved = 0;
-               int last = 0;
-               int height = lineHeight;
-               int maxWidth = 0;
-//             for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) {
-//                     String word = text.substring(saved, loc);
-//                     Point extent = gc.textExtent(word);
-//                     if (extent.x > wHint) {
-//                             // overflow
-//                             saved = last;
-//                             height += extent.y;
-//                             // switch to current word so maxWidth will accommodate very long single words
-//                             word = text.substring(last, loc);
-//                             extent = gc.textExtent(word);
-//                     }
-//                     maxWidth = Math.max(maxWidth, extent.x);
-//                     last = loc;
-//             }
-               /*
-                * Correct the height attribute in case it was calculated wrong due to wHint being less than maxWidth.
-                * The recursive call proved to be the only thing that worked in all cases. Some attempts can be made
-                * to estimate the height, but the algorithm needs to be run again to be sure.
-                */
-               if (maxWidth > wHint)
-                       return computeWrapSize(gc, text, maxWidth);               
-               return new Point(maxWidth, height);
-       }
-
-// RAP [rh] paintWrapText unnecessary
-//     public static void paintWrapText(GC gc, String text, Rectangle bounds) {
-//             paintWrapText(gc, text, bounds, false);
-//     }
-       
-// RAP [rh] paintWrapText unnecessary
-//     public static void paintWrapText(GC gc, String text, Rectangle bounds,
-//                     boolean underline) {
-//             BreakIterator wb = BreakIterator.getWordInstance();
-//             wb.setText(text);
-//             FontMetrics fm = gc.getFontMetrics();
-//             int lineHeight = fm.getHeight();
-//             int descent = fm.getDescent();
-//
-//             int saved = 0;
-//             int last = 0;
-//             int y = bounds.y;
-//             int width = bounds.width;
-//
-//             for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) {
-//                     String line = text.substring(saved, loc);
-//                     Point extent = gc.textExtent(line);
-//
-//                     if (extent.x > width) {
-//                             // overflow
-//                             String prevLine = text.substring(saved, last);
-//                             gc.drawText(prevLine, bounds.x, y, true);
-//                             if (underline) {
-//                                     Point prevExtent = gc.textExtent(prevLine);
-//                                     int lineY = y + lineHeight - descent + 1;
-//                                     gc
-//                                                     .drawLine(bounds.x, lineY, bounds.x + prevExtent.x,
-//                                                                     lineY);
-//                             }
-//
-//                             saved = last;
-//                             y += lineHeight;
-//                     }
-//                     last = loc;
-//             }
-//             // paint the last line
-//             String lastLine = text.substring(saved, last);
-//             gc.drawText(lastLine, bounds.x, y, true);
-//             if (underline) {
-//                     int lineY = y + lineHeight - descent + 1;
-//                     Point lastExtent = gc.textExtent(lastLine);
-//                     gc.drawLine(bounds.x, lineY, bounds.x + lastExtent.x, lineY);
-//             }
-//     }
-
-       public static ScrolledComposite getScrolledComposite(Control c) {
-               Composite parent = c.getParent();
-
-               while (parent != null) {
-                       if (parent instanceof ScrolledComposite) {
-                               return (ScrolledComposite) parent;
-                       }
-                       parent = parent.getParent();
-               }
-               return null;
-       }
-
-       public static void ensureVisible(Control c) {
-               ScrolledComposite scomp = getScrolledComposite(c);
-               if (scomp != null) {
-                       Object data = scomp.getData(FOCUS_SCROLLING);
-                       if (data == null || !data.equals(Boolean.FALSE))
-                               FormUtil.ensureVisible(scomp, c);
-               }
-       }
-
-       public static void ensureVisible(ScrolledComposite scomp, Control control) {
-               // if the control is a FormText we do not need to scroll since it will
-               // ensure visibility of its segments as necessary
-//             if (control instanceof FormText)
-//                     return;
-               Point controlSize = control.getSize();
-               Point controlOrigin = getControlLocation(scomp, control);
-               ensureVisible(scomp, controlOrigin, controlSize);
-       }
-
-       public static void ensureVisible(ScrolledComposite scomp,
-                       Point controlOrigin, Point controlSize) {
-               Rectangle area = scomp.getClientArea();
-               Point scompOrigin = scomp.getOrigin();
-
-               int x = scompOrigin.x;
-               int y = scompOrigin.y;
-
-               // horizontal right, but only if the control is smaller
-               // than the client area
-               if (controlSize.x < area.width
-                               && (controlOrigin.x + controlSize.x > scompOrigin.x
-                                               + area.width)) {
-                       x = controlOrigin.x + controlSize.x - area.width;
-               }
-               // horizontal left - make sure the left edge of
-               // the control is showing
-               if (controlOrigin.x < x) {
-                       if (controlSize.x < area.width)
-                               x = controlOrigin.x + controlSize.x - area.width;
-                       else
-                               x = controlOrigin.x;
-               }
-               // vertical bottom
-               if (controlSize.y < area.height
-                               && (controlOrigin.y + controlSize.y > scompOrigin.y
-                                               + area.height)) {
-                       y = controlOrigin.y + controlSize.y - area.height;
-               }
-               // vertical top - make sure the top of
-               // the control is showing
-               if (controlOrigin.y < y) {
-                       if (controlSize.y < area.height)
-                               y = controlOrigin.y + controlSize.y - area.height;
-                       else
-                               y = controlOrigin.y;
-               }
-
-               if (scompOrigin.x != x || scompOrigin.y != y) {
-                       // scroll to reveal
-                       scomp.setOrigin(x, y);
-               }
-       }
-
-       public static void ensureVisible(ScrolledComposite scomp, Control control,
-                       MouseEvent e) {
-               Point controlOrigin = getControlLocation(scomp, control);
-               int rX = controlOrigin.x + e.x;
-               int rY = controlOrigin.y + e.y;
-               Rectangle area = scomp.getClientArea();
-               Point scompOrigin = scomp.getOrigin();
-
-               int x = scompOrigin.x;
-               int y = scompOrigin.y;
-               // System.out.println("Ensure: area="+area+", origin="+scompOrigin+",
-               // cloc="+controlOrigin+", csize="+controlSize+", x="+x+", y="+y);
-
-               // horizontal right
-               if (rX > scompOrigin.x + area.width) {
-                       x = rX - area.width;
-               }
-               // horizontal left
-               else if (rX < x) {
-                       x = rX;
-               }
-               // vertical bottom
-               if (rY > scompOrigin.y + area.height) {
-                       y = rY - area.height;
-               }
-               // vertical top
-               else if (rY < y) {
-                       y = rY;
-               }
-
-               if (scompOrigin.x != x || scompOrigin.y != y) {
-                       // scroll to reveal
-                       scomp.setOrigin(x, y);
-               }
-       }
-
-       public static Point getControlLocation(ScrolledComposite scomp,
-                       Control control) {
-               int x = 0;
-               int y = 0;
-               Control content = scomp.getContent();
-               Control currentControl = control;
-               for (;;) {
-                       if (currentControl == content)
-                               break;
-                       Point location = currentControl.getLocation();
-                       // if (location.x > 0)
-                       // x += location.x;
-                       // if (location.y > 0)
-                       // y += location.y;
-                       x += location.x;
-                       y += location.y;
-                       currentControl = currentControl.getParent();
-               }
-               return new Point(x, y);
-       }
-
-       static void scrollVertical(ScrolledComposite scomp, boolean up) {
-               scroll(scomp, 0, up ? -V_SCROLL_INCREMENT : V_SCROLL_INCREMENT);
-       }
-
-       static void scrollHorizontal(ScrolledComposite scomp, boolean left) {
-               scroll(scomp, left ? -H_SCROLL_INCREMENT : H_SCROLL_INCREMENT, 0);
-       }
-
-       static void scrollPage(ScrolledComposite scomp, boolean up) {
-               Rectangle clientArea = scomp.getClientArea();
-               int increment = up ? -clientArea.height : clientArea.height;
-               scroll(scomp, 0, increment);
-       }
-
-       static void scroll(ScrolledComposite scomp, int xoffset, int yoffset) {
-               Point origin = scomp.getOrigin();
-               Point contentSize = scomp.getContent().getSize();
-               int xorigin = origin.x + xoffset;
-               int yorigin = origin.y + yoffset;
-               xorigin = Math.max(xorigin, 0);
-               xorigin = Math.min(xorigin, contentSize.x - 1);
-               yorigin = Math.max(yorigin, 0);
-               yorigin = Math.min(yorigin, contentSize.y - 1);
-               scomp.setOrigin(xorigin, yorigin);
-       }
-
-// RAP [rh] FormUtil#updatePageIncrement: empty implementation
-       public static void updatePageIncrement(ScrolledComposite scomp) {
-//             ScrollBar vbar = scomp.getVerticalBar();
-//             if (vbar != null) {
-//                     Rectangle clientArea = scomp.getClientArea();
-//                     int increment = clientArea.height - 5;
-//                     vbar.setPageIncrement(increment);
-//             }
-//             ScrollBar hbar = scomp.getHorizontalBar();
-//             if (hbar != null) {
-//                     Rectangle clientArea = scomp.getClientArea();
-//                     int increment = clientArea.width - 5;
-//                     hbar.setPageIncrement(increment);
-//             }
-       }
-
-       public static void processKey(int keyCode, Control c) {
-               if (c.isDisposed()) {
-                       return;
-               }
-               ScrolledComposite scomp = FormUtil.getScrolledComposite(c);
-               if (scomp != null) {
-                       if (c instanceof Combo)
-                               return;
-                       switch (keyCode) {
-                       case SWT.ARROW_DOWN:
-                               if (scomp.getData("novarrows") == null) //$NON-NLS-1$
-                                       FormUtil.scrollVertical(scomp, false);
-                               break;
-                       case SWT.ARROW_UP:
-                               if (scomp.getData("novarrows") == null) //$NON-NLS-1$
-                                       FormUtil.scrollVertical(scomp, true);
-                               break;
-                       case SWT.ARROW_LEFT:
-                               FormUtil.scrollHorizontal(scomp, true);
-                               break;
-                       case SWT.ARROW_RIGHT:
-                               FormUtil.scrollHorizontal(scomp, false);
-                               break;
-                       case SWT.PAGE_UP:
-                               FormUtil.scrollPage(scomp, true);
-                               break;
-                       case SWT.PAGE_DOWN:
-                               FormUtil.scrollPage(scomp, false);
-                               break;
-                       }
-               }
-       }
-
-       public static boolean isWrapControl(Control c) {
-               if ((c.getStyle() & SWT.WRAP) != 0)
-                       return true;
-               if (c instanceof Composite) {
-                       return false;
-//                     return ((Composite) c).getLayout() instanceof ILayoutExtension;
-               }
-               return false;
-       }
-
-       public static int getWidthHint(int wHint, Control c) {
-               boolean wrap = isWrapControl(c);
-               return wrap ? wHint : SWT.DEFAULT;
-       }
-
-       public static int getHeightHint(int hHint, Control c) {
-               if (c instanceof Composite) {
-                       Layout layout = ((Composite) c).getLayout();
-//                     if (layout instanceof ColumnLayout)
-//                             return hHint;
-               }
-               return SWT.DEFAULT;
-       }
-
-       public static int computeMinimumWidth(Control c, boolean changed) {
-               if (c instanceof Composite) {
-                       Layout layout = ((Composite) c).getLayout();
-//                     if (layout instanceof ILayoutExtension)
-//                             return ((ILayoutExtension) layout).computeMinimumWidth(
-//                                             (Composite) c, changed);
-               }
-               return c.computeSize(FormUtil.getWidthHint(5, c), SWT.DEFAULT, changed).x;
-       }
-
-       public static int computeMaximumWidth(Control c, boolean changed) {
-               if (c instanceof Composite) {
-                       Layout layout = ((Composite) c).getLayout();
-//                     if (layout instanceof ILayoutExtension)
-//                             return ((ILayoutExtension) layout).computeMaximumWidth(
-//                                             (Composite) c, changed);
-               }
-               return c.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed).x;
-       }
-
-//     public static Form getForm(Control c) {
-//             Composite parent = c.getParent();
-//             while (parent != null) {
-//                     if (parent instanceof Form) {
-//                             return (Form) parent;
-//                     }
-//                     parent = parent.getParent();
-//             }
-//             return null;
-//     }
-
-// RAP [rh] FormUtil#createAlphaMashImage unnecessary  
-//     public static Image createAlphaMashImage(Device device, Image srcImage) {
-//             Rectangle bounds = srcImage.getBounds();
-//             int alpha = 0;
-//             int calpha = 0;
-//             ImageData data = srcImage.getImageData();
-//             // Create a new image with alpha values alternating
-//             // between fully transparent (0) and fully opaque (255).
-//             // This image will show the background through the
-//             // transparent pixels.
-//             for (int i = 0; i < bounds.height; i++) {
-//                     // scan line
-//                     alpha = calpha;
-//                     for (int j = 0; j < bounds.width; j++) {
-//                             // column
-//                             data.setAlpha(j, i, alpha);
-//                             alpha = alpha == 255 ? 0 : 255;
-//                     }
-//                     calpha = calpha == 255 ? 0 : 255;
-//             }
-//             return new Image(device, data);
-//     }
-
-       public static boolean mnemonicMatch(String text, char key) {
-               char mnemonic = findMnemonic(text);
-               if (mnemonic == '\0')
-                       return false;
-               return Character.toUpperCase(key) == Character.toUpperCase(mnemonic);
-       }
-
-       private static char findMnemonic(String string) {
-               int index = 0;
-               int length = string.length();
-               do {
-                       while (index < length && string.charAt(index) != '&')
-                               index++;
-                       if (++index >= length)
-                               return '\0';
-                       if (string.charAt(index) != '&')
-                               return string.charAt(index);
-                       index++;
-               } while (index < length);
-               return '\0';
-       }
-       
-       public static void setFocusScrollingEnabled(Control c, boolean enabled) {
-               ScrolledComposite scomp = null;
-               
-               if (c instanceof ScrolledComposite)
-                       scomp = (ScrolledComposite)c;
-               else
-                       scomp = getScrolledComposite(c);
-               if (scomp!=null)
-                       scomp.setData(FormUtil.FOCUS_SCROLLING, enabled?null:Boolean.FALSE);
-       }
-       
-       // RAP [rh] FormUtil#setAntialias unnecessary
-//     public static void setAntialias(GC gc, int style) {
-//             if (!gc.getAdvanced()) {
-//                     gc.setAdvanced(true);
-//                     if (!gc.getAdvanced())
-//                             return;
-//             }
-//             gc.setAntialias(style);
-//     }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormColors.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormColors.java
deleted file mode 100644 (file)
index cf0e5d3..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-/**
- * A place to hold all the color constants used in the forms package.
- * 
- * @since 1.0
- */
-
-public interface IFormColors {
-       /**
-        * A prefix for all the keys.
-        */
-       String PREFIX = "org.eclipse.ui.forms."; //$NON-NLS-1$
-       /**
-        * Key for the form title foreground color.
-        */
-       String TITLE = PREFIX + "TITLE"; //$NON-NLS-1$
-
-       /**
-        * A prefix for the header color constants.
-        */
-       String H_PREFIX = PREFIX + "H_"; //$NON-NLS-1$
-       /*
-        * A prefix for the section title bar color constants.
-        */
-       String TB_PREFIX = PREFIX + "TB_"; //$NON-NLS-1$        
-       /**
-        * Key for the form header background gradient ending color.
-        */
-       String H_GRADIENT_END = H_PREFIX + "GRADIENT_END"; //$NON-NLS-1$
-
-       /**
-        * Key for the form header background gradient starting color.
-        * 
-        */
-       String H_GRADIENT_START = H_PREFIX + "GRADIENT_START"; //$NON-NLS-1$
-       /**
-        * Key for the form header bottom keyline 1 color.
-        * 
-        */
-       String H_BOTTOM_KEYLINE1 = H_PREFIX + "BOTTOM_KEYLINE1"; //$NON-NLS-1$
-       /**
-        * Key for the form header bottom keyline 2 color.
-        * 
-        */
-       String H_BOTTOM_KEYLINE2 = H_PREFIX + "BOTTOM_KEYLINE2"; //$NON-NLS-1$
-       /**
-        * Key for the form header light hover color.
-        * 
-        */
-       String H_HOVER_LIGHT = H_PREFIX + "H_HOVER_LIGHT"; //$NON-NLS-1$
-       /**
-        * Key for the form header full hover color.
-        * 
-        */
-       String H_HOVER_FULL = H_PREFIX + "H_HOVER_FULL"; //$NON-NLS-1$
-
-       /**
-        * Key for the tree/table border color.
-        */
-       String BORDER = PREFIX + "BORDER"; //$NON-NLS-1$
-
-       /**
-        * Key for the section separator color.
-        */
-       String SEPARATOR = PREFIX + "SEPARATOR"; //$NON-NLS-1$
-
-       /**
-        * Key for the section title bar background.
-        */
-       String TB_BG = TB_PREFIX + "BG"; //$NON-NLS-1$
-
-       /**
-        * Key for the section title bar foreground.
-        */
-       String TB_FG = TB_PREFIX + "FG"; //$NON-NLS-1$
-
-       /**
-        * Key for the section title bar gradient.
-        * @deprecated Since 3.3, this color is not used any more. The 
-        * tool bar gradient is created starting from {@link #TB_BG} to
-        * the section background color.
-        */
-       String TB_GBG = TB_BG;
-
-       /**
-        * Key for the section title bar border.
-        */
-       String TB_BORDER = TB_PREFIX + "BORDER"; //$NON-NLS-1$
-
-       /**
-        * Key for the section toggle color. Since 3.1, this color is used for all
-        * section styles.
-        */
-       String TB_TOGGLE = TB_PREFIX + "TOGGLE"; //$NON-NLS-1$
-
-       /**
-        * Key for the section toggle hover color.
-        * 
-        */
-       String TB_TOGGLE_HOVER = TB_PREFIX + "TOGGLE_HOVER"; //$NON-NLS-1$              
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormPart.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormPart.java
deleted file mode 100644 (file)
index 954cc03..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-/**
- * Classes that implement this interface can be added to the managed form and
- * take part in the form life cycle. The part is initialized with the form and
- * will be asked to accept focus. The part can receive form input and can elect
- * to do something according to it (for example, select an object that matches
- * the input).
- * <p>
- * The form part has two 'out of sync' states in respect to the model(s) that
- * feed the form: <b>dirty</b> and <b>stale</b>. When a part is dirty, it
- * means that the user interacted with it and now its widgets contain state that
- * is newer than the model. In order to sync up with the model, 'commit' needs
- * to be called. In contrast, the model can change 'under' the form (as a result
- * of some actions outside the form), resulting in data in the model being
- * 'newer' than the content presented in the form. A 'stale' form part is
- * brought in sync with the model by calling 'refresh'. The part is responsible
- * for notifying the form when one of these states change in the part. The form
- * reserves the right to handle this notification in the most appropriate way
- * for the situation (for example, if the form is in a page of the multi-page
- * editor, it may do nothing for stale parts if the page is currently not
- * showing).
- * <p>
- * When the form is disposed, each registered part is disposed as well. Parts
- * are responsible for releasing any system resources they created and for
- * removing themselves as listeners from all event providers.
- * 
- * @see IManagedForm
- * @since 1.0
- * 
- */
-public interface IFormPart {
-       /**
-        * Initializes the part.
-        * 
-        * @param form
-        *            the managed form that manages the part
-        */
-       void initialize(IManagedForm form);
-
-       /**
-        * Disposes the part allowing it to release allocated resources.
-        */
-       void dispose();
-
-       /**
-        * Returns true if the part has been modified with respect to the data
-        * loaded from the model.
-        * 
-        * @return true if the part has been modified with respect to the data
-        *         loaded from the model
-        */
-       boolean isDirty();
-
-       /**
-        * If part is displaying information loaded from a model, this method
-        * instructs it to commit the new (modified) data back into the model.
-        * 
-        * @param onSave
-        *            indicates if commit is called during 'save' operation or for
-        *            some other reason (for example, if form is contained in a
-        *            wizard or a multi-page editor and the user is about to leave
-        *            the page).
-        */
-       void commit(boolean onSave);
-
-       /**
-        * Notifies the part that an object has been set as overall form's input.
-        * The part can elect to react by revealing or selecting the object, or do
-        * nothing if not applicable.
-        * 
-        * @return <code>true</code> if the part has selected and revealed the
-        *         input object, <code>false</code> otherwise.
-        */
-       boolean setFormInput(Object input);
-
-       /**
-        * Instructs form part to transfer focus to the widget that should has focus
-        * in that part. The method can do nothing (if it has no widgets capable of
-        * accepting focus).
-        */
-       void setFocus();
-
-       /**
-        * Tests whether the form part is stale and needs refreshing. Parts can
-        * receive notification from models that will make their content stale, but
-        * may need to delay refreshing to improve performance (for example, there
-        * is no need to immediately refresh a part on a form that is current on a
-        * hidden page).
-        * <p>
-        * It is important to differentiate 'stale' and 'dirty' states. Part is
-        * 'dirty' if user interacted with its editable widgets and changed the
-        * values. In contrast, part is 'stale' when the data it presents in the
-        * widgets has been changed in the model without direct user interaction.
-        * 
-        * @return <code>true</code> if the part needs refreshing,
-        *         <code>false</code> otherwise.
-        */
-       boolean isStale();
-
-       /**
-        * Refreshes the part completely from the information freshly obtained from
-        * the model. The method will not be called if the part is not stale.
-        * Otherwise, the part is responsible for clearing the 'stale' flag after
-        * refreshing itself.
-        */
-       void refresh();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IManagedForm.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IManagedForm.java
deleted file mode 100644 (file)
index 490d3a3..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.swt.custom.ScrolledComposite;
-//import org.eclipse.ui.forms.widgets.FormToolkit;
-//import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-/**
- * Managed form wraps a form widget and adds life cycle methods for form parts.
- * A form part is a portion of the form that participates in form life cycle
- * events.
- * <p>
- * There is no 1/1 mapping between widgets and form parts. A widget like Section
- * can be a part by itself, but a number of widgets can gather around one form
- * part.
- * <p>
- * This interface should not be extended or implemented. New form instances
- * should be created using ManagedForm.
- * 
- * @see ManagedForm
- * @since 1.0
- * @noimplement This interface is not intended to be implemented by clients.
- * @noextend This interface is not intended to be extended by clients.
- */
-public interface IManagedForm {
-       /**
-        * Initializes the form by looping through the managed parts and
-        * initializing them. Has no effect if already called once.
-        */
-       public void initialize();
-
-       /**
-        * Returns the toolkit used by this form.
-        * 
-        * @return the toolkit
-        */
-       public FormToolkit getToolkit();
-
-       /**
-        * Returns the form widget managed by this form.
-        * 
-        * @return the form widget
-        */
-       public ScrolledComposite getForm();
-
-       /**
-        * Reflows the form as a result of the layout change.
-        * 
-        * @param changed
-        *            if <code>true</code>, discard cached layout information
-        */
-       public void reflow(boolean changed);
-
-       /**
-        * A part can use this method to notify other parts that implement
-        * IPartSelectionListener about selection changes.
-        * 
-        * @param part
-        *            the part that broadcasts the selection
-        * @param selection
-        *            the selection in the part
-        */
-       public void fireSelectionChanged(IFormPart part, ISelection selection);
-
-       /**
-        * Returns all the parts currently managed by this form.
-        * 
-        * @return the managed parts
-        */
-       IFormPart[] getParts();
-
-       /**
-        * Adds the new part to the form.
-        * 
-        * @param part
-        *            the part to add
-        */
-       void addPart(IFormPart part);
-
-       /**
-        * Removes the part from the form.
-        * 
-        * @param part
-        *            the part to remove
-        */
-       void removePart(IFormPart part);
-
-       /**
-        * Sets the input of this page to the provided object.
-        * 
-        * @param input
-        *            the new page input
-        * @return <code>true</code> if the form contains this object,
-        *         <code>false</code> otherwise.
-        */
-       boolean setInput(Object input);
-
-       /**
-        * Returns the current page input.
-        * 
-        * @return page input object or <code>null</code> if not applicable.
-        */
-       Object getInput();
-
-       /**
-        * Tests if form is dirty. A managed form is dirty if at least one managed
-        * part is dirty.
-        * 
-        * @return <code>true</code> if at least one managed part is dirty,
-        *         <code>false</code> otherwise.
-        */
-       boolean isDirty();
-
-       /**
-        * Notifies the form that the dirty state of one of its parts has changed.
-        * The global dirty state of the form can be obtained by calling 'isDirty'.
-        * 
-        * @see #isDirty
-        */
-       void dirtyStateChanged();
-
-       /**
-        * Commits the dirty form. All pending changes in the widgets are flushed
-        * into the model.
-        * 
-        * @param onSave
-        */
-       void commit(boolean onSave);
-
-       /**
-        * Tests if form is stale. A managed form is stale if at least one managed
-        * part is stale. This can happen when the underlying model changes,
-        * resulting in the presentation of the part being out of sync with the
-        * model and needing refreshing.
-        * 
-        * @return <code>true</code> if the form is stale, <code>false</code>
-        *         otherwise.
-        */
-       boolean isStale();
-
-       /**
-        * Notifies the form that the stale state of one of its parts has changed.
-        * The global stale state of the form can be obtained by calling 'isStale'.
-        */
-       void staleStateChanged();
-
-       /**
-        * Refreshes the form by refreshing every part that is stale.
-        */
-       void refresh();
-
-       /**
-        * Sets the container that owns this form. Depending on the context, the
-        * container may be wizard, editor page, editor etc.
-        * 
-        * @param container
-        *            the container of this form
-        */
-       void setContainer(Object container);
-
-       /**
-        * Returns the container of this form.
-        * 
-        * @return the form container
-        */
-       Object getContainer();
-
-       /**
-        * Returns the message manager that will keep track of messages in this
-        * form.
-        * 
-        * @return the message manager instance
-        */
-//     IMessageManager getMessageManager();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IPartSelectionListener.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IPartSelectionListener.java
deleted file mode 100644 (file)
index 0f557d4..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-import org.eclipse.jface.viewers.ISelection;
-
-/**
- * Form parts can implement this interface if they want to be 
- * notified when another part on the same form changes selection 
- * state.
- * 
- * @see IFormPart
- * @since 1.0
- */
-public interface IPartSelectionListener {
-       /**
-        * Called when the provided part has changed selection state.
-        * 
-        * @param part
-        *            the selection source
-        * @param selection
-        *            the new selection
-        */
-       public void selectionChanged(IFormPart part, ISelection selection);
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/ManagedForm.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/ManagedForm.java
deleted file mode 100644 (file)
index 4140465..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms;
-
-import java.util.Vector;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.widgets.Composite;
-//import org.eclipse.ui.forms.widgets.FormToolkit;
-//import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-/**
- * Managed form wraps a form widget and adds life cycle methods for form parts.
- * A form part is a portion of the form that participates in form life cycle
- * events.
- * <p>
- * There is requirement for 1/1 mapping between widgets and form parts. A widget
- * like Section can be a part by itself, but a number of widgets can join around
- * one form part.
- * <p>
- * Note to developers: this class is left public to allow its use beyond the
- * original intention (inside a multi-page editor's page). You should limit the
- * use of this class to make new instances inside a form container (wizard page,
- * dialog etc.). Clients that need access to the class should not do it
- * directly. Instead, they should do it through IManagedForm interface as much
- * as possible.
- * 
- * @since 1.0
- */
-public class ManagedForm implements IManagedForm {
-       private Object input;
-
-       private ScrolledComposite form;
-
-       private FormToolkit toolkit;
-
-       private Object container;
-
-       private boolean ownsToolkit;
-
-       private boolean initialized;
-
-       private Vector parts = new Vector();
-
-       /**
-        * Creates a managed form in the provided parent. Form toolkit and widget
-        * will be created and owned by this object.
-        * 
-        * @param parent
-        *            the parent widget
-        */
-       public ManagedForm(Composite parent) {
-               toolkit = new FormToolkit(parent.getDisplay());
-               ownsToolkit = true;
-               form = toolkit.createScrolledForm(parent);
-               
-       }
-
-       /**
-        * Creates a managed form that will use the provided toolkit and
-        * 
-        * @param toolkit
-        * @param form
-        */
-       public ManagedForm(FormToolkit toolkit, ScrolledComposite form) {
-               this.form = form;
-               this.toolkit = toolkit;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#addPart(org.eclipse.ui.forms.IFormPart)
-        */
-       public void addPart(IFormPart part) {
-               parts.add(part);
-               part.initialize(this);
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#removePart(org.eclipse.ui.forms.IFormPart)
-        */
-       public void removePart(IFormPart part) {
-               parts.remove(part);
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#getParts()
-        */
-       public IFormPart[] getParts() {
-               return (IFormPart[]) parts.toArray(new IFormPart[parts.size()]);
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#getToolkit()
-        */
-       public FormToolkit getToolkit() {
-               return toolkit;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#getForm()
-        */
-       public ScrolledComposite getForm() {
-               return form;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#reflow(boolean)
-        */
-       public void reflow(boolean changed) {
-//             form.reflow(changed);
-       }
-
-       /**
-        * A part can use this method to notify other parts that implement
-        * IPartSelectionListener about selection changes.
-        * 
-        * @param part
-        *            the part that broadcasts the selection
-        * @param selection
-        *            the selection in the part
-        * @see IPartSelectionListener
-        */
-       public void fireSelectionChanged(IFormPart part, ISelection selection) {
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart cpart = (IFormPart) parts.get(i);
-                       if (part.equals(cpart))
-                               continue;
-//                     if (cpart instanceof IPartSelectionListener) {
-//                             ((IPartSelectionListener) cpart).selectionChanged(part,
-//                                             selection);
-//                     }
-               }
-       }
-
-       /**
-        * Initializes the form by looping through the managed parts and
-        * initializing them. Has no effect if already called once.
-        */
-       public void initialize() {
-               if (initialized)
-                       return;
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart part = (IFormPart) parts.get(i);
-                       part.initialize(this);
-               }
-               initialized = true;
-       }
-
-       /**
-        * Disposes all the parts in this form.
-        */
-       public void dispose() {
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart part = (IFormPart) parts.get(i);
-                       part.dispose();
-               }
-               if (ownsToolkit) {
-                       toolkit.dispose();
-               }
-       }
-
-       /**
-        * Refreshes the form by refreshes all the stale parts. Since 3.1, this
-        * method is performed on a UI thread when called from another thread so it
-        * is not needed to wrap the call in <code>Display.syncExec</code> or
-        * <code>asyncExec</code>.
-        */
-       public void refresh() {
-               Thread t = Thread.currentThread();
-               Thread dt = toolkit.getColors().getDisplay().getThread();
-               if (t.equals(dt))
-                       doRefresh();
-               else {
-                       toolkit.getColors().getDisplay().asyncExec(new Runnable() {
-                               public void run() {
-                                       doRefresh();
-                               }
-                       });
-               }
-       }
-
-       private void doRefresh() {
-               int nrefreshed = 0;
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart part = (IFormPart) parts.get(i);
-                       if (part.isStale()) {
-                               part.refresh();
-                               nrefreshed++;
-                       }
-               }
-//             if (nrefreshed > 0)
-//                     form.reflow(true);
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#commit(boolean)
-        */
-       public void commit(boolean onSave) {
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart part = (IFormPart) parts.get(i);
-                       if (part.isDirty())
-                               part.commit(onSave);
-               }
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#setInput(java.lang.Object)
-        */
-       public boolean setInput(Object input) {
-               boolean pageResult = false;
-
-               this.input = input;
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart part = (IFormPart) parts.get(i);
-                       boolean result = part.setFormInput(input);
-                       if (result)
-                               pageResult = true;
-               }
-               return pageResult;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#getInput()
-        */
-       public Object getInput() {
-               return input;
-       }
-
-       /**
-        * Transfers the focus to the first form part.
-        */
-       public void setFocus() {
-               if (parts.size() > 0) {
-                       IFormPart part = (IFormPart) parts.get(0);
-                       part.setFocus();
-               }
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#isDirty()
-        */
-       public boolean isDirty() {
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart part = (IFormPart) parts.get(i);
-                       if (part.isDirty())
-                               return true;
-               }
-               return false;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#isStale()
-        */
-       public boolean isStale() {
-               for (int i = 0; i < parts.size(); i++) {
-                       IFormPart part = (IFormPart) parts.get(i);
-                       if (part.isStale())
-                               return true;
-               }
-               return false;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#dirtyStateChanged()
-        */
-       public void dirtyStateChanged() {
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#staleStateChanged()
-        */
-       public void staleStateChanged() {
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#getContainer()
-        */
-       public Object getContainer() {
-               return container;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.ui.forms.IManagedForm#setContainer(java.lang.Object)
-        */
-       public void setContainer(Object container) {
-               this.container = container;
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.forms.IManagedForm#getMessageManager()
-        */
-//     public IMessageManager getMessageManager() {
-//             return form.getMessageManager();
-//     }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormEditor.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormEditor.java
deleted file mode 100644 (file)
index 484dae8..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms.editor;
-
-import org.argeo.cms.ui.eclipse.forms.FormToolkit;
-import org.eclipse.jface.dialogs.IPageChangeProvider;
-
-/**
- * This class forms a base of multi-page form editors that typically use one or
- * more pages with forms and one page for raw source of the editor input.
- * <p>
- * Pages are added 'lazily' i.e. adding a page reserves a tab for it but does
- * not cause the page control to be created. Page control is created when an
- * attempt is made to select the page in question. This allows editors with
- * several tabs and complex pages to open quickly.
- * <p>
- * Subclasses should extend this class and implement <code>addPages</code>
- * method. One of the two <code>addPage</code> methods should be called to
- * contribute pages to the editor. One adds complete (standalone) editors as
- * nested tabs. These editors will be created right away and will be hooked so
- * that key bindings, selection service etc. is compatible with the one for the
- * standalone case. The other method adds classes that implement
- * <code>IFormPage</code> interface. These pages will be created lazily and
- * they will share the common key binding and selection service. Since 3.1,
- * FormEditor is a page change provider. It allows listeners to attach to it and
- * get notified when pages are changed. This new API in JFace allows dynamic
- * help to update on page changes.
- * 
- * @since 1.0
- */
-// RAP [if] As RAP is still using workbench 3.4, the implementation of
-// IPageChangeProvider is missing from MultiPageEditorPart. Remove this code
-// with the adoption of workbench > 3.5
-//public abstract class FormEditor extends MultiPageEditorPart  {
-public abstract class FormEditor  implements
-        IPageChangeProvider {
-       private FormToolkit formToolkit;
-       
-       
-public FormToolkit getToolkit() {
-               return formToolkit;
-       }
-
-public void editorDirtyStateChanged() {
-       
-}
-
-public FormPage getActivePageInstance() {
-       return null;
-}
-
-       // RAP [if] As RAP is still using workbench 3.4, the implementation of
-// IPageChangeProvider is missing from MultiPageEditorPart. Remove this code
-// with the adoption of workbench > 3.5
-//     private ListenerList pageListeners = new ListenerList();
-//     
-//    /*
-//     * (non-Javadoc)
-//     * 
-//     * @see org.eclipse.jface.dialogs.IPageChangeProvider#addPageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
-//     */
-//    public void addPageChangedListener(IPageChangedListener listener) {
-//        pageListeners.add(listener);
-//    }
-//
-//    /*
-//     * (non-Javadoc)
-//     * 
-//     * @see org.eclipse.jface.dialogs.IPageChangeProvider#removePageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
-//     */
-//    public void removePageChangedListener(IPageChangedListener listener) {
-//        pageListeners.remove(listener);
-//    }
-//    
-//     private void firePageChanged(final PageChangedEvent event) {
-//        Object[] listeners = pageListeners.getListeners();
-//        for (int i = 0; i < listeners.length; ++i) {
-//            final IPageChangedListener l = (IPageChangedListener) listeners[i];
-//            SafeRunnable.run(new SafeRunnable() {
-//                public void run() {
-//                    l.pageChanged(event);
-//                }
-//            });
-//        }
-//    }
-// RAPEND [if]
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormPage.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormPage.java
deleted file mode 100644 (file)
index a788412..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms.editor;
-import org.argeo.cms.ui.eclipse.forms.IManagedForm;
-import org.argeo.cms.ui.eclipse.forms.ManagedForm;
-import org.eclipse.swt.custom.BusyIndicator;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-/**
- * A base class that all pages that should be added to FormEditor must subclass.
- * Form page has an instance of PageForm that extends managed form. Subclasses
- * should override method 'createFormContent(ManagedForm)' to fill the form with
- * content. Note that page itself can be loaded lazily (on first open).
- * Consequently, the call to create the form content can come after the editor
- * has been opened for a while (in fact, it is possible to open and close the
- * editor and never create the form because no attempt has been made to show the
- * page).
- * 
- * @since 1.0
- */
-public class FormPage implements IFormPage {
-       private FormEditor editor;
-       private PageForm mform;
-       private int index;
-       private String id;
-       
-       private String partName;
-       
-       
-       
-       public void setPartName(String partName) {
-               this.partName = partName;
-       }
-       private static class PageForm extends ManagedForm {
-               public PageForm(FormPage page, ScrolledComposite form) {
-                       super(page.getEditor().getToolkit(), form);
-                       setContainer(page);
-               }
-               
-               public FormPage getPage() {
-                       return (FormPage)getContainer();
-               }
-               public void dirtyStateChanged() {
-                       getPage().getEditor().editorDirtyStateChanged();
-               }
-               public void staleStateChanged() {
-                       if (getPage().isActive())
-                               refresh();
-               }
-       }
-       /**
-        * A constructor that creates the page and initializes it with the editor.
-        * 
-        * @param editor
-        *            the parent editor
-        * @param id
-        *            the unique identifier
-        * @param title
-        *            the page title
-        */
-       public FormPage(FormEditor editor, String id, String title) {
-               this(id, title);
-               initialize(editor);
-       }
-       /**
-        * The constructor. The parent editor need to be passed in the
-        * <code>initialize</code> method if this constructor is used.
-        * 
-        * @param id
-        *            a unique page identifier
-        * @param title
-        *            a user-friendly page title
-        */
-       public FormPage(String id, String title) {
-               this.id = id;
-               setPartName(title);
-       }
-       /**
-        * Initializes the form page.
-        * 
-        * @see IEditorPart#init
-        */
-//     public void init(IEditorSite site, IEditorInput input) {
-//             setSite(site);
-//             setInput(input);
-//     }
-       /**
-        * Primes the form page with the parent editor instance.
-        * 
-        * @param editor
-        *            the parent editor
-        */
-       public void initialize(FormEditor editor) {
-               this.editor = editor;
-       }
-       /**
-        * Returns the parent editor.
-        * 
-        * @return parent editor instance
-        */
-       public FormEditor getEditor() {
-               return editor;
-       }
-       /**
-        * Returns the managed form owned by this page.
-        * 
-        * @return the managed form
-        */
-       public IManagedForm getManagedForm() {
-               return mform;
-       }
-       /**
-        * Implements the required method by refreshing the form when set active.
-        * Subclasses must call super when overriding this method.
-        */
-       public void setActive(boolean active) {
-               if (active) {
-                       // We are switching to this page - refresh it
-                       // if needed.
-                       if (mform != null)
-                               mform.refresh();
-               }
-       }
-       /**
-        * Tests if the page is active by asking the parent editor if this page is
-        * the currently active page.
-        * 
-        * @return <code>true</code> if the page is currently active,
-        *         <code>false</code> otherwise.
-        */
-       public boolean isActive() {
-               return this.equals(editor.getActivePageInstance());
-       }
-       /**
-        * Creates the part control by creating the managed form using the parent
-        * editor's toolkit. Subclasses should override
-        * <code>createFormContent(IManagedForm)</code> to populate the form with
-        * content.
-        * 
-        * @param parent
-        *            the page parent composite
-        */
-       public void createPartControl(Composite parent) {
-               ScrolledComposite form = editor.getToolkit().createScrolledForm(parent);
-               mform = new PageForm(this, form);
-               BusyIndicator.showWhile(parent.getDisplay(), new Runnable() {
-                       public void run() {
-                               createFormContent(mform);
-                       }
-               });
-       }
-       /**
-        * Subclasses should override this method to create content in the form
-        * hosted in this page.
-        * 
-        * @param managedForm
-        *            the form hosted in this page.
-        */
-       protected void createFormContent(IManagedForm managedForm) {
-       }
-       /**
-        * Returns the form page control.
-        * 
-        * @return managed form's control
-        */
-       public Control getPartControl() {
-               return mform != null ? mform.getForm() : null;
-       }
-       /**
-        * Disposes the managed form.
-        */
-       public void dispose() {
-               if (mform != null)
-                       mform.dispose();
-       }
-       /**
-        * Returns the unique identifier that can be used to reference this page.
-        * 
-        * @return the unique page identifier
-        */
-       public String getId() {
-               return id;
-       }
-       /**
-        * Returns <code>null</code>- form page has no title image. Subclasses
-        * may override.
-        * 
-        * @return <code>null</code>
-        */
-       public Image getTitleImage() {
-               return null;
-       }
-       /**
-        * Sets the focus by delegating to the managed form.
-        */
-       public void setFocus() {
-               if (mform != null)
-                       mform.setFocus();
-       }
-       /**
-        * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
-        */
-//     public void doSave(IProgressMonitor monitor) {
-//             if (mform != null)
-//                     mform.commit(true);
-//     }
-       /**
-        * @see org.eclipse.ui.ISaveablePart#doSaveAs()
-        */
-       public void doSaveAs() {
-       }
-       /**
-        * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
-        */
-       public boolean isSaveAsAllowed() {
-               return false;
-       }
-       /**
-        * Implemented by testing if the managed form is dirty.
-        * 
-        * @return <code>true</code> if the managed form is dirty,
-        *         <code>false</code> otherwise.
-        * 
-        * @see org.eclipse.ui.ISaveablePart#isDirty()
-        */
-       public boolean isDirty() {
-               return mform != null ? mform.isDirty() : false;
-       }
-       /**
-        * Preserves the page index.
-        * 
-        * @param index
-        *            the assigned page index
-        */
-       public void setIndex(int index) {
-               this.index = index;
-       }
-       /**
-        * Returns the saved page index.
-        * 
-        * @return the page index
-        */
-       public int getIndex() {
-               return index;
-       }
-       /**
-        * Form pages are not editors.
-        * 
-        * @return <code>false</code>
-        */
-       public boolean isEditor() {
-               return false;
-       }
-       /**
-        * Attempts to select and reveal the given object by passing the request to
-        * the managed form.
-        * 
-        * @param object
-        *            the object to select and reveal in the page if possible.
-        * @return <code>true</code> if the page has been successfully selected
-        *         and revealed by one of the managed form parts, <code>false</code>
-        *         otherwise.
-        */
-       public boolean selectReveal(Object object) {
-               if (mform != null)
-                       return mform.setInput(object);
-               return false;
-       }
-       /**
-        * By default, editor will be allowed to flip the page.
-        * @return <code>true</code>
-        */
-       public boolean canLeaveThePage() {
-               return true;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/IFormPage.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/IFormPage.java
deleted file mode 100644 (file)
index eb08cb5..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.argeo.cms.ui.eclipse.forms.editor;
-import org.argeo.cms.ui.eclipse.forms.IManagedForm;
-import org.eclipse.swt.widgets.Control;
-/**
- * Interface that all GUI pages need to implement in order
- * to be added to FormEditor part. The interface makes 
- * several assumptions:
- * <ul>
- * <li>The form page has a managed form</li>
- * <li>The form page has a unique id</li>
- * <li>The form page can be GUI but can also wrap a complete
- * editor class (in that case, it should return <code>true</code>
- * from <code>isEditor()</code> method).</li>
- * <li>The form page is lazy i.e. understands that 
- * its part control will be created at the last possible
- * moment.</li>.
- * </ul>
- * <p>Existing editors can be wrapped by implementing
- * this interface. In this case, 'isEditor' should return <code>true</code>.
- * A common editor to wrap in <code>TextEditor</code> that is
- * often added to show the raw source code of the file open into
- * the multi-page editor.
- * 
- * @since 1.0
- */
-public interface IFormPage {
-       /**
-        * @param editor
-        *            the form editor that this page belongs to
-        */
-       void initialize(FormEditor editor);
-       /**
-        * Returns the editor this page belongs to.
-        * 
-        * @return the form editor
-        */
-       FormEditor getEditor();
-       /**
-        * Returns the managed form of this page, unless this is a source page.
-        * 
-        * @return the managed form or <samp>null </samp> if this is a source page.
-        */
-       IManagedForm getManagedForm();
-       /**
-        * Indicates whether the page has become the active in the editor. Classes
-        * that implement this interface may use this method to commit the page (on
-        * <code>false</code>) or lazily create and/or populate the content on
-        * <code>true</code>.
-        * 
-        * @param active
-        *            <code>true</code> if page should be visible, <code>false</code>
-        *            otherwise.
-        */
-       void setActive(boolean active);
-       /**
-        * Returns <samp>true </samp> if page is currently active, false if not.
-        * 
-        * @return <samp>true </samp> for active page.
-        */
-       boolean isActive();
-       /**
-        * Tests if the content of the page is in a state that allows the
-        * editor to flip to another page. Typically, pages that contain
-        * raw source with syntax errors should not allow editors to 
-        * leave them until errors are corrected.
-        * @return <code>true</code> if the editor can flip to another page,
-        * <code>false</code> otherwise.
-        */
-       boolean canLeaveThePage();
-       /**
-        * Returns the control associated with this page.
-        * 
-        * @return the control of this page if created or <samp>null </samp> if the
-        *         page has not been shown yet.
-        */
-       Control getPartControl();
-       /**
-        * Page must have a unique id that can be used to show it without knowing
-        * its relative position in the editor.
-        * 
-        * @return the unique page identifier
-        */
-       String getId();
-       /**
-        * Returns the position of the page in the editor.
-        * 
-        * @return the zero-based index of the page in the editor.
-        */
-       int getIndex();
-       /**
-        * Sets the position of the page in the editor.
-        * 
-        * @param index
-        *            the zero-based index of the page in the editor.
-        */
-       void setIndex(int index);
-       /**
-        * Tests whether this page wraps a complete editor that
-        * can be registered on its own, or represents a page
-        * that cannot exist outside the multi-page editor context.
-        * 
-        * @return <samp>true </samp> if the page wraps an editor,
-        *         <samp>false </samp> if this is a form page.
-        */
-       boolean isEditor();
-       /**
-        * A hint to bring the provided object into focus. If the object is in a
-        * tree or table control, select it. If it is shown on a scrollable page,
-        * ensure that it is visible. If the object is not presented in 
-        * the page, <code>false</code> should be returned to allow another
-        * page to try.
-        * 
-        * @param object
-        *            object to select and reveal
-        * @return <code>true</code> if the request was successful, <code>false</code>
-        *         otherwise.
-        */
-       boolean selectReveal(Object object);
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditableLink.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditableLink.java
deleted file mode 100644 (file)
index 3c1e8cd..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.SwtEditablePart;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** Editable String that displays a browsable link when read-only */
-public class EditableLink extends EditablePropertyString implements
-               SwtEditablePart {
-       private static final long serialVersionUID = 5055000749992803591L;
-
-       private String type;
-       private String message;
-       private boolean readOnly;
-
-       public EditableLink(Composite parent, int style, Node node,
-                       String propertyName, String type, String message)
-                       throws RepositoryException {
-               super(parent, style, node, propertyName, message);
-               this.message = message;
-               this.type = type;
-
-               readOnly = SWT.READ_ONLY == (style & SWT.READ_ONLY);
-               if (node.hasProperty(propertyName)) {
-                       this.setStyle(FormStyle.propertyText.style());
-                       this.setText(node.getProperty(propertyName).getString());
-               } else {
-                       this.setStyle(FormStyle.propertyMessage.style());
-                       this.setText("");
-               }
-       }
-
-       public void setText(String text) {
-               Control child = getControl();
-               if (child instanceof Label) {
-                       Label lbl = (Label) child;
-                       if (EclipseUiUtils.isEmpty(text))
-                               lbl.setText(message);
-                       else if (readOnly)
-                               setLinkValue(lbl, text);
-                       else
-                               // if canEdit() we put only the value with no link
-                               // to avoid glitches of the edition life cycle
-                               lbl.setText(text);
-               } else if (child instanceof Text) {
-                       Text txt = (Text) child;
-                       if (EclipseUiUtils.isEmpty(text)) {
-                               txt.setText("");
-                               txt.setMessage(message);
-                       } else
-                               txt.setText(text);
-               }
-       }
-
-       private void setLinkValue(Label lbl, String text) {
-               if (FormStyle.email.style().equals(type))
-                       lbl.setText(FormUtils.getMailLink(text));
-               else if (FormStyle.phone.style().equals(type))
-                       lbl.setText(FormUtils.getPhoneLink(text));
-               else if (FormStyle.website.style().equals(type))
-                       lbl.setText(FormUtils.getUrlLink(text));
-               else if (FormStyle.facebook.style().equals(type)
-                               || FormStyle.instagram.style().equals(type)
-                               || FormStyle.linkedIn.style().equals(type)
-                               || FormStyle.twitter.style().equals(type))
-                       lbl.setText(FormUtils.getUrlLink(text));
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditableMultiStringProperty.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditableMultiStringProperty.java
deleted file mode 100644 (file)
index ff82700..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.SwtEditablePart;
-import org.argeo.cms.ui.widgets.StyledControl;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** Display, add or remove values from a list in a CMS context */
-public class EditableMultiStringProperty extends StyledControl implements SwtEditablePart {
-       private static final long serialVersionUID = -7044614381252178595L;
-
-       private String propertyName;
-       private String message;
-       // TODO implement the ability to provide a list of possible values
-//     private String[] possibleValues;
-       private boolean canEdit;
-       private SelectionListener removeValueSL;
-       private List<String> values;
-
-       // TODO manage within the CSS
-       private int rowSpacing = 5;
-       private int rowMarging = 0;
-       private int oneValueMargingRight = 5;
-       private int btnWidth = 16;
-       private int btnHeight = 16;
-       private int btnHorizontalIndent = 3;
-
-       public EditableMultiStringProperty(Composite parent, int style, Node node, String propertyName, List<String> values,
-                       String[] possibleValues, String addValueMsg, SelectionListener removeValueSelectionListener)
-                       throws RepositoryException {
-               super(parent, style, node, true);
-
-               this.propertyName = propertyName;
-               this.values = values;
-//             this.possibleValues = new String[] { "Un", "Deux", "Trois" };
-               this.message = addValueMsg;
-               this.canEdit = removeValueSelectionListener != null;
-               this.removeValueSL = removeValueSelectionListener;
-       }
-
-       public List<String> getValues() {
-               return values;
-       }
-
-       public void setValues(List<String> values) {
-               this.values = values;
-       }
-
-       // Row layout items do not need explicit layout data
-       protected void setControlLayoutData(Control control) {
-       }
-
-       /** To be overridden */
-       protected void setContainerLayoutData(Composite composite) {
-               composite.setLayoutData(CmsSwtUtils.fillWidth());
-       }
-
-       @Override
-       public Control getControl() {
-               return super.getControl();
-       }
-
-       @Override
-       protected Control createControl(Composite box, String style) {
-               Composite row = new Composite(box, SWT.NO_FOCUS);
-               row.setLayoutData(EclipseUiUtils.fillAll());
-
-               RowLayout rl = new RowLayout(SWT.HORIZONTAL);
-               rl.wrap = true;
-               rl.spacing = rowSpacing;
-               rl.marginRight = rl.marginLeft = rl.marginBottom = rl.marginTop = rowMarging;
-               row.setLayout(rl);
-
-               if (values != null) {
-                       for (final String value : values) {
-                               if (canEdit)
-                                       createRemovableValue(row, SWT.SINGLE, value);
-                               else
-                                       createValueLabel(row, SWT.SINGLE, value);
-                       }
-               }
-
-               if (!canEdit)
-                       return row;
-               else if (isEditing())
-                       return createText(row, style);
-               else
-                       return createLabel(row, style);
-       }
-
-       /**
-        * Override to provide specific layout for the existing values, typically adding
-        * a pound (#) char for tags or anchor info for browsable links. We assume the
-        * parent composite already has a layout and it is the caller responsibility to
-        * apply corresponding layout data
-        */
-       protected Label createValueLabel(Composite parent, int style, String value) {
-               Label label = new Label(parent, style);
-               label.setText("#" + value);
-               CmsSwtUtils.markup(label);
-               CmsSwtUtils.style(label, FormStyle.propertyText.style());
-               return label;
-       }
-
-       private Composite createRemovableValue(Composite parent, int style, String value) {
-               Composite valCmp = new Composite(parent, SWT.NO_FOCUS);
-               GridLayout gl = EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false));
-               gl.marginRight = oneValueMargingRight;
-               valCmp.setLayout(gl);
-
-               createValueLabel(valCmp, SWT.WRAP, value);
-
-               Button deleteBtn = new Button(valCmp, SWT.FLAT);
-               deleteBtn.setData(FormConstants.LINKED_VALUE, value);
-               deleteBtn.addSelectionListener(removeValueSL);
-               CmsSwtUtils.style(deleteBtn, FormStyle.delete.style() + FormStyle.BUTTON_SUFFIX);
-               GridData gd = new GridData();
-               gd.heightHint = btnHeight;
-               gd.widthHint = btnWidth;
-               gd.horizontalIndent = btnHorizontalIndent;
-               deleteBtn.setLayoutData(gd);
-
-               return valCmp;
-       }
-
-       protected Text createText(Composite box, String style) {
-               final Text text = new Text(box, getStyle());
-               // The "add new value" text is not meant to change, so we can set it on
-               // creation
-               text.setMessage(message);
-               CmsSwtUtils.style(text, style);
-               text.setFocus();
-
-               text.addTraverseListener(new TraverseListener() {
-                       private static final long serialVersionUID = 1L;
-
-                       public void keyTraversed(TraverseEvent e) {
-                               if (e.keyCode == SWT.CR) {
-                                       addValue(text);
-                                       e.doit = false;
-                               }
-                       }
-               });
-
-               // The OK button does not work with the focusOut listener
-               // because focus out is called before the OK button is pressed
-
-               // // we must call layout() now so that the row data can compute the
-               // height
-               // // of the other controls.
-               // text.getParent().layout();
-               // int height = text.getSize().y;
-               //
-               // Button okBtn = new Button(box, SWT.BORDER | SWT.PUSH | SWT.BOTTOM);
-               // okBtn.setText("OK");
-               // RowData rd = new RowData(SWT.DEFAULT, height - 2);
-               // okBtn.setLayoutData(rd);
-               //
-               // okBtn.addSelectionListener(new SelectionAdapter() {
-               // private static final long serialVersionUID = 2780819012423622369L;
-               //
-               // @Override
-               // public void widgetSelected(SelectionEvent e) {
-               // addValue(text);
-               // }
-               // });
-
-               return text;
-       }
-
-       /** Performs the real addition, overwrite to make further sanity checks */
-       protected void addValue(Text text) {
-               String value = text.getText();
-               String errMsg = null;
-
-               if (EclipseUiUtils.isEmpty(value))
-                       return;
-
-               if (values.contains(value))
-                       errMsg = "Dupplicated value: " + value + ", please correct and try again";
-               if (errMsg != null)
-                       MessageDialog.openError(this.getShell(), "Addition not allowed", errMsg);
-               else {
-                       values.add(value);
-                       Composite newCmp = createRemovableValue(text.getParent(), SWT.SINGLE, value);
-                       newCmp.moveAbove(text);
-                       text.setText("");
-                       newCmp.getParent().layout();
-               }
-       }
-
-       protected Label createLabel(Composite box, String style) {
-               if (canEdit) {
-                       Label lbl = new Label(box, getStyle());
-                       lbl.setText(message);
-                       CmsSwtUtils.style(lbl, style);
-                       CmsSwtUtils.markup(lbl);
-                       if (mouseListener != null)
-                               lbl.addMouseListener(mouseListener);
-                       return lbl;
-               }
-               return null;
-       }
-
-       protected void clear(boolean deep) {
-               Control child = getControl();
-               if (deep)
-                       super.clear(deep);
-               else {
-                       child.getParent().dispose();
-               }
-       }
-
-       public void setText(String text) {
-               Control child = getControl();
-               if (child instanceof Label) {
-                       Label lbl = (Label) child;
-                       if (canEdit)
-                               lbl.setText(text);
-                       else
-                               lbl.setText("");
-               } else if (child instanceof Text) {
-                       Text txt = (Text) child;
-                       txt.setText(text);
-               }
-       }
-
-       public synchronized void startEditing() {
-               CmsSwtUtils.style(getControl(), FormStyle.propertyText.style());
-//             getControl().setData(STYLE, FormStyle.propertyText.style());
-               super.startEditing();
-       }
-
-       public synchronized void stopEditing() {
-               CmsSwtUtils.style(getControl(), FormStyle.propertyMessage.style());
-//             getControl().setData(STYLE, FormStyle.propertyMessage.style());
-               super.stopEditing();
-       }
-
-       public String getPropertyName() {
-               return propertyName;
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditablePropertyDate.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditablePropertyDate.java
deleted file mode 100644 (file)
index 641f916..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import java.text.DateFormat;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.SwtEditablePart;
-import org.argeo.cms.ui.widgets.StyledControl;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.DateTime;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/** CMS form part to display and edit a date */
-public class EditablePropertyDate extends StyledControl implements SwtEditablePart {
-       private static final long serialVersionUID = 2500215515778162468L;
-
-       // Context
-       private String propertyName;
-       private String message;
-       private DateFormat dateFormat;
-
-       // UI Objects
-       private Text dateTxt;
-       private Button openCalBtn;
-
-       // TODO manage within the CSS
-       private int fieldBtnSpacing = 5;
-
-       /**
-        * 
-        * @param parent
-        * @param style
-        * @param node
-        * @param propertyName
-        * @param message
-        * @param dateFormat   provide a {@link DateFormat} as contract to be able to
-        *                     read/write dates as strings
-        * @throws RepositoryException
-        */
-       public EditablePropertyDate(Composite parent, int style, Node node, String propertyName, String message,
-                       DateFormat dateFormat) throws RepositoryException {
-               super(parent, style, node, false);
-
-               this.propertyName = propertyName;
-               this.message = message;
-               this.dateFormat = dateFormat;
-
-               if (node.hasProperty(propertyName)) {
-                       this.setStyle(FormStyle.propertyText.style());
-                       this.setText(dateFormat.format(node.getProperty(propertyName).getDate().getTime()));
-               } else {
-                       this.setStyle(FormStyle.propertyMessage.style());
-                       this.setText(message);
-               }
-       }
-
-       public void setText(String text) {
-               Control child = getControl();
-               if (child instanceof Label) {
-                       Label lbl = (Label) child;
-                       if (EclipseUiUtils.isEmpty(text))
-                               lbl.setText(message);
-                       else
-                               lbl.setText(text);
-               } else if (child instanceof Text) {
-                       Text txt = (Text) child;
-                       if (EclipseUiUtils.isEmpty(text)) {
-                               txt.setText("");
-                       } else
-                               txt.setText(text);
-               }
-       }
-
-       public synchronized void startEditing() {
-               // if (dateTxt != null && !dateTxt.isDisposed())
-               CmsSwtUtils.style(getControl(), FormStyle.propertyText);
-//             getControl().setData(STYLE, FormStyle.propertyText.style());
-               super.startEditing();
-       }
-
-       public synchronized void stopEditing() {
-               if (EclipseUiUtils.isEmpty(dateTxt.getText()))
-                       CmsSwtUtils.style(getControl(), FormStyle.propertyMessage);
-//                     getControl().setData(STYLE, FormStyle.propertyMessage.style());
-               else
-                       CmsSwtUtils.style(getControl(), FormStyle.propertyText);
-//             getControl().setData(STYLE, FormStyle.propertyText.style());
-               super.stopEditing();
-       }
-
-       public String getPropertyName() {
-               return propertyName;
-       }
-
-       @Override
-       protected Control createControl(Composite box, String style) {
-               if (isEditing()) {
-                       return createCustomEditableControl(box, style);
-               } else
-                       return createLabel(box, style);
-       }
-
-       protected Label createLabel(Composite box, String style) {
-               Label lbl = new Label(box, getStyle() | SWT.WRAP);
-               lbl.setLayoutData(CmsSwtUtils.fillWidth());
-               CmsSwtUtils.style(lbl, style);
-               CmsSwtUtils.markup(lbl);
-               if (mouseListener != null)
-                       lbl.addMouseListener(mouseListener);
-               return lbl;
-       }
-
-       private Control createCustomEditableControl(Composite box, String style) {
-               box.setLayoutData(CmsSwtUtils.fillWidth());
-               Composite dateComposite = new Composite(box, SWT.NONE);
-               GridLayout gl = EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false));
-               gl.horizontalSpacing = fieldBtnSpacing;
-               dateComposite.setLayout(gl);
-               dateTxt = new Text(dateComposite, SWT.BORDER);
-               CmsSwtUtils.style(dateTxt, style);
-               dateTxt.setLayoutData(new GridData(120, SWT.DEFAULT));
-               dateTxt.setToolTipText(
-                               "Enter a date with form \"" + FormUtils.DEFAULT_SHORT_DATE_FORMAT + "\" or use the calendar");
-               openCalBtn = new Button(dateComposite, SWT.FLAT);
-               CmsSwtUtils.style(openCalBtn, FormStyle.calendar.style() + FormStyle.BUTTON_SUFFIX);
-               GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
-               gd.heightHint = 17;
-               openCalBtn.setLayoutData(gd);
-               // openCalBtn.setImage(PeopleRapImages.CALENDAR_BTN);
-
-               openCalBtn.addSelectionListener(new SelectionAdapter() {
-                       private static final long serialVersionUID = 1L;
-
-                       public void widgetSelected(SelectionEvent event) {
-                               CalendarPopup popup = new CalendarPopup(dateTxt);
-                               popup.open();
-                       }
-               });
-
-               // dateTxt.addFocusListener(new FocusListener() {
-               // private static final long serialVersionUID = 1L;
-               //
-               // @Override
-               // public void focusLost(FocusEvent event) {
-               // String newVal = dateTxt.getText();
-               // // Enable reset of the field
-               // if (FormUtils.notNull(newVal))
-               // calendar = null;
-               // else {
-               // try {
-               // Calendar newCal = parseDate(newVal);
-               // // DateText.this.setText(newCal);
-               // calendar = newCal;
-               // } catch (ParseException pe) {
-               // // Silent. Manage error popup?
-               // if (calendar != null)
-               // EditablePropertyDate.this.setText(calendar);
-               // }
-               // }
-               // }
-               //
-               // @Override
-               // public void focusGained(FocusEvent event) {
-               // }
-               // });
-               return dateTxt;
-       }
-
-       protected void clear(boolean deep) {
-               Control child = getControl();
-               if (deep || child instanceof Label)
-                       super.clear(deep);
-               else {
-                       child.getParent().dispose();
-               }
-       }
-
-       /** Enable setting a custom tooltip on the underlying text */
-       @Deprecated
-       public void setToolTipText(String toolTipText) {
-               dateTxt.setToolTipText(toolTipText);
-       }
-
-       @Deprecated
-       /** Enable setting a custom message on the underlying text */
-       public void setMessage(String message) {
-               dateTxt.setMessage(message);
-       }
-
-       @Deprecated
-       public void setText(Calendar cal) {
-               String newValueStr = "";
-               if (cal != null)
-                       newValueStr = dateFormat.format(cal.getTime());
-               if (!newValueStr.equals(dateTxt.getText()))
-                       dateTxt.setText(newValueStr);
-       }
-
-       // UTILITIES TO MANAGE THE CALENDAR POPUP
-       // TODO manage the popup shell in a cleaner way
-       private class CalendarPopup extends Shell {
-               private static final long serialVersionUID = 1L;
-               private DateTime dateTimeCtl;
-
-               public CalendarPopup(Control source) {
-                       super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
-                       populate();
-                       // Add border and shadow style
-                       CmsSwtUtils.markup(CalendarPopup.this);
-                       CmsSwtUtils.style(CalendarPopup.this, FormStyle.popupCalendar.style());
-                       pack();
-                       layout();
-                       setLocation(source.toDisplay((source.getLocation().x - 2), (source.getSize().y) + 3));
-
-                       addShellListener(new ShellAdapter() {
-                               private static final long serialVersionUID = 5178980294808435833L;
-
-                               @Override
-                               public void shellDeactivated(ShellEvent e) {
-                                       close();
-                                       dispose();
-                               }
-                       });
-                       open();
-               }
-
-               private void setProperty() {
-                       // Direct set does not seems to work. investigate
-                       // cal.set(dateTimeCtl.getYear(), dateTimeCtl.getMonth(),
-                       // dateTimeCtl.getDay(), 12, 0);
-                       Calendar cal = new GregorianCalendar();
-                       cal.set(Calendar.YEAR, dateTimeCtl.getYear());
-                       cal.set(Calendar.MONTH, dateTimeCtl.getMonth());
-                       cal.set(Calendar.DAY_OF_MONTH, dateTimeCtl.getDay());
-                       String dateStr = dateFormat.format(cal.getTime());
-                       dateTxt.setText(dateStr);
-               }
-
-               protected void populate() {
-                       setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-                       dateTimeCtl = new DateTime(this, SWT.CALENDAR);
-                       dateTimeCtl.setLayoutData(EclipseUiUtils.fillAll());
-
-                       Calendar calendar = FormUtils.parseDate(dateFormat, dateTxt.getText());
-
-                       if (calendar != null)
-                               dateTimeCtl.setDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
-                                               calendar.get(Calendar.DAY_OF_MONTH));
-
-                       dateTimeCtl.addSelectionListener(new SelectionAdapter() {
-                               private static final long serialVersionUID = -8414377364434281112L;
-
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       setProperty();
-                               }
-                       });
-
-                       dateTimeCtl.addMouseListener(new MouseListener() {
-                               private static final long serialVersionUID = 1L;
-
-                               @Override
-                               public void mouseUp(MouseEvent e) {
-                               }
-
-                               @Override
-                               public void mouseDown(MouseEvent e) {
-                               }
-
-                               @Override
-                               public void mouseDoubleClick(MouseEvent e) {
-                                       setProperty();
-                                       close();
-                                       dispose();
-                               }
-                       });
-               }
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditablePropertyString.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/EditablePropertyString.java
deleted file mode 100644 (file)
index f2575e1..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import static org.argeo.cms.ui.forms.FormStyle.propertyMessage;
-import static org.argeo.cms.ui.forms.FormStyle.propertyText;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.SwtEditablePart;
-import org.argeo.cms.ui.widgets.EditableText;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** Editable String in a CMS context */
-public class EditablePropertyString extends EditableText implements SwtEditablePart {
-       private static final long serialVersionUID = 5055000749992803591L;
-
-       private String propertyName;
-       private String message;
-
-       // encode the '&' character in rap
-       private final static String AMPERSAND = "&#38;";
-       private final static String AMPERSAND_REGEX = "&(?![#a-zA-Z0-9]+;)";
-
-       public EditablePropertyString(Composite parent, int style, Node node, String propertyName, String message)
-                       throws RepositoryException {
-               super(parent, style, node, true);
-               //setUseTextAsLabel(true);
-               this.propertyName = propertyName;
-               this.message = message;
-
-               if (node.hasProperty(propertyName)) {
-                       this.setStyle(propertyText.style());
-                       this.setText(node.getProperty(propertyName).getString());
-               } else {
-                       this.setStyle(propertyMessage.style());
-                       this.setText(message + "  ");
-               }
-       }
-
-       public void setText(String text) {
-               Control child = getControl();
-               if (child instanceof Label) {
-                       Label lbl = (Label) child;
-                       if (EclipseUiUtils.isEmpty(text))
-                               lbl.setText(message + "  ");
-                       else
-                               // TODO enhance this
-                               lbl.setText(text.replaceAll(AMPERSAND_REGEX, AMPERSAND));
-               } else if (child instanceof Text) {
-                       Text txt = (Text) child;
-                       if (EclipseUiUtils.isEmpty(text)) {
-                               txt.setText("");
-                               txt.setMessage(message + " ");
-                       } else
-                               txt.setText(text.replaceAll("<br/>", "\n"));
-               }
-       }
-
-       public synchronized void startEditing() {
-               CmsSwtUtils.style(getControl(), FormStyle.propertyText);
-               super.startEditing();
-       }
-
-       public synchronized void stopEditing() {
-               if (EclipseUiUtils.isEmpty(((Text) getControl()).getText()))
-                       CmsSwtUtils.style(getControl(), FormStyle.propertyMessage);
-               else
-                       CmsSwtUtils.style(getControl(), FormStyle.propertyText);
-               super.stopEditing();
-       }
-
-       public String getPropertyName() {
-               return propertyName;
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormConstants.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormConstants.java
deleted file mode 100644 (file)
index fe9f7e7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-/** Constants used in the various CMS Forms */
-public interface FormConstants {
-       // DATAKEYS
-       public final static String LINKED_VALUE = "LinkedValue";
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormEditorHeader.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormEditorHeader.java
deleted file mode 100644 (file)
index a75c191..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import java.util.Observable;
-import java.util.Observer;
-
-import javax.jcr.Node;
-
-import org.argeo.api.cms.ux.CmsEditable;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-
-/** Add life cycle management abilities to an editable form page */
-public class FormEditorHeader implements SelectionListener, Observer {
-       private static final long serialVersionUID = 7392898696542484282L;
-
-       // private final Node context;
-       private final CmsEditable cmsEditable;
-       private Button publishBtn;
-
-       // Should we provide here the ability to switch from read only to edition
-       // mode?
-       // private Button editBtn;
-       // private boolean readOnly;
-
-       // TODO add information about the current node status, typically if it is
-       // dirty or not
-
-       private Composite parent;
-       private Composite display;
-       private Object layoutData;
-
-       public FormEditorHeader(Composite parent, int style, Node context,
-                       CmsEditable cmsEditable) {
-               this.cmsEditable = cmsEditable;
-               this.parent = parent;
-               // readOnly = SWT.READ_ONLY == (style & SWT.READ_ONLY);
-               // this.context = context;
-               if (this.cmsEditable instanceof Observable)
-                       ((Observable) this.cmsEditable).addObserver(this);
-               refresh();
-       }
-
-       public void setLayoutData(Object layoutData) {
-               this.layoutData = layoutData;
-               if (display != null && !display.isDisposed())
-                       display.setLayoutData(layoutData);
-       }
-
-       protected void refresh() {
-               if (display != null && !display.isDisposed())
-                       display.dispose();
-
-               display = new Composite(parent, SWT.NONE);
-               display.setLayoutData(layoutData);
-
-               CmsSwtUtils.style(display, FormStyle.header.style());
-               display.setBackgroundMode(SWT.INHERIT_FORCE);
-
-               display.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
-               publishBtn = createSimpleBtn(display, getPublishButtonLabel());
-               display.moveAbove(null);
-               parent.layout();
-       }
-
-       private Button createSimpleBtn(Composite parent, String label) {
-               Button button = new Button(parent, SWT.FLAT | SWT.PUSH);
-               button.setText(label);
-               CmsSwtUtils.style(button, FormStyle.header.style());
-               button.addSelectionListener(this);
-               return button;
-       }
-
-       private String getPublishButtonLabel() {
-               // Rather check if the current node differs from what has been
-               // previously committed
-               // For the time being, we always reach here, the underlying CmsEditable
-               // is always editing.
-               if (cmsEditable.isEditing())
-                       return " Publish ";
-               else
-                       return " Edit ";
-       }
-
-       @Override
-       public void widgetSelected(SelectionEvent e) {
-               if (e.getSource() == publishBtn) {
-                       // For the time being, the underlying CmsEditable
-                       // is always editing when we reach this point
-                       if (cmsEditable.isEditing()) {
-                               // we always leave the node in a check outed state
-                               cmsEditable.stopEditing();
-                               cmsEditable.startEditing();
-                       } else {
-                               cmsEditable.startEditing();
-                       }
-               }
-       }
-
-       @Override
-       public void widgetDefaultSelected(SelectionEvent e) {
-       }
-
-       @Override
-       public void update(Observable o, Object arg) {
-               if (o == cmsEditable) {
-                       refresh();
-               }
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java
deleted file mode 100644 (file)
index 1888055..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFormatException;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.api.cms.ux.CmsEditable;
-import org.argeo.api.cms.ux.CmsImageManager;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.SwtEditablePart;
-import org.argeo.cms.ui.viewers.AbstractPageViewer;
-import org.argeo.cms.ui.viewers.Section;
-import org.argeo.cms.ui.viewers.SectionPart;
-import org.argeo.cms.ui.widgets.EditableImage;
-import org.argeo.cms.ui.widgets.Img;
-import org.argeo.cms.ui.widgets.StyledControl;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.rap.fileupload.FileDetails;
-import org.eclipse.rap.fileupload.FileUploadEvent;
-import org.eclipse.rap.fileupload.FileUploadHandler;
-import org.eclipse.rap.fileupload.FileUploadListener;
-import org.eclipse.rap.fileupload.FileUploadReceiver;
-import org.eclipse.rap.rwt.service.ServerPushSession;
-import org.eclipse.rap.rwt.widgets.FileUpload;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-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 CmsLog log = CmsLog.getLog(FormPageViewer.class);
-       private static final long serialVersionUID = 5277789504209413500L;
-
-       private final Section mainSection;
-
-       // TODO manage within the CSS
-       private Integer labelColWidth = null;
-       private int rowLayoutHSpacing = 8;
-
-       // Context cached in the viewer
-       // The reference to translate from text to calendar and reverse
-       private DateFormat dateFormat = new SimpleDateFormat(FormUtils.DEFAULT_SHORT_DATE_FORMAT);
-       private CmsImageManager<Control, Node> imageManager;
-       private FileUploadListener fileUploadListener;
-
-       public FormPageViewer(Section mainSection, int style, CmsEditable cmsEditable) throws RepositoryException {
-               super(mainSection, style, cmsEditable);
-               this.mainSection = mainSection;
-
-               if (getCmsEditable().canEdit()) {
-                       fileUploadListener = new FUL();
-               }
-       }
-
-       @Override
-       protected void prepare(SwtEditablePart part, Object caretPosition) {
-               if (part instanceof Img) {
-                       ((Img) part).setFileUploadListener(fileUploadListener);
-               }
-       }
-
-       /** To be overridden.Save the edited part. */
-       protected void save(SwtEditablePart part) throws RepositoryException {
-               Node node = null;
-               if (part instanceof EditableMultiStringProperty) {
-                       EditableMultiStringProperty ept = (EditableMultiStringProperty) part;
-                       // SWT : View
-                       List<String> values = ept.getValues();
-                       // JCR : Model
-                       node = ept.getNode();
-                       String propName = ept.getPropertyName();
-                       if (values.isEmpty()) {
-                               if (node.hasProperty(propName))
-                                       node.getProperty(propName).remove();
-                       } else {
-                               node.setProperty(propName, values.toArray(new String[0]));
-                       }
-                       // => Viewer : Controller
-               } else if (part instanceof EditablePropertyString) {
-                       EditablePropertyString ept = (EditablePropertyString) part;
-                       // SWT : View
-                       String txt = ((Text) ept.getControl()).getText();
-                       // JCR : Model
-                       node = ept.getNode();
-                       String propName = ept.getPropertyName();
-                       if (EclipseUiUtils.isEmpty(txt)) {
-                               if (node.hasProperty(propName))
-                                       node.getProperty(propName).remove();
-                       } else {
-                               setPropertySilently(node, propName, txt);
-                               // node.setProperty(propName, txt);
-                       }
-                       // node.getSession().save();
-                       // => Viewer : Controller
-               } else if (part instanceof EditablePropertyDate) {
-                       EditablePropertyDate ept = (EditablePropertyDate) part;
-                       Calendar cal = FormUtils.parseDate(dateFormat, ((Text) ept.getControl()).getText());
-                       node = ept.getNode();
-                       String propName = ept.getPropertyName();
-                       if (cal == null) {
-                               if (node.hasProperty(propName))
-                                       node.getProperty(propName).remove();
-                       } else {
-                               node.setProperty(propName, cal);
-                       }
-                       // node.getSession().save();
-                       // => Viewer : Controller
-               }
-               // TODO: make this configurable, sometimes we do not want to save the
-               // current session at this stage
-               if (node != null && node.getSession().hasPendingChanges()) {
-                       JcrUtils.updateLastModified(node, true);
-                       node.getSession().save();
-               }
-       }
-
-       @Override
-       protected void updateContent(SwtEditablePart part) throws RepositoryException {
-               if (part instanceof EditableMultiStringProperty) {
-                       EditableMultiStringProperty ept = (EditableMultiStringProperty) part;
-                       // SWT : View
-                       Node node = ept.getNode();
-                       String propName = ept.getPropertyName();
-                       List<String> valStrings = new ArrayList<String>();
-                       if (node.hasProperty(propName)) {
-                               Value[] values = node.getProperty(propName).getValues();
-                               for (Value val : values)
-                                       valStrings.add(val.getString());
-                       }
-                       ept.setValues(valStrings);
-               } else if (part instanceof EditablePropertyString) {
-                       // || part instanceof EditableLink
-                       EditablePropertyString ept = (EditablePropertyString) part;
-                       // JCR : Model
-                       Node node = ept.getNode();
-                       String propName = ept.getPropertyName();
-                       if (node.hasProperty(propName)) {
-                               String value = node.getProperty(propName).getString();
-                               ept.setText(value);
-                       } else
-                               ept.setText("");
-                       // => Viewer : Controller
-               } else if (part instanceof EditablePropertyDate) {
-                       EditablePropertyDate ept = (EditablePropertyDate) part;
-                       // JCR : Model
-                       Node node = ept.getNode();
-                       String propName = ept.getPropertyName();
-                       if (node.hasProperty(propName))
-                               ept.setText(dateFormat.format(node.getProperty(propName).getDate().getTime()));
-                       else
-                               ept.setText("");
-               } else if (part instanceof SectionPart) {
-                       SectionPart sectionPart = (SectionPart) part;
-                       Node partNode = sectionPart.getNode();
-                       // use control AFTER setting style, since it may have been reset
-                       if (part instanceof EditableImage) {
-                               EditableImage editableImage = (EditableImage) part;
-                               imageManager().load(partNode, part.getControl(), editableImage.getPreferredImageSize());
-                       }
-               }
-       }
-
-       // FILE UPLOAD LISTENER
-       protected class FUL implements FileUploadListener {
-
-               public FUL() {
-               }
-
-               public void uploadProgress(FileUploadEvent event) {
-                       // TODO Monitor upload progress
-               }
-
-               public void uploadFailed(FileUploadEvent event) {
-                       throw new IllegalStateException("Upload failed " + event, event.getException());
-               }
-
-               public void uploadFinished(FileUploadEvent event) {
-                       for (FileDetails file : event.getFileDetails()) {
-                               if (log.isDebugEnabled())
-                                       log.debug("Received: " + file.getFileName());
-                       }
-                       mainSection.getDisplay().syncExec(new Runnable() {
-                               @Override
-                               public void run() {
-                                       saveEdit();
-                               }
-                       });
-                       FileUploadHandler uploadHandler = (FileUploadHandler) event.getSource();
-                       uploadHandler.dispose();
-               }
-       }
-
-       // FOCUS OUT LISTENER
-       protected FocusListener createFocusListener() {
-               return new FocusOutListener();
-       }
-
-       private class FocusOutListener implements FocusListener {
-               private static final long serialVersionUID = -6069205786732354186L;
-
-               @Override
-               public void focusLost(FocusEvent event) {
-                       saveEdit();
-               }
-
-               @Override
-               public void focusGained(FocusEvent event) {
-                       // does nothing;
-               }
-       }
-
-       // MOUSE LISTENER
-       @Override
-       protected MouseListener createMouseListener() {
-               return new ML();
-       }
-
-       private class ML extends MouseAdapter {
-               private static final long serialVersionUID = 8526890859876770905L;
-
-               @Override
-               public void mouseDoubleClick(MouseEvent e) {
-                       if (e.button == 1) {
-                               Control source = (Control) e.getSource();
-                               if (getCmsEditable().canEdit()) {
-                                       if (getCmsEditable().isEditing() && !(getEdited() instanceof Img)) {
-                                               if (source == mainSection)
-                                                       return;
-                                               SwtEditablePart part = findDataParent(source);
-                                               upload(part);
-                                       } else {
-                                               getCmsEditable().startEditing();
-                                       }
-                               }
-                       }
-               }
-
-               @Override
-               public void mouseDown(MouseEvent e) {
-                       if (getCmsEditable().isEditing()) {
-                               if (e.button == 1) {
-                                       Control source = (Control) e.getSource();
-                                       SwtEditablePart composite = findDataParent(source);
-                                       Point point = new Point(e.x, e.y);
-                                       if (!(composite instanceof Img))
-                                               edit(composite, source.toDisplay(point));
-                               } else if (e.button == 3) {
-                                       // EditablePart composite = findDataParent((Control) e
-                                       // .getSource());
-                                       // if (styledTools != null)
-                                       // styledTools.show(composite, new Point(e.x, e.y));
-                               }
-                       }
-               }
-
-               protected synchronized void upload(SwtEditablePart part) {
-                       if (part instanceof SectionPart) {
-                               if (part instanceof Img) {
-                                       if (getEdited() == part)
-                                               return;
-                                       edit(part, null);
-                                       layout(part.getControl());
-                               }
-                       }
-               }
-       }
-
-       @Override
-       public Control getControl() {
-               return mainSection;
-       }
-
-       protected CmsImageManager<Control, Node> imageManager() {
-               if (imageManager == null)
-                       imageManager = (CmsImageManager<Control, Node>) CmsSwtUtils.getCmsView(mainSection).getImageManager();
-               return imageManager;
-       }
-
-       // LOCAL UI HELPERS
-       protected Section createSectionIfNeeded(Composite body, Node node) throws RepositoryException {
-               Section section = null;
-               if (node != null) {
-                       section = new Section(body, SWT.NO_FOCUS, node);
-                       section.setLayoutData(CmsSwtUtils.fillWidth());
-                       section.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               }
-               return section;
-       }
-
-       protected void createSimpleLT(Composite bodyRow, Node node, String propName, String label, String msg)
-                       throws RepositoryException {
-               if (getCmsEditable().canEdit() || node.hasProperty(propName)) {
-                       createPropertyLbl(bodyRow, label);
-                       EditablePropertyString eps = new EditablePropertyString(bodyRow, SWT.WRAP | SWT.LEFT, node, propName, msg);
-                       eps.setMouseListener(getMouseListener());
-                       eps.setFocusListener(getFocusListener());
-                       eps.setLayoutData(CmsSwtUtils.fillWidth());
-               }
-       }
-
-       protected void createMultiStringLT(Composite bodyRow, Node node, String propName, String label, String msg)
-                       throws RepositoryException {
-               boolean canEdit = getCmsEditable().canEdit();
-               if (canEdit || node.hasProperty(propName)) {
-                       createPropertyLbl(bodyRow, label);
-
-                       List<String> valueStrings = new ArrayList<String>();
-
-                       if (node.hasProperty(propName)) {
-                               Value[] values = node.getProperty(propName).getValues();
-                               for (Value value : values)
-                                       valueStrings.add(value.getString());
-                       }
-
-                       // TODO use a drop down to display possible values to the end user
-                       EditableMultiStringProperty emsp = new EditableMultiStringProperty(bodyRow, SWT.SINGLE | SWT.LEAD, node,
-                                       propName, valueStrings, new String[] { "Implement this" }, msg,
-                                       canEdit ? getRemoveValueSelListener() : null);
-                       addListeners(emsp);
-                       // emsp.setMouseListener(getMouseListener());
-                       emsp.setStyle(FormStyle.propertyMessage.style());
-                       emsp.setLayoutData(CmsSwtUtils.fillWidth());
-               }
-       }
-
-       protected Label createPropertyLbl(Composite parent, String value) {
-               return createPropertyLbl(parent, value, SWT.NONE);
-       }
-
-       protected Label createPropertyLbl(Composite parent, String value, int vAlign) {
-               // boolean isSmall = CmsView.getCmsView(parent).getUxContext().isSmall();
-               Label label = new Label(parent, SWT.LEAD | SWT.WRAP);
-               label.setText(value + " ");
-               CmsSwtUtils.style(label, FormStyle.propertyLabel.style());
-               GridData gd = new GridData(SWT.LEAD, vAlign, false, false);
-               if (labelColWidth != null)
-                       gd.widthHint = labelColWidth;
-               label.setLayoutData(gd);
-               return label;
-       }
-
-       protected Label newStyledLabel(Composite parent, String style, String value) {
-               Label label = new Label(parent, SWT.NONE);
-               label.setText(value);
-               CmsSwtUtils.style(label, style);
-               return label;
-       }
-
-       protected Composite createRowLayoutComposite(Composite parent) throws RepositoryException {
-               Composite bodyRow = new Composite(parent, SWT.NO_FOCUS);
-               bodyRow.setLayoutData(CmsSwtUtils.fillWidth());
-               RowLayout rl = new RowLayout(SWT.WRAP);
-               rl.type = SWT.HORIZONTAL;
-               rl.spacing = rowLayoutHSpacing;
-               rl.marginHeight = rl.marginWidth = 0;
-               rl.marginTop = rl.marginBottom = rl.marginLeft = rl.marginRight = 0;
-               bodyRow.setLayout(rl);
-               return bodyRow;
-       }
-
-       protected Composite createAddImgComposite(final Section section, Composite parent, final Node parentNode)
-                       throws RepositoryException {
-
-               Composite body = new Composite(parent, SWT.NO_FOCUS);
-               body.setLayout(new GridLayout());
-
-               FormFileUploadReceiver receiver = new FormFileUploadReceiver(section, parentNode, null);
-               final FileUploadHandler currentUploadHandler = new FileUploadHandler(receiver);
-               if (fileUploadListener != null)
-                       currentUploadHandler.addUploadListener(fileUploadListener);
-
-               // Button creation
-               final FileUpload fileUpload = new FileUpload(body, SWT.BORDER);
-               fileUpload.setText("Import an image");
-               fileUpload.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
-               fileUpload.addSelectionListener(new SelectionAdapter() {
-                       private static final long serialVersionUID = 4869523412991968759L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               ServerPushSession pushSession = new ServerPushSession();
-                               pushSession.start();
-                               String uploadURL = currentUploadHandler.getUploadUrl();
-                               fileUpload.submit(uploadURL);
-                       }
-               });
-
-               return body;
-       }
-
-       protected class FormFileUploadReceiver extends FileUploadReceiver {
-
-               private Node context;
-               private Section section;
-               private String name;
-
-               public FormFileUploadReceiver(Section section, Node context, String name) {
-                       this.context = context;
-                       this.section = section;
-                       this.name = name;
-               }
-
-               @Override
-               public void receive(InputStream stream, FileDetails details) throws IOException {
-
-                       if (name == null)
-                               name = details.getFileName();
-
-                       // TODO clean image name more carefully
-                       String cleanedName = name.replaceAll("[^a-zA-Z0-9-.]", "");
-                       // We add a unique prefix to workaround the cache issue: when
-                       // deleting and re-adding a new image with same name, the end user
-                       // browser will use the cache and the image will remain unchanged
-                       // for a while
-                       cleanedName = System.currentTimeMillis() % 100000 + "_" + cleanedName;
-
-                       imageManager().uploadImage(context, context, cleanedName, stream, details.getContentType());
-                       // TODO clean refresh strategy
-                       section.getDisplay().asyncExec(new Runnable() {
-                               @Override
-                               public void run() {
-                                       try {
-                                               FormPageViewer.this.refresh(section);
-                                               section.layout();
-                                               section.getParent().layout();
-                                       } catch (RepositoryException re) {
-                                               throw new JcrException("Unable to refresh " + "image section for " + context, re);
-                                       }
-                               }
-                       });
-               }
-       }
-
-       protected void addListeners(StyledControl control) {
-               control.setMouseListener(getMouseListener());
-               control.setFocusListener(getFocusListener());
-       }
-
-       protected Img createImgComposite(Composite parent, Node node, Point preferredSize) throws RepositoryException {
-               Img img = new Img(parent, SWT.NONE, node, new Cms2DSize(preferredSize.x, preferredSize.y)) {
-                       private static final long serialVersionUID = 1297900641952417540L;
-
-                       @Override
-                       protected void setContainerLayoutData(Composite composite) {
-                               composite.setLayoutData(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
-                       }
-
-                       @Override
-                       protected void setControlLayoutData(Control control) {
-                               control.setLayoutData(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
-                       }
-               };
-               img.setLayoutData(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
-               updateContent(img);
-               addListeners(img);
-               return img;
-       }
-
-       protected Composite addDeleteAbility(final Section section, final Node sessionNode, int topWeight,
-                       int rightWeight) {
-               Composite comp = new Composite(section, SWT.NONE);
-               comp.setLayoutData(CmsSwtUtils.fillAll());
-               comp.setLayout(new FormLayout());
-
-               // The body to be populated
-               Composite body = new Composite(comp, SWT.NO_FOCUS);
-               body.setLayoutData(EclipseUiUtils.fillFormData());
-
-               if (getCmsEditable().canEdit()) {
-                       // the delete button
-                       Button deleteBtn = new Button(comp, SWT.FLAT);
-                       CmsSwtUtils.style(deleteBtn, FormStyle.deleteOverlay.style());
-                       FormData formData = new FormData();
-                       formData.right = new FormAttachment(rightWeight, 0);
-                       formData.top = new FormAttachment(topWeight, 0);
-                       deleteBtn.setLayoutData(formData);
-                       deleteBtn.moveAbove(body);
-
-                       deleteBtn.addSelectionListener(new SelectionAdapter() {
-                               private static final long serialVersionUID = 4304223543657238462L;
-
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       super.widgetSelected(e);
-                                       if (MessageDialog.openConfirm(section.getShell(), "Confirm deletion",
-                                                       "Are you really you want to remove this?")) {
-                                               Session session;
-                                               try {
-                                                       session = sessionNode.getSession();
-                                                       Section parSection = section.getParentSection();
-                                                       sessionNode.remove();
-                                                       session.save();
-                                                       refresh(parSection);
-                                                       layout(parSection);
-                                               } catch (RepositoryException re) {
-                                                       throw new JcrException("Unable to delete " + sessionNode, re);
-                                               }
-
-                                       }
-
-                               }
-                       });
-               }
-               return body;
-       }
-
-//     // LOCAL HELPERS FOR NODE MANAGEMENT
-//     private Node getOrCreateNode(Node parent, String nodeName, String nodeType) throws RepositoryException {
-//             Node node = null;
-//             if (getCmsEditable().canEdit() && !parent.hasNode(nodeName)) {
-//                     node = JcrUtils.mkdirs(parent, nodeName, nodeType);
-//                     parent.getSession().save();
-//             }
-//
-//             if (getCmsEditable().canEdit() || parent.hasNode(nodeName))
-//                     node = parent.getNode(nodeName);
-//
-//             return node;
-//     }
-
-       private SelectionListener getRemoveValueSelListener() {
-               return new SelectionAdapter() {
-                       private static final long serialVersionUID = 9022259089907445195L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               Object source = e.getSource();
-                               if (source instanceof Button) {
-                                       Button btn = (Button) source;
-                                       Object obj = btn.getData(FormConstants.LINKED_VALUE);
-                                       SwtEditablePart ep = findDataParent(btn);
-                                       if (ep != null && ep instanceof EditableMultiStringProperty) {
-                                               EditableMultiStringProperty emsp = (EditableMultiStringProperty) ep;
-                                               List<String> values = emsp.getValues();
-                                               if (values.contains(obj)) {
-                                                       values.remove(values.indexOf(obj));
-                                                       emsp.setValues(values);
-                                                       try {
-                                                               save(emsp);
-                                                               // TODO workaround to force refresh
-                                                               edit(emsp, 0);
-                                                               cancelEdit();
-                                                       } catch (RepositoryException e1) {
-                                                               throw new JcrException("Unable to remove value " + obj, e1);
-                                                       }
-                                                       layout(emsp);
-                                               }
-                                       }
-                               }
-                       }
-               };
-       }
-
-       protected void setPropertySilently(Node node, String propName, String value) throws RepositoryException {
-               try {
-                       // TODO Clean this:
-                       // Format strings to replace \n
-                       value = value.replaceAll("\n", "<br/>");
-                       // Do not make the update if validation fails
-                       try {
-                               MarkupValidatorCopy.getInstance().validate(value);
-                       } catch (Exception e) {
-                               log.warn("Cannot set [" + value + "] on prop " + propName + "of " + node
-                                               + ", String cannot be validated - " + e.getMessage());
-                               return;
-                       }
-                       // TODO check if the newly created property is of the correct type,
-                       // otherwise the property will be silently created with a STRING
-                       // property type.
-                       node.setProperty(propName, value);
-               } catch (ValueFormatException vfe) {
-                       log.warn("Cannot set [" + value + "] on prop " + propName + "of " + node + " - " + vfe.getMessage());
-               }
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormStyle.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormStyle.java
deleted file mode 100644 (file)
index 709ecd0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import org.argeo.api.cms.ux.CmsStyle;
-
-/** Syles used */
-public enum FormStyle implements CmsStyle {
-       // Main
-       form, title,
-       // main part
-       header, headerBtn, headerCombo, section, sectionHeader,
-       // Property fields
-       propertyLabel, propertyText, propertyMessage, errorMessage,
-       // Date
-       popupCalendar,
-       // Buttons
-       starred, unstarred, starOverlay, editOverlay, deleteOverlay, updateOverlay, deleteOverlaySmall, calendar, delete,
-       // Contacts
-       email, address, phone, website,
-       // Social Media
-       facebook, twitter, linkedIn, instagram;
-
-       @Override
-       public String getClassPrefix() {
-               return "argeo-form";
-       }
-
-       // TODO clean button style management
-       public final static String BUTTON_SUFFIX = "_btn";
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormUtils.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/FormUtils.java
deleted file mode 100644 (file)
index eeafabb..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.ux.CmsView;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.fieldassist.ControlDecoration;
-import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** Utilitary methods to ease implementation of CMS forms */
-public class FormUtils {
-       private final static CmsLog log = CmsLog.getLog(FormUtils.class);
-
-       public final static String DEFAULT_SHORT_DATE_FORMAT = "dd/MM/yyyy";
-
-       /** Best effort to convert a String to a calendar. Fails silently */
-       public static Calendar parseDate(DateFormat dateFormat, String calStr) {
-               Calendar cal = null;
-               if (EclipseUiUtils.notEmpty(calStr)) {
-                       try {
-                               Date date = dateFormat.parse(calStr);
-                               cal = new GregorianCalendar();
-                               cal.setTime(date);
-                       } catch (ParseException pe) {
-                               // Silent
-                               log.warn("Unable to parse date: " + calStr + " - msg: "
-                                               + pe.getMessage());
-                       }
-               }
-               return cal;
-       }
-
-       /** Add a double click listener on tables that display a JCR node list */
-       public static void addCanonicalDoubleClickListener(final TableViewer v) {
-               v.addDoubleClickListener(new IDoubleClickListener() {
-
-                       @Override
-                       public void doubleClick(DoubleClickEvent event) {
-                               CmsView cmsView = CmsUiUtils.getCmsView();
-                               Node node = (Node) ((IStructuredSelection) event.getSelection())
-                                               .getFirstElement();
-                               try {
-                                       cmsView.navigateTo(node.getPath());
-                               } catch (RepositoryException e) {
-                                       throw new CmsException("Unable to get path for node "
-                                                       + node + " before calling navigateTo(path)", e);
-                               }
-                       }
-               });
-       }
-
-       // MANAGE ERROR DECORATION
-
-       public static ControlDecoration addDecoration(final Text text) {
-               final ControlDecoration dynDecoration = new ControlDecoration(text,
-                               SWT.LEFT);
-               Image icon = getDecorationImage(FieldDecorationRegistry.DEC_ERROR);
-               dynDecoration.setImage(icon);
-               dynDecoration.setMarginWidth(3);
-               dynDecoration.hide();
-               return dynDecoration;
-       }
-
-       public static void refreshDecoration(Text text, ControlDecoration deco,
-                       boolean isValid, boolean clean) {
-               if (isValid || clean) {
-                       text.setBackground(null);
-                       deco.hide();
-               } else {
-                       text.setBackground(new Color(text.getDisplay(), 250, 200, 150));
-                       deco.show();
-               }
-       }
-
-       public static Image getDecorationImage(String image) {
-               FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
-               return registry.getFieldDecoration(image).getImage();
-       }
-
-       public static void addCompulsoryDecoration(Label label) {
-               final ControlDecoration dynDecoration = new ControlDecoration(label,
-                               SWT.RIGHT | SWT.TOP);
-               Image icon = getDecorationImage(FieldDecorationRegistry.DEC_REQUIRED);
-               dynDecoration.setImage(icon);
-               dynDecoration.setMarginWidth(3);
-       }
-
-       // TODO the read only generation of read only links for various contact type
-       // should be factorised in the cms Utils.
-       /**
-        * Creates the read-only HTML snippet to display in a label with styling
-        * enabled in order to provide a click-able phone number
-        */
-       public static String getPhoneLink(String value) {
-               return getPhoneLink(value, value);
-       }
-
-       /**
-        * Creates the read-only HTML snippet to display in a label with styling
-        * enabled in order to provide a click-able phone number
-        * 
-        * @param value
-        * @param label
-        *            a potentially distinct label
-        * @return the link
-        */
-       public static String getPhoneLink(String value, String label) {
-               StringBuilder builder = new StringBuilder();
-               builder.append("<a href=\"tel:");
-               builder.append(value).append("\" target=\"_blank\" >").append(label)
-                               .append("</a>");
-               return builder.toString();
-       }
-
-       /**
-        * Creates the read-only HTML snippet to display in a label with styling
-        * enabled in order to provide a click-able mail
-        */
-       public static String getMailLink(String value) {
-               return getMailLink(value, value);
-       }
-
-       /**
-        * Creates the read-only HTML snippet to display in a label with styling
-        * enabled in order to provide a click-able mail
-        * 
-        * @param value
-        * @param label
-        *            a potentially distinct label
-        * @return the link
-        */
-       public static String getMailLink(String value, String label) {
-               StringBuilder builder = new StringBuilder();
-               value = replaceAmpersand(value);
-               builder.append("<a href=\"mailto:");
-               builder.append(value).append("\" >").append(label).append("</a>");
-               return builder.toString();
-       }
-
-       /**
-        * Creates the read-only HTML snippet to display in a label with styling
-        * enabled in order to provide a click-able link
-        */
-       public static String getUrlLink(String value) {
-               return getUrlLink(value, value);
-       }
-
-       /**
-        * Creates the read-only HTML snippet to display in a label with styling
-        * enabled in order to provide a click-able link
-        */
-       public static String getUrlLink(String value, String label) {
-               StringBuilder builder = new StringBuilder();
-               value = replaceAmpersand(value);
-               label = replaceAmpersand(label);
-               if (!(value.startsWith("http://") || value.startsWith("https://")))
-                       value = "http://" + value;
-               builder.append("<a href=\"");
-               builder.append(value + "\" target=\"_blank\" >" + label + "</a>");
-               return builder.toString();
-       }
-
-       private static String AMPERSAND = "&#38;";
-
-       /**
-        * Cleans a String by replacing any '&#38;' by its HTML encoding '&#38;#38;' to
-        * avoid <code>SAXParseException</code> while rendering HTML with RWT
-        */
-       public static String replaceAmpersand(String value) {
-               value = value.replaceAll("&(?![#a-zA-Z0-9]+;)", AMPERSAND);
-               return value;
-       }
-
-       // Prevents instantiation
-       private FormUtils() {
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/MarkupValidatorCopy.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/MarkupValidatorCopy.java
deleted file mode 100644 (file)
index 3f588d1..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-package org.argeo.cms.ui.forms;
-
-import java.io.StringReader;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.eclipse.rap.rwt.SingletonUtil;
-import org.eclipse.swt.widgets.Widget;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Copy of RAP v2.3 since it is in an internal package.
- */
-class MarkupValidatorCopy {
-
-       // Used by Eclipse Scout project
-       public static final String MARKUP_VALIDATION_DISABLED = "org.eclipse.rap.rwt.markupValidationDisabled";
-
-       private static final String DTD = createDTD();
-       private static final Map<String, String[]> SUPPORTED_ELEMENTS = createSupportedElementsMap();
-       private final SAXParser saxParser;
-
-       public static MarkupValidatorCopy getInstance() {
-               return SingletonUtil.getSessionInstance(MarkupValidatorCopy.class);
-       }
-
-       public MarkupValidatorCopy() {
-               saxParser = createSAXParser();
-       }
-
-       public void validate(String text) {
-               StringBuilder markup = new StringBuilder();
-               markup.append(DTD);
-               markup.append("<html>");
-               markup.append(text);
-               markup.append("</html>");
-               InputSource inputSource = new InputSource(new StringReader(markup.toString()));
-               try {
-                       saxParser.parse(inputSource, new MarkupHandler());
-               } catch (RuntimeException exception) {
-                       throw exception;
-               } catch (Exception exception) {
-                       throw new IllegalArgumentException("Failed to parse markup text", exception);
-               }
-       }
-
-       public static boolean isValidationDisabledFor(Widget widget) {
-               return Boolean.TRUE.equals(widget.getData(MARKUP_VALIDATION_DISABLED));
-       }
-
-       private static SAXParser createSAXParser() {
-               SAXParser result = null;
-               SAXParserFactory parserFactory = SAXParserFactory.newInstance();
-               try {
-                       result = parserFactory.newSAXParser();
-               } catch (Exception exception) {
-                       throw new RuntimeException("Failed to create SAX parser", exception);
-               }
-               return result;
-       }
-
-       private static String createDTD() {
-               StringBuilder result = new StringBuilder();
-               result.append("<!DOCTYPE html [");
-               result.append("<!ENTITY quot \"&#34;\">");
-               result.append("<!ENTITY amp \"&#38;\">");
-               result.append("<!ENTITY apos \"&#39;\">");
-               result.append("<!ENTITY lt \"&#60;\">");
-               result.append("<!ENTITY gt \"&#62;\">");
-               result.append("<!ENTITY nbsp \"&#160;\">");
-               result.append("<!ENTITY ensp \"&#8194;\">");
-               result.append("<!ENTITY emsp \"&#8195;\">");
-               result.append("<!ENTITY ndash \"&#8211;\">");
-               result.append("<!ENTITY mdash \"&#8212;\">");
-               result.append("]>");
-               return result.toString();
-       }
-
-       private static Map<String, String[]> createSupportedElementsMap() {
-               Map<String, String[]> result = new HashMap<String, String[]>();
-               result.put("html", new String[0]);
-               result.put("br", new String[0]);
-               result.put("b", new String[] { "style" });
-               result.put("strong", new String[] { "style" });
-               result.put("i", new String[] { "style" });
-               result.put("em", new String[] { "style" });
-               result.put("sub", new String[] { "style" });
-               result.put("sup", new String[] { "style" });
-               result.put("big", new String[] { "style" });
-               result.put("small", new String[] { "style" });
-               result.put("del", new String[] { "style" });
-               result.put("ins", new String[] { "style" });
-               result.put("code", new String[] { "style" });
-               result.put("samp", new String[] { "style" });
-               result.put("kbd", new String[] { "style" });
-               result.put("var", new String[] { "style" });
-               result.put("cite", new String[] { "style" });
-               result.put("dfn", new String[] { "style" });
-               result.put("q", new String[] { "style" });
-               result.put("abbr", new String[] { "style", "title" });
-               result.put("span", new String[] { "style" });
-               result.put("img", new String[] { "style", "src", "width", "height", "title", "alt" });
-               result.put("a", new String[] { "style", "href", "target", "title" });
-               return result;
-       }
-
-       private static class MarkupHandler extends DefaultHandler {
-
-               @Override
-               public void startElement(String uri, String localName, String name, Attributes attributes) {
-                       checkSupportedElements(name, attributes);
-                       checkSupportedAttributes(name, attributes);
-                       checkMandatoryAttributes(name, attributes);
-               }
-
-               private static void checkSupportedElements(String elementName, Attributes attributes) {
-                       if (!SUPPORTED_ELEMENTS.containsKey(elementName)) {
-                               throw new IllegalArgumentException("Unsupported element in markup text: " + elementName);
-                       }
-               }
-
-               private static void checkSupportedAttributes(String elementName, Attributes attributes) {
-                       if (attributes.getLength() > 0) {
-                               List<String> supportedAttributes = Arrays.asList(SUPPORTED_ELEMENTS.get(elementName));
-                               int index = 0;
-                               String attributeName = attributes.getQName(index);
-                               while (attributeName != null) {
-                                       if (!supportedAttributes.contains(attributeName)) {
-                                               String message = "Unsupported attribute \"{0}\" for element \"{1}\" in markup text";
-                                               message = MessageFormat.format(message, new Object[] { attributeName, elementName });
-                                               throw new IllegalArgumentException(message);
-                                       }
-                                       index++;
-                                       attributeName = attributes.getQName(index);
-                               }
-                       }
-               }
-
-               private static void checkMandatoryAttributes(String elementName, Attributes attributes) {
-                       checkIntAttribute(elementName, attributes, "img", "width");
-                       checkIntAttribute(elementName, attributes, "img", "height");
-               }
-
-               private static void checkIntAttribute(String elementName, Attributes attributes, String checkedElementName,
-                               String checkedAttributeName) {
-                       if (checkedElementName.equals(elementName)) {
-                               String attribute = attributes.getValue(checkedAttributeName);
-                               try {
-                                       Integer.parseInt(attribute);
-                               } catch (NumberFormatException exception) {
-                                       String message = "Mandatory attribute \"{0}\" for element \"{1}\" is missing or not a valid integer";
-                                       Object[] arguments = new Object[] { checkedAttributeName, checkedElementName };
-                                       message = MessageFormat.format(message, arguments);
-                                       throw new IllegalArgumentException(message);
-                               }
-                       }
-               }
-
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/forms/package-info.java
deleted file mode 100644 (file)
index 5f954c1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Argeo CMS forms, based on SWT/JFace. */
-package org.argeo.cms.ui.forms;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java
deleted file mode 100644 (file)
index d9c1c12..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-package org.argeo.cms.ui.fs;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.FileSystem;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.spi.FileSystemProvider;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.Session;
-
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.fs.FileIconNameLabelProvider;
-import org.argeo.eclipse.ui.fs.FsTableViewer;
-import org.argeo.eclipse.ui.fs.FsUiConstants;
-import org.argeo.eclipse.ui.fs.FsUiUtils;
-import org.argeo.eclipse.ui.fs.NioFileLabelProvider;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowData;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Default CMS browser composite: a sashForm layout with bookmarks at the left
- * hand side, a simple table in the middle and an overview at right hand side.
- */
-public class CmsFsBrowser extends Composite {
-       // private final static Log log = LogFactory.getLog(CmsFsBrowser.class);
-       private static final long serialVersionUID = -40347919096946585L;
-
-       private final FileSystemProvider nodeFileSystemProvider;
-       private final Node currentBaseContext;
-
-       // UI Parts for the browser
-       private Composite leftPannelCmp;
-       private Composite filterCmp;
-       private Text filterTxt;
-       private FsTableViewer directoryDisplayViewer;
-       private Composite rightPannelCmp;
-
-       private FsContextMenu contextMenu;
-
-       // Local context (this composite is state full)
-       private Path initialPath;
-       private Path currDisplayedFolder;
-       private Path currSelected;
-
-       // local variables (to be cleaned)
-       private int bookmarkColWith = 500;
-
-       /*
-        * WARNING: unfinalised implementation of the mechanism to retrieve base
-        * paths
-        */
-
-       private final static String NODE_PREFIX = "node://";
-
-       private String getCurrentHomePath() {
-               Session session = null;
-               try {
-                       Repository repo = currentBaseContext.getSession().getRepository();
-                       session = CurrentUser.tryAs(() -> repo.login());
-                       String homepath = CmsJcrUtils.getUserHome(session).getPath();
-                       return homepath;
-               } catch (Exception e) {
-                       throw new CmsException("Cannot retrieve Current User Home Path", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       protected Path[] getMyFilesPath() {
-               // return Paths.get(System.getProperty("user.dir"));
-               String currHomeUriStr = NODE_PREFIX + getCurrentHomePath();
-               try {
-                       URI uri = new URI(currHomeUriStr);
-                       FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri);
-                       if (fileSystem == null) {
-                               PrivilegedExceptionAction<FileSystem> pea = new PrivilegedExceptionAction<FileSystem>() {
-                                       @Override
-                                       public FileSystem run() throws Exception {
-                                               return nodeFileSystemProvider.newFileSystem(uri, null);
-                                       }
-
-                               };
-                               fileSystem = CurrentUser.tryAs(pea);
-                       }
-                       Path[] paths = { fileSystem.getPath(getCurrentHomePath()), fileSystem.getPath("/") };
-                       return paths;
-               } catch (URISyntaxException | PrivilegedActionException e) {
-                       throw new RuntimeException("unable to initialise home file system for " + currHomeUriStr, e);
-               }
-       }
-
-       private Path[] getMyGroupsFilesPath() {
-               // TODO
-               Path[] paths = { Paths.get(System.getProperty("user.dir")), Paths.get("/tmp") };
-               return paths;
-       }
-
-       private Path[] getMyBookmarks() {
-               // TODO
-               Path[] paths = { Paths.get(System.getProperty("user.dir")), Paths.get("/tmp"), Paths.get("/opt") };
-               return paths;
-       }
-
-       /* End of warning */
-
-       public CmsFsBrowser(Composite parent, int style, Node context, FileSystemProvider fileSystemProvider) {
-               super(parent, style);
-               this.nodeFileSystemProvider = fileSystemProvider;
-               this.currentBaseContext = context;
-
-               this.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-               SashForm form = new SashForm(this, SWT.HORIZONTAL);
-
-               leftPannelCmp = new Composite(form, SWT.NO_FOCUS);
-               // Bookmarks are still static
-               populateBookmarks(leftPannelCmp);
-
-               Composite centerCmp = new Composite(form, SWT.BORDER | SWT.NO_FOCUS);
-               createDisplay(centerCmp);
-
-               rightPannelCmp = new Composite(form, SWT.NO_FOCUS);
-
-               form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               form.setWeights(new int[] { 15, 40, 20 });
-       }
-
-       void refresh() {
-               modifyFilter(false);
-               // also refresh bookmarks and groups
-       }
-
-       private void createDisplay(final Composite parent) {
-               parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-               // top filter
-               filterCmp = new Composite(parent, SWT.NO_FOCUS);
-               filterCmp.setLayoutData(EclipseUiUtils.fillWidth());
-               addFilterPanel(filterCmp);
-
-               // Main display
-               directoryDisplayViewer = new FsTableViewer(parent, SWT.MULTI);
-               List<ColumnDefinition> colDefs = new ArrayList<>();
-               colDefs.add(new ColumnDefinition(new FileIconNameLabelProvider(), "Name", 250));
-               colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_SIZE), "Size", 100));
-               colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_TYPE), "Type", 150));
-               colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_LAST_MODIFIED),
-                               "Last modified", 400));
-               final Table table = directoryDisplayViewer.configureDefaultTable(colDefs);
-               table.setLayoutData(EclipseUiUtils.fillAll());
-
-               // table.addKeyListener(new KeyListener() {
-               // private static final long serialVersionUID = -8083424284436715709L;
-               //
-               // @Override
-               // public void keyReleased(KeyEvent e) {
-               // }
-               //
-               // @Override
-               // public void keyPressed(KeyEvent e) {
-               // if (log.isDebugEnabled())
-               // log.debug("Key event received: " + e.keyCode);
-               // IStructuredSelection selection = (IStructuredSelection)
-               // directoryDisplayViewer.getSelection();
-               // Path selected = null;
-               // if (!selection.isEmpty())
-               // selected = ((Path) selection.getFirstElement());
-               // if (e.keyCode == SWT.CR) {
-               // if (!Files.isDirectory(selected))
-               // return;
-               // if (selected != null) {
-               // currDisplayedFolder = selected;
-               // directoryDisplayViewer.setInput(currDisplayedFolder, "*");
-               // }
-               // } else if (e.keyCode == SWT.BS) {
-               // currDisplayedFolder = currDisplayedFolder.getParent();
-               // directoryDisplayViewer.setInput(currDisplayedFolder, "*");
-               // directoryDisplayViewer.getTable().setFocus();
-               // }
-               // }
-               // });
-
-               directoryDisplayViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
-                       @Override
-                       public void selectionChanged(SelectionChangedEvent event) {
-                               IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
-                               Path selected = null;
-                               if (selection.isEmpty())
-                                       setSelected(null);
-                               else
-                                       selected = ((Path) selection.getFirstElement());
-                               if (selected != null) {
-                                       // TODO manage multiple selection
-                                       setSelected(selected);
-                               }
-                       }
-               });
-
-               directoryDisplayViewer.addDoubleClickListener(new IDoubleClickListener() {
-                       @Override
-                       public void doubleClick(DoubleClickEvent event) {
-                               IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
-                               Path selected = null;
-                               if (!selection.isEmpty())
-                                       selected = ((Path) selection.getFirstElement());
-                               if (selected != null) {
-                                       if (!Files.isDirectory(selected))
-                                               return;
-                                       setInput(selected);
-                               }
-                       }
-               });
-
-               // The context menu
-               contextMenu = new FsContextMenu(this);
-
-               table.addMouseListener(new MouseAdapter() {
-                       private static final long serialVersionUID = 6737579410648595940L;
-
-                       @Override
-                       public void mouseDown(MouseEvent e) {
-                               if (e.button == 3) {
-                                       // contextMenu.setCurrFolderPath(currDisplayedFolder);
-                                       contextMenu.show(table, new Point(e.x, e.y), currDisplayedFolder);
-                               }
-                       }
-               });
-       }
-
-       private void addPathElementBtn(Path path) {
-               Button elemBtn = new Button(filterCmp, SWT.PUSH);
-               String nameStr;
-               if (path.toString().equals("/"))
-                       nameStr = "[jcr:root]";
-               else
-                       nameStr = path.getFileName().toString();
-               elemBtn.setText(nameStr + " >> ");
-               CmsSwtUtils.style(elemBtn, FsStyles.BREAD_CRUMB_BTN);
-               elemBtn.addSelectionListener(new SelectionAdapter() {
-                       private static final long serialVersionUID = -4103695476023480651L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               setInput(path);
-                       }
-               });
-       }
-
-       public void setInput(Path path) {
-               if (path.equals(currDisplayedFolder))
-                       return;
-               currDisplayedFolder = path;
-
-               Path diff = initialPath.relativize(currDisplayedFolder);
-
-               for (Control child : filterCmp.getChildren())
-                       if (!child.equals(filterTxt))
-                               child.dispose();
-
-               addPathElementBtn(initialPath);
-               Path currTarget = initialPath;
-               if (!diff.toString().equals(""))
-                       for (Path pathElem : diff) {
-                               currTarget = currTarget.resolve(pathElem);
-                               addPathElementBtn(currTarget);
-                       }
-
-               filterTxt.setText("");
-               filterTxt.moveBelow(null);
-               setSelected(null);
-               filterCmp.getParent().layout(true, true);
-       }
-
-       private void setSelected(Path path) {
-               currSelected = path;
-               setOverviewInput(path);
-       }
-
-       public Viewer getViewer() {
-               return directoryDisplayViewer;
-       }
-
-       private void populateBookmarks(Composite parent) {
-               CmsSwtUtils.clear(parent);
-               parent.setLayout(new GridLayout());
-               ISelectionChangedListener selList = new BookmarksSelChangeListener();
-
-               FsTableViewer homeViewer = new FsTableViewer(parent, SWT.SINGLE | SWT.NO_SCROLL);
-               Table table = homeViewer.configureDefaultSingleColumnTable(bookmarkColWith);
-               GridData gd = EclipseUiUtils.fillWidth();
-               gd.horizontalIndent = 10;
-               table.setLayoutData(gd);
-               homeViewer.addSelectionChangedListener(selList);
-               homeViewer.setPathsInput(getMyFilesPath());
-
-               appendTitle(parent, "Shared files");
-               FsTableViewer groupsViewer = new FsTableViewer(parent, SWT.SINGLE | SWT.NO_SCROLL);
-               table = groupsViewer.configureDefaultSingleColumnTable(bookmarkColWith);
-               gd = EclipseUiUtils.fillWidth();
-               gd.horizontalIndent = 10;
-               table.setLayoutData(gd);
-               groupsViewer.addSelectionChangedListener(selList);
-               groupsViewer.setPathsInput(getMyGroupsFilesPath());
-
-               appendTitle(parent, "My bookmarks");
-               FsTableViewer bookmarksViewer = new FsTableViewer(parent, SWT.SINGLE | SWT.NO_SCROLL);
-               table = bookmarksViewer.configureDefaultSingleColumnTable(bookmarkColWith);
-               gd = EclipseUiUtils.fillWidth();
-               gd.horizontalIndent = 10;
-               table.setLayoutData(gd);
-               bookmarksViewer.addSelectionChangedListener(selList);
-               bookmarksViewer.setPathsInput(getMyBookmarks());
-       }
-
-       /**
-        * Recreates the content of the box that displays information about the
-        * current selected Path.
-        */
-       private void setOverviewInput(Path path) {
-               try {
-                       EclipseUiUtils.clear(rightPannelCmp);
-                       rightPannelCmp.setLayout(new GridLayout());
-                       if (path != null) {
-                               // if (isImg(context)) {
-                               // EditableImage image = new Img(parent, RIGHT, context,
-                               // imageWidth);
-                               // image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER,
-                               // true, false,
-                               // 2, 1));
-                               // }
-
-                               Label contextL = new Label(rightPannelCmp, SWT.NONE);
-                               contextL.setText(path.getFileName().toString());
-                               contextL.setFont(EclipseUiUtils.getBoldFont(rightPannelCmp));
-                               addProperty(rightPannelCmp, "Last modified", Files.getLastModifiedTime(path).toString());
-                               // addProperty(rightPannelCmp, "Owner",
-                               // Files.getOwner(path).getName());
-                               if (Files.isDirectory(path)) {
-                                       addProperty(rightPannelCmp, "Type", "Folder");
-                               } else {
-                                       String mimeType = Files.probeContentType(path);
-                                       if (EclipseUiUtils.isEmpty(mimeType))
-                                               mimeType = "<i>Unknown</i>";
-                                       addProperty(rightPannelCmp, "Type", mimeType);
-                                       addProperty(rightPannelCmp, "Size", FsUiUtils.humanReadableByteCount(Files.size(path), false));
-                               }
-                       }
-                       rightPannelCmp.layout(true, true);
-               } catch (IOException e) {
-                       throw new CmsException("Cannot display details for " + path.toString(), e);
-               }
-       }
-
-       private void addFilterPanel(Composite parent) {
-               RowLayout rl = new RowLayout(SWT.HORIZONTAL);
-               rl.wrap = true;
-               parent.setLayout(rl);
-               // parent.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2,
-               // false)));
-
-               filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL);
-               filterTxt.setMessage("Search current folder");
-               filterTxt.setLayoutData(new RowData(250, SWT.DEFAULT));
-               filterTxt.addModifyListener(new ModifyListener() {
-                       private static final long serialVersionUID = 1L;
-
-                       public void modifyText(ModifyEvent event) {
-                               modifyFilter(false);
-                       }
-               });
-               filterTxt.addKeyListener(new KeyListener() {
-                       private static final long serialVersionUID = 2533535233583035527L;
-
-                       @Override
-                       public void keyReleased(KeyEvent e) {
-                       }
-
-                       @Override
-                       public void keyPressed(KeyEvent e) {
-                               // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
-                               // // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
-                               // FilterEntitiesVirtualTable currTable = null;
-                               // if (currEdited != null) {
-                               // FilterEntitiesVirtualTable table =
-                               // browserCols.get(currEdited);
-                               // if (table != null && !table.isDisposed())
-                               // currTable = table;
-                               // }
-                               //
-                               // if (e.keyCode == SWT.ARROW_DOWN)
-                               // currTable.setFocus();
-                               // else if (e.keyCode == SWT.BS) {
-                               // if (filterTxt.getText().equals("")
-                               // && !(currEdited.getNameCount() == 1 ||
-                               // currEdited.equals(initialPath))) {
-                               // Path oldEdited = currEdited;
-                               // Path parentPath = currEdited.getParent();
-                               // setEdited(parentPath);
-                               // if (browserCols.containsKey(parentPath))
-                               // browserCols.get(parentPath).setSelected(oldEdited);
-                               // filterTxt.setFocus();
-                               // e.doit = false;
-                               // }
-                               // } else if (e.keyCode == SWT.TAB && !shiftPressed) {
-                               // Path uniqueChild = getOnlyChild(currEdited,
-                               // filterTxt.getText());
-                               // if (uniqueChild != null) {
-                               // // Highlight the unique chosen child
-                               // currTable.setSelected(uniqueChild);
-                               // setEdited(uniqueChild);
-                               // }
-                               // filterTxt.setFocus();
-                               // e.doit = false;
-                               // }
-                       }
-               });
-       }
-
-       private Path getOnlyChild(Path parent, String filter) {
-               try (DirectoryStream<Path> stream = Files.newDirectoryStream(currDisplayedFolder, filter + "*")) {
-                       Path uniqueChild = null;
-                       boolean moreThanOne = false;
-                       loop: for (Path entry : stream) {
-                               if (uniqueChild == null) {
-                                       uniqueChild = entry;
-                               } else {
-                                       moreThanOne = true;
-                                       break loop;
-                               }
-                       }
-                       if (!moreThanOne)
-                               return uniqueChild;
-                       return null;
-               } catch (IOException ioe) {
-                       throw new CmsException(
-                                       "Unable to determine unique child existence and get it under " + parent + " with filter " + filter,
-                                       ioe);
-               }
-       }
-
-       private void modifyFilter(boolean fromOutside) {
-               if (!fromOutside)
-                       if (currDisplayedFolder != null) {
-                               String filter = filterTxt.getText() + "*";
-                               directoryDisplayViewer.setInput(currDisplayedFolder, filter);
-                       }
-       }
-
-       private class BookmarksSelChangeListener implements ISelectionChangedListener {
-
-               @Override
-               public void selectionChanged(SelectionChangedEvent event) {
-                       IStructuredSelection selection = (IStructuredSelection) event.getSelection();
-                       if (selection.isEmpty())
-                               return;
-                       else {
-                               Path newSelected = (Path) selection.getFirstElement();
-                               if (newSelected.equals(currDisplayedFolder) && newSelected.equals(initialPath))
-                                       return;
-                               initialPath = newSelected;
-                               setInput(newSelected);
-                       }
-               }
-       }
-
-       // Simplify UI implementation
-       private void addProperty(Composite parent, String propName, String value) {
-               Label contextL = new Label(parent, SWT.NONE);
-               contextL.setText(propName + ": " + value);
-       }
-
-       private Label appendTitle(Composite parent, String value) {
-               Label titleLbl = new Label(parent, SWT.NONE);
-               titleLbl.setText(value);
-               titleLbl.setFont(EclipseUiUtils.getBoldFont(parent));
-               GridData gd = EclipseUiUtils.fillWidth();
-               gd.horizontalIndent = 5;
-               gd.verticalIndent = 5;
-               titleLbl.setLayoutData(gd);
-               return titleLbl;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FileDrop.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FileDrop.java
deleted file mode 100644 (file)
index e875b5a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.argeo.cms.ui.fs;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-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;
-import org.eclipse.swt.dnd.DropTargetEvent;
-import org.eclipse.swt.widgets.Control;
-
-/** Allows a control to receive file drops. */
-public class FileDrop {
-       private final static CmsLog log = CmsLog.getLog(FileDrop.class);
-
-       public void createDropTarget(Control control) {
-               FileDropAdapter fileDropAdapter = new FileDropAdapter() {
-                       @Override
-                       protected void processUpload(InputStream in, String fileName, String contentType) throws IOException {
-                               if (log.isDebugEnabled())
-                                       log.debug("Process upload of " + fileName + " (" + contentType + ")");
-                               processFileUpload(in, fileName, contentType);
-                       }
-               };
-               DropTarget dropTarget = new DropTarget(control, DND.DROP_MOVE | DND.DROP_COPY);
-               fileDropAdapter.prepareDropTarget(control, dropTarget);
-       }
-
-       public void handleFileDrop(Control control, DropTargetEvent event) {
-       }
-
-       /** Executed in UI thread */
-       protected void processFileUpload(InputStream in, String fileName, String contentType) throws IOException {
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java
deleted file mode 100644 (file)
index 1fb3c2a..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-package org.argeo.cms.ui.fs;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.dialogs.SingleValue;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-/** Generic popup context menu to manage NIO Path in a Viewer. */
-public class FsContextMenu extends Shell {
-       private static final long serialVersionUID = -9120261153509855795L;
-
-       private final static CmsLog log = CmsLog.getLog(FsContextMenu.class);
-
-       // Default known actions
-       public final static String ACTION_ID_CREATE_FOLDER = "createFolder";
-       public final static String ACTION_ID_BOOKMARK_FOLDER = "bookmarkFolder";
-       public final static String ACTION_ID_SHARE_FOLDER = "shareFolder";
-       public final static String ACTION_ID_DOWNLOAD_FOLDER = "downloadFolder";
-       public final static String ACTION_ID_DELETE = "delete";
-       public final static String ACTION_ID_UPLOAD_FILE = "uploadFiles";
-       public final static String ACTION_ID_OPEN = "open";
-
-       // Local context
-       private final CmsFsBrowser browser;
-       // private final Viewer viewer;
-       private final static String KEY_ACTION_ID = "actionId";
-       private final static String[] DEFAULT_ACTIONS = { ACTION_ID_CREATE_FOLDER, ACTION_ID_BOOKMARK_FOLDER,
-                       ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_DELETE, ACTION_ID_UPLOAD_FILE,
-                       ACTION_ID_OPEN };
-       private Map<String, Button> actionButtons = new HashMap<String, Button>();
-
-       private Path currFolderPath;
-
-       public FsContextMenu(CmsFsBrowser browser) { // Viewer viewer, Display
-                                                                                                       // display) {
-               super(browser.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
-               this.browser = browser;
-               setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-               Composite boxCmp = new Composite(this, SWT.NO_FOCUS | SWT.BORDER);
-               boxCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
-               CmsSwtUtils.style(boxCmp, FsStyles.CONTEXT_MENU_BOX);
-               createContextMenu(boxCmp);
-
-               addShellListener(new ActionsShellListener());
-       }
-
-       protected void createContextMenu(Composite boxCmp) {
-               ActionsSelListener asl = new ActionsSelListener();
-               for (String actionId : DEFAULT_ACTIONS) {
-                       Button btn = new Button(boxCmp, SWT.FLAT | SWT.PUSH | SWT.LEAD);
-                       btn.setText(getLabel(actionId));
-                       btn.setLayoutData(EclipseUiUtils.fillWidth());
-                       CmsSwtUtils.markup(btn);
-                       CmsSwtUtils.style(btn, actionId + FsStyles.BUTTON_SUFFIX);
-                       btn.setData(KEY_ACTION_ID, actionId);
-                       btn.addSelectionListener(asl);
-                       actionButtons.put(actionId, btn);
-               }
-       }
-
-       protected String getLabel(String actionId) {
-               switch (actionId) {
-               case ACTION_ID_CREATE_FOLDER:
-                       return "Create Folder";
-               case ACTION_ID_BOOKMARK_FOLDER:
-                       return "Bookmark Folder";
-               case ACTION_ID_SHARE_FOLDER:
-                       return "Share Folder";
-               case ACTION_ID_DOWNLOAD_FOLDER:
-                       return "Download as zip archive";
-               case ACTION_ID_DELETE:
-                       return "Delete";
-               case ACTION_ID_UPLOAD_FILE:
-                       return "Upload Files";
-               case ACTION_ID_OPEN:
-                       return "Open";
-               default:
-                       throw new IllegalArgumentException("Unknown action ID " + actionId);
-               }
-       }
-
-       protected void aboutToShow(Control source, Point location) {
-               IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection());
-               boolean emptySel = true;
-               boolean multiSel = false;
-               boolean isFolder = true;
-               if (selection != null && !selection.isEmpty()) {
-                       emptySel = false;
-                       multiSel = selection.size() > 1;
-                       if (!multiSel && selection.getFirstElement() instanceof Path) {
-                               isFolder = Files.isDirectory((Path) selection.getFirstElement());
-                       }
-               }
-               if (emptySel) {
-                       setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE);
-                       setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_DELETE, ACTION_ID_OPEN,
-                                       // to be implemented
-                                       ACTION_ID_BOOKMARK_FOLDER);
-               } else if (multiSel) {
-                       setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_DELETE);
-                       setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_OPEN,
-                                       // to be implemented
-                                       ACTION_ID_BOOKMARK_FOLDER);
-               } else if (isFolder) {
-                       setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_DELETE);
-                       setVisible(false, ACTION_ID_OPEN,
-                                       // to be implemented
-                                       ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_BOOKMARK_FOLDER);
-               } else {
-                       setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_OPEN, ACTION_ID_DELETE);
-                       setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER,
-                                       // to be implemented
-                                       ACTION_ID_BOOKMARK_FOLDER);
-               }
-       }
-
-       private void setVisible(boolean visible, String... buttonIds) {
-               for (String id : buttonIds) {
-                       Button button = actionButtons.get(id);
-                       button.setVisible(visible);
-                       GridData gd = (GridData) button.getLayoutData();
-                       gd.heightHint = visible ? SWT.DEFAULT : 0;
-               }
-       }
-
-       public void show(Control source, Point location, Path currFolderPath) {
-               if (isVisible())
-                       setVisible(false);
-               // TODO find a better way to retrieve the parent path (cannot be deduced
-               // from table content because it will fail on an empty folder)
-               this.currFolderPath = currFolderPath;
-               aboutToShow(source, location);
-               pack();
-               layout();
-               if (source instanceof Control)
-                       setLocation(((Control) source).toDisplay(location.x, location.y));
-               open();
-       }
-
-       class StyleButton extends Label {
-               private static final long serialVersionUID = 7731102609123946115L;
-
-               public StyleButton(Composite parent, int swtStyle) {
-                       super(parent, swtStyle);
-               }
-
-       }
-
-       // class ActionsMouseListener extends MouseAdapter {
-       // private static final long serialVersionUID = -1041871937815812149L;
-       //
-       // @Override
-       // public void mouseDown(MouseEvent e) {
-       // Object eventSource = e.getSource();
-       // if (e.button == 1) {
-       // if (eventSource instanceof Button) {
-       // Button pressedBtn = (Button) eventSource;
-       // String actionId = (String) pressedBtn.getData(KEY_ACTION_ID);
-       // switch (actionId) {
-       // case ACTION_ID_CREATE_FOLDER:
-       // createFolder();
-       // break;
-       // case ACTION_ID_DELETE:
-       // deleteItems();
-       // break;
-       // default:
-       // throw new IllegalArgumentException("Unimplemented action " + actionId);
-       // // case ACTION_ID_SHARE_FOLDER:
-       // // return "Share Folder";
-       // // case ACTION_ID_DOWNLOAD_FOLDER:
-       // // return "Download as zip archive";
-       // // case ACTION_ID_UPLOAD_FILE:
-       // // return "Upload Files";
-       // // case ACTION_ID_OPEN:
-       // // return "Open";
-       // }
-       // }
-       // }
-       // viewer.getControl().setFocus();
-       // // setVisible(false);
-       // }
-       // }
-
-       class ActionsSelListener extends SelectionAdapter {
-               private static final long serialVersionUID = -1041871937815812149L;
-
-               @Override
-               public void widgetSelected(SelectionEvent e) {
-                       Object eventSource = e.getSource();
-                       if (eventSource instanceof Button) {
-                               Button pressedBtn = (Button) eventSource;
-                               String actionId = (String) pressedBtn.getData(KEY_ACTION_ID);
-                               switch (actionId) {
-                               case ACTION_ID_CREATE_FOLDER:
-                                       createFolder();
-                                       break;
-                               case ACTION_ID_DELETE:
-                                       deleteItems();
-                                       break;
-                               case ACTION_ID_OPEN:
-                                       openFile();
-                                       break;
-                               case ACTION_ID_UPLOAD_FILE:
-                                       uploadFiles();
-                                       break;
-                               default:
-                                       throw new IllegalArgumentException("Unimplemented action " + actionId);
-                                       // case ACTION_ID_SHARE_FOLDER:
-                                       // return "Share Folder";
-                                       // case ACTION_ID_DOWNLOAD_FOLDER:
-                                       // return "Download as zip archive";
-                                       // case ACTION_ID_OPEN:
-                                       // return "Open";
-                               }
-                       }
-                       browser.setFocus();
-                       // viewer.getControl().setFocus();
-                       // setVisible(false);
-
-               }
-       }
-
-       class ActionsShellListener extends org.eclipse.swt.events.ShellAdapter {
-               private static final long serialVersionUID = -5092341449523150827L;
-
-               @Override
-               public void shellDeactivated(ShellEvent e) {
-                       setVisible(false);
-               }
-       }
-
-       private void openFile() {
-               log.warn("Implement single sourced, workbench independant \"Open File\" action");
-       }
-
-       private void deleteItems() {
-               IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection());
-               if (selection.isEmpty())
-                       return;
-
-               StringBuilder builder = new StringBuilder();
-               @SuppressWarnings("unchecked")
-               Iterator<Object> iterator = selection.iterator();
-               List<Path> paths = new ArrayList<>();
-
-               while (iterator.hasNext()) {
-                       Path path = (Path) iterator.next();
-                       builder.append(path.getFileName() + ", ");
-                       paths.add(path);
-               }
-               String msg = "You are about to delete following elements: " + builder.substring(0, builder.length() - 2)
-                               + ". Are you sure?";
-               if (MessageDialog.openConfirm(this, "Confirm deletion", msg)) {
-                       for (Path path : paths) {
-                               try {
-                                       // Might have already been deleted if we are in a tree
-                                       Files.deleteIfExists(path);
-                               } catch (IOException e) {
-                                       throw new CmsException("Cannot delete path " + path, e);
-                               }
-                       }
-                       browser.refresh();
-               }
-       }
-
-       private void createFolder() {
-               String msg = "Please provide a name.";
-               String name = SingleValue.ask("Create folder", msg);
-               // TODO enhance check of name validity
-               if (EclipseUiUtils.notEmpty(name)) {
-                       try {
-                               Path child = currFolderPath.resolve(name);
-                               if (Files.exists(child))
-                                       throw new CmsException("An item with name " + name + " already exists at "
-                                                       + currFolderPath.toString() + ", cannot create");
-                               else
-                                       Files.createDirectories(child);
-                               browser.refresh();
-                       } catch (IOException e) {
-                               throw new CmsException("Cannot create folder " + name + " at " + currFolderPath.toString(), e);
-                       }
-               }
-       }
-
-       private void uploadFiles() {
-               try {
-                       FileDialog dialog = new FileDialog(browser.getShell(), SWT.MULTI);
-                       dialog.setText("Choose one or more files to upload");
-
-                       if (EclipseUiUtils.notEmpty(dialog.open())) {
-                               String[] names = dialog.getFileNames();
-                               // Workaround small differences between RAP and RCP
-                               // 1. returned names are absolute path on RAP and
-                               // relative in RCP
-                               // 2. in RCP we must use getFilterPath that does not
-                               // exists on RAP
-                               Method filterMethod = null;
-                               Path parPath = null;
-                               try {
-                                       filterMethod = dialog.getClass().getDeclaredMethod("getFilterPath");
-                                       String filterPath = (String) filterMethod.invoke(dialog);
-                                       parPath = Paths.get(filterPath);
-                               } catch (NoSuchMethodException nsme) { // RAP
-                               }
-                               if (names.length == 0)
-                                       return;
-                               else {
-                                       loop: for (String name : names) {
-                                               Path tmpPath = Paths.get(name);
-                                               if (parPath != null)
-                                                       tmpPath = parPath.resolve(tmpPath);
-                                               if (Files.exists(tmpPath)) {
-                                                       URI uri = tmpPath.toUri();
-                                                       String uriStr = uri.toString();
-
-                                                       if (Files.isDirectory(tmpPath)) {
-                                                               MessageDialog.openError(browser.getShell(), "Unimplemented directory import",
-                                                                               "Upload of directories in the system is not yet implemented");
-                                                               continue loop;
-                                                       }
-                                                       Path targetPath = currFolderPath.resolve(tmpPath.getFileName().toString());
-                                                       InputStream in = null;
-                                                       try {
-                                                               in = new ByteArrayInputStream(Files.readAllBytes(tmpPath));
-                                                               Files.copy(in, targetPath);
-                                                               Files.delete(tmpPath);
-                                                       } finally {
-                                                               IOUtils.closeQuietly(in);
-                                                       }
-                                                       if (log.isDebugEnabled())
-                                                               log.debug("copied uploaded file " + uriStr + " to " + targetPath.toString());
-                                               } else {
-                                                       String msg = "Cannot copy tmp file from " + tmpPath.toString();
-                                                       if (parPath != null)
-                                                               msg += "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS";
-                                                       MessageDialog.openError(browser.getShell(), "Missing file", msg);
-                                                       continue loop;
-                                               }
-                                       }
-                                       browser.refresh();
-                               }
-                       }
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       MessageDialog.openError(getShell(), "Upload has failed", "Cannot import files to " + currFolderPath);
-               }
-       }
-
-       public void setCurrFolderPath(Path currFolderPath) {
-               this.currFolderPath = currFolderPath;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FsStyles.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/FsStyles.java
deleted file mode 100644 (file)
index 9ae3192..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.cms.ui.fs;
-
-/** FS Ui specific CSS styles */
-public interface FsStyles {
-       String BREAD_CRUMB_BTN = "breadCrumb_btn";
-       String CONTEXT_MENU_BOX = "contextMenu_box";
-       String BUTTON_SUFFIX = "_btn";
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/package-info.java
deleted file mode 100644 (file)
index 6a6c272..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** SWT/JFace file system components. */
-package org.argeo.cms.ui.fs;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/Activator.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/Activator.java
deleted file mode 100644 (file)
index e10da3a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.argeo.cms.ui.internal;
-
-import org.argeo.api.cms.CmsState;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.util.tracker.ServiceTracker;
-
-public class Activator implements BundleActivator {
-
-       // avoid dependency to RWT OSGi
-       private final static String CONTEXT_NAME_PROP = "contextName";
-
-       private static ServiceTracker<CmsState, CmsState> nodeState;
-
-       // @Override
-       public void start(BundleContext bc) throws Exception {
-               // UI
-//             bc.registerService(ApplicationConfiguration.class, new MaintenanceUi(),
-//                             LangUtils.dico(CONTEXT_NAME_PROP, "system"));
-//             bc.registerService(ApplicationConfiguration.class, new UserUi(), LangUtils.dico(CONTEXT_NAME_PROP, "user"));
-
-               nodeState = new ServiceTracker<>(bc, CmsState.class, null);
-               nodeState.open();
-       }
-
-       @Override
-       public void stop(BundleContext context) throws Exception {
-               if (nodeState != null) {
-                       nodeState.close();
-                       nodeState = null;
-               }
-       }
-
-       public static CmsState getNodeState() {
-               return nodeState.getService();
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/JcrContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/JcrContentProvider.java
deleted file mode 100644 (file)
index ea0abdf..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.argeo.cms.ui.internal;
-
-import java.util.ArrayList;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsException;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-@Deprecated
-class JcrContentProvider implements ITreeContentProvider {
-       private static final long serialVersionUID = -1333678161322488674L;
-
-       @Override
-       public void dispose() {
-       }
-
-       @Override
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-               if (newInput == null)
-                       return;
-               if (!(newInput instanceof Node))
-                       throw new CmsException("Input " + newInput + " must be a node");
-       }
-
-       @Override
-       public Object[] getElements(Object inputElement) {
-               try {
-                       Node node = (Node) inputElement;
-                       ArrayList<Node> arr = new ArrayList<Node>();
-                       NodeIterator nit = node.getNodes();
-                       while (nit.hasNext()) {
-                               arr.add(nit.nextNode());
-                       }
-                       return arr.toArray();
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot get elements", e);
-               }
-       }
-
-       @Override
-       public Object[] getChildren(Object parentElement) {
-               try {
-                       Node node = (Node) parentElement;
-                       ArrayList<Node> arr = new ArrayList<Node>();
-                       NodeIterator nit = node.getNodes();
-                       while (nit.hasNext()) {
-                               arr.add(nit.nextNode());
-                       }
-                       return arr.toArray();
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot get elements", e);
-               }
-       }
-
-       @Override
-       public Object getParent(Object element) {
-               try {
-                       Node node = (Node) element;
-                       if (node.getName().equals(""))
-                               return null;
-                       else
-                               return node.getParent();
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot get elements", e);
-               }
-       }
-
-       @Override
-       public boolean hasChildren(Object element) {
-               try {
-                       Node node = (Node) element;
-                       return node.hasNodes();
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot get elements", e);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/JcrFileUploadReceiver.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/JcrFileUploadReceiver.java
deleted file mode 100644 (file)
index 60bb42b..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.argeo.cms.ui.internal;
-
-import static javax.jcr.nodetype.NodeType.NT_FILE;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.commons.io.FilenameUtils;
-import org.argeo.api.cms.ux.CmsImageManager;
-import org.argeo.cms.ui.widgets.Img;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.rap.fileupload.FileDetails;
-import org.eclipse.rap.fileupload.FileUploadReceiver;
-
-public class JcrFileUploadReceiver extends FileUploadReceiver {
-       private Img img;
-       private final Node parentNode;
-       private final String nodeName;
-       private final CmsImageManager imageManager;
-
-       /** If nodeName is null, use the uploaded file name */
-       public JcrFileUploadReceiver(Img img, Node parentNode, String nodeName, CmsImageManager imageManager) {
-               super();
-               this.img = img;
-               this.parentNode = parentNode;
-               this.nodeName = nodeName;
-               this.imageManager = imageManager;
-       }
-
-       @Override
-       public void receive(InputStream stream, FileDetails details) throws IOException {
-               try {
-                       String fileName = nodeName != null ? nodeName : details.getFileName();
-                       String contentType = details.getContentType();
-                       if (isImage(details.getFileName(), contentType)) {
-                               imageManager.uploadImage(img.getNode(),parentNode, fileName, stream, contentType);
-                               return;
-                       }
-
-                       Node fileNode;
-                       if (parentNode.hasNode(fileName)) {
-                               fileNode = parentNode.getNode(fileName);
-                               if (!fileNode.isNodeType(NT_FILE))
-                                       fileNode.remove();
-                       }
-                       fileNode = JcrUtils.copyStreamAsFile(parentNode, fileName, stream);
-
-                       if (contentType != null) {
-                               fileNode.addMixin(NodeType.MIX_MIMETYPE);
-                               fileNode.setProperty(Property.JCR_MIMETYPE, contentType);
-                       }
-                       processNewFile(fileNode);
-                       fileNode.getSession().save();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot receive " + details, e);
-               }
-       }
-
-       protected Boolean isImage(String fileName, String contentType) {
-               String ext = FilenameUtils.getExtension(fileName);
-               return ext != null && (ext.equals("png") || ext.equalsIgnoreCase("jpg"));
-       }
-
-       protected void processNewFile(Node node) {
-
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/SimpleEditableImage.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/SimpleEditableImage.java
deleted file mode 100644 (file)
index 6162a74..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.argeo.cms.ui.internal;
-
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.cms.ui.widgets.EditableImage;
-import org.argeo.cms.ux.AbstractImageManager;
-import org.argeo.cms.ux.CmsUxUtils;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Text;
-
-/** NOT working yet. */
-public class SimpleEditableImage extends EditableImage {
-       private static final long serialVersionUID = -5689145523114022890L;
-
-       private String src;
-       private Cms2DSize imageSize;
-
-       public SimpleEditableImage(Composite parent, int swtStyle) {
-               super(parent, swtStyle);
-               // load(getControl());
-               getParent().layout();
-       }
-
-       public SimpleEditableImage(Composite parent, int swtStyle, String src, Cms2DSize imageSize) {
-               super(parent, swtStyle);
-               this.src = src;
-               this.imageSize = imageSize;
-       }
-
-       @Override
-       protected Control createControl(Composite box, String style) {
-               if (isEditing()) {
-                       return createText(box, style);
-               } else {
-                       return createLabel(box, style);
-               }
-       }
-
-       protected String createImgTag() throws RepositoryException {
-               String imgTag;
-               if (src != null)
-                       imgTag = CmsUxUtils.img(src, imageSize);
-               else
-                       imgTag = CmsUiUtils.noImg(imageSize != null ? imageSize : AbstractImageManager.NO_IMAGE_SIZE);
-               return imgTag;
-       }
-
-       protected Text createText(Composite box, String style) {
-               Text text = new Text(box, getStyle());
-               CmsSwtUtils.style(text, style);
-               return text;
-       }
-
-       public String getSrc() {
-               return src;
-       }
-
-       public void setSrc(String src) {
-               this.src = src;
-       }
-
-       public Cms2DSize getImageSize() {
-               return imageSize;
-       }
-
-       public void setImageSize(Cms2DSize imageSize) {
-               this.imageSize = imageSize;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java
deleted file mode 100644 (file)
index 3806341..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Observable;
-import java.util.TreeMap;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-
-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 = CmsConstants.CN;
-       /** Key for a JCR repository URI */
-       // public final static String JCR_REPOSITORY_URI = "argeo.jcr.repository.uri";
-       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>());
-
-       @SuppressWarnings("rawtypes")
-       public synchronized Repository getRepository(Map parameters) throws RepositoryException {
-               if (!parameters.containsKey(CN))
-                       throw new RepositoryException("Parameter " + CN + " has to be defined.");
-               String alias = parameters.get(CN).toString();
-               if (!repositories.containsKey(alias))
-                       throw new RepositoryException("No repository registered with alias " + alias);
-
-               return repositories.get(alias);
-       }
-
-       /** Access to the read-only map */
-       public synchronized Map<String, Repository> getRepositories() {
-               return repositories;
-       }
-
-       /** Registers a service, typically called when OSGi services are bound. */
-       @SuppressWarnings("rawtypes")
-       public synchronized void register(Repository repository, Map properties) {
-               String alias;
-               if (properties == null || !properties.containsKey(CN)) {
-                       log.warn("Cannot register a repository if no " + CN + " property is specified.");
-                       return;
-               }
-               alias = properties.get(CN).toString();
-               Map<String, Repository> map = new TreeMap<String, Repository>(repositories);
-               map.put(alias, repository);
-               repositories = Collections.unmodifiableMap(map);
-               setChanged();
-               notifyObservers(alias);
-       }
-
-       /** Unregisters a service, typically called when OSGi services are unbound. */
-       @SuppressWarnings("rawtypes")
-       public synchronized void unregister(Repository repository, Map properties) {
-               // TODO: also check bean name?
-               if (properties == null || !properties.containsKey(CN)) {
-                       log.warn("Cannot unregister a repository without property " + CN);
-                       return;
-               }
-
-               String alias = properties.get(CN).toString();
-               Map<String, Repository> map = new TreeMap<String, Repository>(repositories);
-               if (map.remove(alias) == null) {
-                       log.warn("No repository was registered with alias " + alias);
-                       return;
-               }
-               repositories = Collections.unmodifiableMap(map);
-               setChanged();
-               notifyObservers(alias);
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/FullVersioningTreeContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/FullVersioningTreeContentProvider.java
deleted file mode 100644 (file)
index 0f7ee77..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionIterator;
-import javax.jcr.version.VersionManager;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Display some version information of a JCR full versionable node in a tree
- * like structure
- */
-public class FullVersioningTreeContentProvider implements ITreeContentProvider {
-       private static final long serialVersionUID = 8691772509491211112L;
-
-       /**
-        * Sends back the first level of the Tree. input element must be a single
-        * node object
-        */
-       public Object[] getElements(Object inputElement) {
-               try {
-                       Node rootNode = (Node) inputElement;
-                       String curPath = rootNode.getPath();
-                       VersionManager vm = rootNode.getSession().getWorkspace()
-                                       .getVersionManager();
-
-                       VersionHistory vh = vm.getVersionHistory(curPath);
-                       List<Version> result = new ArrayList<Version>();
-                       VersionIterator vi = vh.getAllLinearVersions();
-
-                       while (vi.hasNext()) {
-                               result.add(vi.nextVersion());
-                       }
-                       return result.toArray();
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException(
-                                       "Unexpected error while getting version elements", re);
-               }
-       }
-
-       public Object[] getChildren(Object parentElement) {
-               try {
-                       if (parentElement instanceof Version) {
-                               List<Node> tmp = new ArrayList<Node>();
-                               tmp.add(((Version) parentElement).getFrozenNode());
-                               return tmp.toArray();
-                       }
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unexpected error while getting child "
-                                       + "node for version element", re);
-               }
-               return null;
-       }
-
-       public Object getParent(Object element) {
-               try {
-                       // this will not work in a simpleVersionning environment, parent is
-                       // not a node.
-                       if (element instanceof Node
-                                       && ((Node) element).isNodeType(NodeType.NT_FROZEN_NODE)) {
-                               Node node = (Node) element;
-                               return node.getParent();
-                       } else
-                               return null;
-               } catch (RepositoryException e) {
-                       return null;
-               }
-       }
-
-       public boolean hasChildren(Object element) {
-               try {
-                       if (element instanceof Version)
-                               return true;
-                       else if (element instanceof Node)
-                               return ((Node) element).hasNodes();
-                       else
-                               return false;
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot check children of " + element, e);
-               }
-       }
-
-       public void dispose() {
-       }
-
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrBrowserUtils.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrBrowserUtils.java
deleted file mode 100644 (file)
index b36acc3..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.ui.jcr.model.RepositoriesElem;
-import org.argeo.cms.ui.jcr.model.RepositoryElem;
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.cms.ui.jcr.model.WorkspaceElem;
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-
-/** Useful methods to manage the JCR Browser */
-public class JcrBrowserUtils {
-
-       public static String getPropertyTypeAsString(Property prop) {
-               try {
-                       return PropertyType.nameFromValue(prop.getType());
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot check type for " + prop, e);
-               }
-       }
-
-       /** Insure that the UI component is not stale, refresh if needed */
-       public static void forceRefreshIfNeeded(TreeParent element) {
-               Node curNode = null;
-
-               boolean doRefresh = false;
-
-               try {
-                       if (element instanceof SingleJcrNodeElem) {
-                               curNode = ((SingleJcrNodeElem) element).getNode();
-                       } else if (element instanceof WorkspaceElem) {
-                               curNode = ((WorkspaceElem) element).getRootNode();
-                       }
-
-                       if (curNode != null && element.getChildren().length != curNode.getNodes().getSize())
-                               doRefresh = true;
-                       else if (element instanceof RepositoryElem) {
-                               RepositoryElem rn = (RepositoryElem) element;
-                               if (rn.isConnected()) {
-                                       String[] wkpNames = rn.getAccessibleWorkspaceNames();
-                                       if (element.getChildren().length != wkpNames.length)
-                                               doRefresh = true;
-                               }
-                       } else if (element instanceof RepositoriesElem) {
-                               doRefresh = true;
-                               // Always force refresh for RepositoriesElem : the condition
-                               // below does not take remote repository into account and it is
-                               // not trivial to do so.
-
-                               // RepositoriesElem rn = (RepositoriesElem) element;
-                               // if (element.getChildren().length !=
-                               // rn.getRepositoryRegister()
-                               // .getRepositories().size())
-                               // doRefresh = true;
-                       }
-                       if (doRefresh) {
-                               element.clearChildren();
-                               element.getChildren();
-                       }
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unexpected error while synchronising the UI with the JCR repository", re);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrDClickListener.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrDClickListener.java
deleted file mode 100644 (file)
index 1707681..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import javax.jcr.Node;
-
-import org.argeo.cms.ui.jcr.model.RepositoryElem;
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.cms.ui.jcr.model.WorkspaceElem;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-
-/** Centralizes the management of double click on a NodeTreeViewer */
-public class JcrDClickListener implements IDoubleClickListener {
-       // private final static Log log = LogFactory
-       // .getLog(GenericNodeDoubleClickListener.class);
-
-       private TreeViewer nodeViewer;
-
-       // private JcrFileProvider jfp;
-       // private FileHandler fileHandler;
-
-       public JcrDClickListener(TreeViewer nodeViewer) {
-               this.nodeViewer = nodeViewer;
-               // jfp = new JcrFileProvider();
-               // Commented out. see https://www.argeo.org/bugzilla/show_bug.cgi?id=188
-               // fileHandler = null;
-               // fileHandler = new FileHandler(jfp);
-       }
-
-       public void doubleClick(DoubleClickEvent event) {
-               if (event.getSelection() == null || event.getSelection().isEmpty())
-                       return;
-               Object obj = ((IStructuredSelection) event.getSelection()).getFirstElement();
-               if (obj instanceof RepositoryElem) {
-                       RepositoryElem rpNode = (RepositoryElem) obj;
-                       if (rpNode.isConnected()) {
-                               rpNode.logout();
-                       } else {
-                               rpNode.login();
-                       }
-                       nodeViewer.refresh(obj);
-               } else if (obj instanceof WorkspaceElem) {
-                       WorkspaceElem wn = (WorkspaceElem) obj;
-                       if (wn.isConnected())
-                               wn.logout();
-                       else
-                               wn.login();
-                       nodeViewer.refresh(obj);
-               } else if (obj instanceof SingleJcrNodeElem) {
-                       SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj;
-                       Node node = sjn.getNode();
-                       openNode(node);
-               }
-       }
-
-       protected void openNode(Node node) {
-               // TODO implement generic behaviour
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrImages.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrImages.java
deleted file mode 100644 (file)
index d1d1e31..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import org.argeo.cms.ui.theme.CmsImages;
-import org.eclipse.swt.graphics.Image;
-
-/** Shared icons. */
-public class JcrImages {
-       public final static Image NODE = CmsImages.createIcon("node.gif");
-       public final static Image FOLDER = CmsImages.createIcon("folder.gif");
-       public final static Image FILE = CmsImages.createIcon("file.gif");
-       public final static Image BINARY = CmsImages.createIcon("binary.png");
-       public final static Image HOME = CmsImages.createIcon("person-logged-in.png");
-       public final static Image SORT = CmsImages.createIcon("sort.gif");
-       public final static Image REMOVE = CmsImages.createIcon("remove.gif");
-
-       public final static Image REPOSITORIES = CmsImages.createIcon("repositories.gif");
-       public final static Image REPOSITORY_DISCONNECTED = CmsImages.createIcon("repository_disconnected.gif");
-       public final static Image REPOSITORY_CONNECTED = CmsImages.createIcon("repository_connected.gif");
-       public final static Image REMOTE_DISCONNECTED = CmsImages.createIcon("remote_disconnected.gif");
-       public final static Image REMOTE_CONNECTED = CmsImages.createIcon("remote_connected.gif");
-       public final static Image WORKSPACE_DISCONNECTED = CmsImages.createIcon("workspace_disconnected.png");
-       public final static Image WORKSPACE_CONNECTED = CmsImages.createIcon("workspace_connected.png");
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java
deleted file mode 100644 (file)
index cc8479f..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.jcr.util.JcrItemsComparator;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Implementation of the {@code ITreeContentProvider} in order to display a
- * single JCR node and its children in a tree like structure
- */
-public class JcrTreeContentProvider implements ITreeContentProvider {
-       private static final long serialVersionUID = -2128326504754297297L;
-       // private Node rootNode;
-       private JcrItemsComparator itemComparator = new JcrItemsComparator();
-
-       /**
-        * Sends back the first level of the Tree. input element must be a single node
-        * object
-        */
-       public Object[] getElements(Object inputElement) {
-               Node rootNode = (Node) inputElement;
-               return childrenNodes(rootNode);
-       }
-
-       public Object[] getChildren(Object parentElement) {
-               return childrenNodes((Node) parentElement);
-       }
-
-       public Object getParent(Object element) {
-               try {
-                       Node node = (Node) element;
-                       if (!node.getPath().equals("/"))
-                               return node.getParent();
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       return null;
-               }
-       }
-
-       public boolean hasChildren(Object element) {
-               try {
-                       return ((Node) element).hasNodes();
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot check children existence on " + element, e);
-               }
-       }
-
-       protected Object[] childrenNodes(Node parentNode) {
-               try {
-                       List<Node> children = new ArrayList<Node>();
-                       NodeIterator nit = parentNode.getNodes();
-                       while (nit.hasNext()) {
-                               Node node = nit.nextNode();
-//                             if (node.getName().startsWith("rep:") || node.getName().startsWith("jcr:")
-//                                             || node.getName().startsWith("nt:"))
-//                                     continue nodes;
-                               children.add(node);
-                       }
-                       Node[] arr = children.toArray(new Node[0]);
-                       Arrays.sort(arr, itemComparator);
-                       return arr;
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot list children of " + parentNode, e);
-               }
-       }
-
-       public void dispose() {
-       }
-
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java
deleted file mode 100644 (file)
index 0625cc8..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-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.cms.ux.widgets.TreeParent;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Implementation of the {@code ITreeContentProvider} to display multiple
- * repository environment in a tree like structure
- */
-public class NodeContentProvider implements ITreeContentProvider {
-       private static final long serialVersionUID = -4083809398848374403L;
-       final private RepositoryRegister repositoryRegister;
-       final private RepositoryFactory repositoryFactory;
-
-       // Current user session on the default workspace of the argeo Node
-       final private Session userSession;
-       final private Keyring keyring;
-       private boolean sortChildren;
-
-       // Reference for cleaning
-       private SingleJcrNodeElem homeNode = null;
-       private RepositoriesElem repositoriesNode = null;
-
-       // Utils
-       private TreeBrowserComparator itemComparator = new TreeBrowserComparator();
-
-       public NodeContentProvider(Session userSession, Keyring keyring,
-                       RepositoryRegister repositoryRegister,
-                       RepositoryFactory repositoryFactory, Boolean sortChildren) {
-               this.userSession = userSession;
-               this.keyring = keyring;
-               this.repositoryRegister = repositoryRegister;
-               this.repositoryFactory = repositoryFactory;
-               this.sortChildren = sortChildren;
-       }
-
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-               if (newInput == null)// dispose
-                       return;
-
-               if (userSession != null) {
-                       Node userHome = CmsJcrUtils.getUserHome(userSession);
-                       if (userHome != null) {
-                               // TODO : find a way to dynamically get alias for the node
-                               if (homeNode != null)
-                                       homeNode.dispose();
-                               homeNode = new SingleJcrNodeElem(null, userHome,
-                                               userSession.getUserID(), CmsConstants.EGO_REPOSITORY);
-                       }
-               }
-               if (repositoryRegister != null) {
-                       if (repositoriesNode != null)
-                               repositoriesNode.dispose();
-                       repositoriesNode = new RepositoriesElem("Repositories",
-                                       repositoryRegister, repositoryFactory, null, userSession,
-                                       keyring);
-               }
-       }
-
-       /**
-        * Sends back the first level of the Tree. Independent from inputElement
-        * that can be null
-        */
-       public Object[] getElements(Object inputElement) {
-               List<Object> objs = new ArrayList<Object>();
-               if (homeNode != null)
-                       objs.add(homeNode);
-               if (repositoriesNode != null)
-                       objs.add(repositoriesNode);
-               return objs.toArray();
-       }
-
-       public Object[] getChildren(Object parentElement) {
-               if (parentElement instanceof TreeParent) {
-                       if (sortChildren) {
-                               Object[] tmpArr = ((TreeParent) parentElement).getChildren();
-                               if (tmpArr == null)
-                                       return new Object[0];
-                               TreeParent[] arr = new TreeParent[tmpArr.length];
-                               for (int i = 0; i < tmpArr.length; i++)
-                                       arr[i] = (TreeParent) tmpArr[i];
-                               Arrays.sort(arr, itemComparator);
-                               return arr;
-                       } else
-                               return ((TreeParent) parentElement).getChildren();
-               } else
-                       return new Object[0];
-       }
-
-       /**
-        * Sets whether the content provider should order the children nodes or not.
-        * It is user duty to call a full refresh of the tree after changing this
-        * parameter.
-        */
-       public void setSortChildren(boolean sortChildren) {
-               this.sortChildren = sortChildren;
-       }
-
-       public Object getParent(Object element) {
-               if (element instanceof TreeParent) {
-                       return ((TreeParent) element).getParent();
-               } else
-                       return null;
-       }
-
-       public boolean hasChildren(Object element) {
-               if (element instanceof RepositoriesElem) {
-                       RepositoryRegister rr = ((RepositoriesElem) element)
-                                       .getRepositoryRegister();
-                       return rr.getRepositories().size() > 0;
-               } else if (element instanceof TreeParent) {
-                       TreeParent tp = (TreeParent) element;
-                       return tp.hasChildren();
-               }
-               return false;
-       }
-
-       public void dispose() {
-               if (homeNode != null)
-                       homeNode.dispose();
-               if (repositoriesNode != null) {
-                       // logs out open sessions
-                       // see https://bugzilla.argeo.org/show_bug.cgi?id=23
-                       repositoriesNode.dispose();
-               }
-       }
-
-       /**
-        * Specific comparator for this view. See specification here:
-        * https://www.argeo.org/bugzilla/show_bug.cgi?id=139
-        */
-       private class TreeBrowserComparator implements Comparator<TreeParent> {
-
-               public int category(TreeParent element) {
-                       if (element instanceof SingleJcrNodeElem) {
-                               Node node = ((SingleJcrNodeElem) element).getNode();
-                               try {
-                                       if (node.isNodeType(NodeType.NT_FOLDER))
-                                               return 5;
-                               } catch (RepositoryException e) {
-                                       // TODO Auto-generated catch block
-                                       e.printStackTrace();
-                               }
-                       }
-                       return 10;
-               }
-
-               public int compare(TreeParent o1, TreeParent o2) {
-                       int cat1 = category(o1);
-                       int cat2 = category(o2);
-
-                       if (cat1 != cat2) {
-                               return cat1 - cat2;
-                       }
-                       return o1.getName().compareTo(o2.getName());
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java
deleted file mode 100644 (file)
index a5751c0..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import javax.jcr.NamespaceException;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-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;
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.cms.ui.jcr.model.WorkspaceElem;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.graphics.Image;
-
-/** Provides reasonable defaults for know JCR types. */
-public class NodeLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = -3662051696443321843L;
-
-       private final static CmsLog log = CmsLog.getLog(NodeLabelProvider.class);
-
-       public String getText(Object element) {
-               try {
-                       if (element instanceof SingleJcrNodeElem) {
-                               SingleJcrNodeElem sjn = (SingleJcrNodeElem) element;
-                               return getText(sjn.getNode());
-                       } else if (element instanceof Node) {
-                               return getText((Node) element);
-                       } else
-                               return super.getText(element);
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Unexpected JCR error while getting node name.");
-               }
-       }
-
-       protected String getText(Node node) throws RepositoryException {
-               String label = node.getName();
-               StringBuffer mixins = new StringBuffer("");
-               for (NodeType type : node.getMixinNodeTypes())
-                       mixins.append(' ').append(type.getName());
-
-               return label + " [" + node.getPrimaryNodeType().getName() + mixins + "]";
-       }
-
-       @Override
-       public Image getImage(Object element) {
-               if (element instanceof RemoteRepositoryElem) {
-                       if (((RemoteRepositoryElem) element).isConnected())
-                               return JcrImages.REMOTE_CONNECTED;
-                       else
-                               return JcrImages.REMOTE_DISCONNECTED;
-               } else if (element instanceof RepositoryElem) {
-                       if (((RepositoryElem) element).isConnected())
-                               return JcrImages.REPOSITORY_CONNECTED;
-                       else
-                               return JcrImages.REPOSITORY_DISCONNECTED;
-               } else if (element instanceof WorkspaceElem) {
-                       if (((WorkspaceElem) element).isConnected())
-                               return JcrImages.WORKSPACE_CONNECTED;
-                       else
-                               return JcrImages.WORKSPACE_DISCONNECTED;
-               } else if (element instanceof RepositoriesElem) {
-                       return JcrImages.REPOSITORIES;
-               } else if (element instanceof SingleJcrNodeElem) {
-                       Node nodeElem = ((SingleJcrNodeElem) element).getNode();
-                       return getImage(nodeElem);
-
-                       // if (element instanceof Node) {
-                       // return getImage((Node) element);
-                       // } else if (element instanceof WrappedNode) {
-                       // return getImage(((WrappedNode) element).getNode());
-                       // } else if (element instanceof NodesWrapper) {
-                       // return getImage(((NodesWrapper) element).getNode());
-                       // }
-               }
-               // try {
-               // return super.getImage();
-               // } catch (RepositoryException e) {
-               // return null;
-               // }
-               return super.getImage(element);
-       }
-
-       protected Image getImage(Node node) {
-               try {
-                       if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FILE))
-                               return JcrImages.FILE;
-                       else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER))
-                               return JcrImages.FOLDER;
-                       else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_RESOURCE))
-                               return JcrImages.BINARY;
-                       try {
-                               // TODO check workspace type?
-                               if (node.getDepth() == 1 && node.hasProperty(Property.JCR_ID))
-                                       return JcrImages.HOME;
-
-                               // optimizes
-//                             if (node.hasProperty(LdapAttrs.uid.property()) && node.isNodeType(NodeTypes.NODE_USER_HOME))
-//                                     return JcrImages.HOME;
-                       } catch (NamespaceException e) {
-                               // node namespace is not registered in this repo
-                       }
-                       return JcrImages.NODE;
-               } catch (RepositoryException e) {
-                       log.warn("Error while retrieving type for " + node + " in order to display corresponding image");
-                       e.printStackTrace();
-                       return null;
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/OsgiRepositoryRegister.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/OsgiRepositoryRegister.java
deleted file mode 100644 (file)
index 444350a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Repository;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-public class OsgiRepositoryRegister extends DefaultRepositoryRegister {
-       private final static BundleContext bc = FrameworkUtil.getBundle(OsgiRepositoryRegister.class).getBundleContext();
-       private final ServiceTracker<Repository, Repository> repositoryTracker;
-
-       public OsgiRepositoryRegister() {
-               repositoryTracker = new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
-
-                       @Override
-                       public Repository addingService(ServiceReference<Repository> reference) {
-
-                               Repository repository = super.addingService(reference);
-                               Map<String, Object> props = new HashMap<>();
-                               for (String key : reference.getPropertyKeys()) {
-                                       props.put(key, reference.getProperty(key));
-                               }
-                               register(repository, props);
-                               return repository;
-                       }
-
-                       @Override
-                       public void removedService(ServiceReference<Repository> reference, Repository service) {
-                               Map<String, Object> props = new HashMap<>();
-                               for (String key : reference.getPropertyKeys()) {
-                                       props.put(key, reference.getProperty(key));
-                               }
-                               unregister(service, props);
-                               super.removedService(reference, service);
-                       }
-
-               };
-       }
-
-       public void init() {
-               repositoryTracker.open();
-       }
-
-       public void destroy() {
-               repositoryTracker.close();
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertiesContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertiesContentProvider.java
deleted file mode 100644 (file)
index fd544bb..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.jcr.util.JcrItemsComparator;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/** Simple content provider that displays all properties of a given Node */
-public class PropertiesContentProvider implements IStructuredContentProvider {
-       private static final long serialVersionUID = 5227554668841613078L;
-       private JcrItemsComparator itemComparator = new JcrItemsComparator();
-
-       public void dispose() {
-       }
-
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-       }
-
-       public Object[] getElements(Object inputElement) {
-               try {
-                       if (inputElement instanceof Node) {
-                               Set<Property> props = new TreeSet<Property>(itemComparator);
-                               PropertyIterator pit = ((Node) inputElement).getProperties();
-                               while (pit.hasNext())
-                                       props.add(pit.nextProperty());
-                               return props.toArray();
-                       }
-                       return new Object[] {};
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot get element for "
-                                       + inputElement, e);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java
deleted file mode 100644 (file)
index 37b90f7..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import org.argeo.cms.ui.CmsUiConstants;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ViewerCell;
-
-/** Default basic label provider for a given JCR Node's properties */
-public class PropertyLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = -5405794508731390147L;
-
-       // To be able to change column order easily
-       public static final int COLUMN_PROPERTY = 0;
-       public static final int COLUMN_VALUE = 1;
-       public static final int COLUMN_TYPE = 2;
-       public static final int COLUMN_ATTRIBUTES = 3;
-
-       // Utils
-       protected DateFormat timeFormatter = new SimpleDateFormat(CmsUiConstants.DATE_TIME_FORMAT);
-
-       public void update(ViewerCell cell) {
-               Object element = cell.getElement();
-               cell.setText(getColumnText(element, cell.getColumnIndex()));
-       }
-
-       public String getColumnText(Object element, int columnIndex) {
-               try {
-                       if (element instanceof Property) {
-                               Property prop = (Property) element;
-                               if (prop.isMultiple()) {
-                                       switch (columnIndex) {
-                                       case COLUMN_PROPERTY:
-                                               return prop.getName();
-                                       case COLUMN_VALUE:
-                                               // Corresponding values are listed on children
-                                               return "";
-                                       case COLUMN_TYPE:
-                                               return JcrBrowserUtils.getPropertyTypeAsString(prop);
-                                       case COLUMN_ATTRIBUTES:
-                                               return JcrUtils.getPropertyDefinitionAsString(prop);
-                                       }
-                               } else {
-                                       switch (columnIndex) {
-                                       case COLUMN_PROPERTY:
-                                               return prop.getName();
-                                       case COLUMN_VALUE:
-                                               return formatValueAsString(prop.getValue());
-                                       case COLUMN_TYPE:
-                                               return JcrBrowserUtils.getPropertyTypeAsString(prop);
-                                       case COLUMN_ATTRIBUTES:
-                                               return JcrUtils.getPropertyDefinitionAsString(prop);
-                                       }
-                               }
-                       } else if (element instanceof Value) {
-                               Value val = (Value) element;
-                               switch (columnIndex) {
-                               case COLUMN_PROPERTY:
-                                       // Nothing to show
-                                       return "";
-                               case COLUMN_VALUE:
-                                       return formatValueAsString(val);
-                               case COLUMN_TYPE:
-                                       // listed on the parent
-                                       return "";
-                               case COLUMN_ATTRIBUTES:
-                                       // Corresponding attributes are listed on the parent
-                                       return "";
-                               }
-                       }
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Cannot retrieve prop value on " + element, re);
-               }
-               return null;
-       }
-
-       private String formatValueAsString(Value value) {
-               // TODO enhance this method
-               try {
-                       String strValue;
-
-                       if (value.getType() == PropertyType.BINARY)
-                               strValue = "<binary>";
-                       else if (value.getType() == PropertyType.DATE)
-                               strValue = timeFormatter.format(value.getDate().getTime());
-                       else
-                               strValue = value.getString();
-                       return strValue;
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("unexpected error while formatting value", e);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/RepositoryRegister.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/RepositoryRegister.java
deleted file mode 100644 (file)
index 802c756..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryFactory;
-
-/** Allows to register repositories by name. */
-public interface RepositoryRegister extends RepositoryFactory {
-       /**
-        * The registered {@link Repository} as a read-only map. Note that this
-        * method should be called for each access in order to be sure to be up to
-        * date in case repositories have registered/unregistered
-        */
-       public Map<String, Repository> getRepositories();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/VersionLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/VersionLabelProvider.java
deleted file mode 100644 (file)
index 37dfe2b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.argeo.cms.ui.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.version.Version;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-
-/**
- * Simple wrapping of the ColumnLabelProvider class to provide text display in
- * order to build a tree for version. The getText() method does not assume that
- * {@link Version} extends {@link Node} class to respect JCR 2.0 specification
- * 
- */
-public class VersionLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = 5270739851193688238L;
-
-       public String getText(Object element) {
-               try {
-                       if (element instanceof Version) {
-                               Version version = (Version) element;
-                               return version.getName();
-                       } else if (element instanceof Node) {
-                               return ((Node) element).getName();
-                       }
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException(
-                                       "Unexpected error while getting element name", re);
-               }
-               return super.getText(element);
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/MaintainedRepositoryElem.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/MaintainedRepositoryElem.java
deleted file mode 100644 (file)
index d33b33f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.argeo.cms.ui.jcr.model;
-
-import javax.jcr.Repository;
-
-import org.argeo.cms.ux.widgets.TreeParent;
-
-/** Wrap a MaintainedRepository */
-public class MaintainedRepositoryElem extends RepositoryElem {
-
-       public MaintainedRepositoryElem(String alias, Repository repository, TreeParent parent) {
-               super(alias, repository, parent);
-               // if (!(repository instanceof MaintainedRepository)) {
-               // throw new ArgeoException("Repository " + alias
-               // + " is not a maintained repository");
-               // }
-       }
-
-       // protected MaintainedRepository getMaintainedRepository() {
-       // return (MaintainedRepository) getRepository();
-       // }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java
deleted file mode 100644 (file)
index 908d1b1..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.argeo.cms.ui.jcr.model;
-
-import java.util.Arrays;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.argeo.cms.ArgeoNames;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.security.Keyring;
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-
-/** Root of a remote repository */
-public class RemoteRepositoryElem extends RepositoryElem {
-       private final Keyring keyring;
-       /**
-        * A session of the logged in user on the default workspace of the node
-        * repository.
-        */
-       private final Session userSession;
-       private final String remoteNodePath;
-
-       private final RepositoryFactory repositoryFactory;
-       private final String uri;
-
-       public RemoteRepositoryElem(String alias, RepositoryFactory repositoryFactory, String uri, TreeParent parent,
-                       Session userSession, Keyring keyring, String remoteNodePath) {
-               super(alias, null, parent);
-               this.repositoryFactory = repositoryFactory;
-               this.uri = uri;
-               this.keyring = keyring;
-               this.userSession = userSession;
-               this.remoteNodePath = remoteNodePath;
-       }
-
-       @Override
-       protected Session repositoryLogin(String workspaceName) throws RepositoryException {
-               Node remoteRepository = userSession.getNode(remoteNodePath);
-               String userID = remoteRepository.getProperty(ArgeoNames.ARGEO_USER_ID).getString();
-               if (userID.trim().equals("")) {
-                       return getRepository().login(workspaceName);
-               } else {
-                       String pwdPath = remoteRepository.getPath() + '/' + ArgeoNames.ARGEO_PASSWORD;
-                       char[] password = keyring.getAsChars(pwdPath);
-                       try {
-                               SimpleCredentials credentials = new SimpleCredentials(userID, password);
-                               return getRepository().login(credentials, workspaceName);
-                       } finally {
-                               Arrays.fill(password, 0, password.length, ' ');
-                       }
-               }
-       }
-
-       @Override
-       public Repository getRepository() {
-               if (repository == null)
-                       repository = CmsJcrUtils.getRepositoryByUri(repositoryFactory, uri);
-               return super.getRepository();
-       }
-
-       public void remove() {
-               try {
-                       Node remoteNode = userSession.getNode(remoteNodePath);
-                       remoteNode.remove();
-                       remoteNode.getSession().save();
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot remove " + remoteNodePath, e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java
deleted file mode 100644 (file)
index 8c40f8b..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.argeo.cms.ui.jcr.model;
-
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-
-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.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-
-/**
- * UI Tree component that implements the Argeo abstraction of a
- * {@link RepositoryFactory} that enable a user to "mount" various repositories
- * in a single Tree like View. It is usually meant to be at the root of the UI
- * Tree and thus {@link #getParent()} method will return null.
- * 
- * The {@link RepositoryFactory} is injected at instantiation time and must be
- * use get or register new {@link Repository} objects upon which a reference is
- * kept here.
- */
-
-public class RepositoriesElem extends TreeParent implements ArgeoNames {
-       private final RepositoryRegister repositoryRegister;
-       private final RepositoryFactory repositoryFactory;
-
-       /**
-        * A session of the logged in user on the default workspace of the node
-        * repository.
-        */
-       private final Session userSession;
-       private final Keyring keyring;
-
-       public RepositoriesElem(String name, RepositoryRegister repositoryRegister, RepositoryFactory repositoryFactory,
-                       TreeParent parent, Session userSession, Keyring keyring) {
-               super(name);
-               this.repositoryRegister = repositoryRegister;
-               this.repositoryFactory = repositoryFactory;
-               this.userSession = userSession;
-               this.keyring = keyring;
-       }
-
-       /**
-        * Override normal behavior to initialize the various repositories only at
-        * request time
-        */
-       @Override
-       public synchronized Object[] getChildren() {
-               if (isLoaded()) {
-                       return super.getChildren();
-               } else {
-                       // initialize current object
-                       Map<String, Repository> refRepos = repositoryRegister.getRepositories();
-                       for (String name : refRepos.keySet()) {
-                               Repository repository = refRepos.get(name);
-                               // if (repository instanceof MaintainedRepository)
-                               // super.addChild(new MaintainedRepositoryElem(name,
-                               // repository, this));
-                               // else
-                               super.addChild(new RepositoryElem(name, repository, this));
-                       }
-
-                       // remote
-                       if (keyring != null) {
-                               try {
-                                       addRemoteRepositories(keyring);
-                               } catch (RepositoryException e) {
-                                       throw new EclipseUiException("Cannot browse remote repositories", e);
-                               }
-                       }
-                       return super.getChildren();
-               }
-       }
-
-       protected void addRemoteRepositories(Keyring jcrKeyring) throws RepositoryException {
-               Node userHome = CmsJcrUtils.getUserHome(userSession);
-               if (userHome != null && userHome.hasNode(ARGEO_REMOTE)) {
-                       NodeIterator it = userHome.getNode(ARGEO_REMOTE).getNodes();
-                       while (it.hasNext()) {
-                               Node remoteNode = it.nextNode();
-                               String uri = remoteNode.getProperty(ARGEO_URI).getString();
-                               try {
-                                       RemoteRepositoryElem remoteRepositoryNode = new RemoteRepositoryElem(remoteNode.getName(),
-                                                       repositoryFactory, uri, this, userSession, jcrKeyring, remoteNode.getPath());
-                                       super.addChild(remoteRepositoryNode);
-                               } catch (Exception e) {
-                                       ErrorFeedback.show("Cannot add remote repository " + remoteNode, e);
-                               }
-                       }
-               }
-       }
-
-       public void registerNewRepository(String alias, Repository repository) {
-               // TODO: implement this
-               // Create a new RepositoryNode Object
-               // add it
-               // super.addChild(new RepositoriesNode(...));
-       }
-
-       /** Returns the {@link RepositoryRegister} wrapped by this object. */
-       public RepositoryRegister getRepositoryRegister() {
-               return repositoryRegister;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java
deleted file mode 100644 (file)
index 296c369..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.argeo.cms.ui.jcr.model;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.jcr.JcrUtils;
-
-/**
- * UI Tree component that wraps a JCR {@link Repository}. It also keeps a
- * reference to its parent Tree Ui component; typically the unique
- * {@link RepositoriesElem} object of the current view to enable bi-directionnal
- * browsing in the tree.
- */
-
-public class RepositoryElem extends TreeParent {
-       private String alias;
-       protected Repository repository;
-       private Session defaultSession = null;
-
-       /** Create a new repository with distinct name and alias */
-       public RepositoryElem(String alias, Repository repository, TreeParent parent) {
-               super(alias);
-               this.repository = repository;
-               setParent(parent);
-               this.alias = alias;
-       }
-
-       public void login() {
-               try {
-                       defaultSession = repositoryLogin(CmsConstants.SYS_WORKSPACE);
-                       String[] wkpNames = defaultSession.getWorkspace().getAccessibleWorkspaceNames();
-                       for (String wkpName : wkpNames) {
-                               if (wkpName.equals(defaultSession.getWorkspace().getName()))
-                                       addChild(new WorkspaceElem(this, wkpName, defaultSession));
-                               else
-                                       addChild(new WorkspaceElem(this, wkpName));
-                       }
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot connect to repository " + alias, e);
-               }
-       }
-
-       public synchronized void logout() {
-               for (Object child : getChildren()) {
-                       if (child instanceof WorkspaceElem)
-                               ((WorkspaceElem) child).logout();
-               }
-               clearChildren();
-               JcrUtils.logoutQuietly(defaultSession);
-               defaultSession = null;
-       }
-
-       /**
-        * Actual call to the {@link Repository#login(javax.jcr.Credentials, String)}
-        * method. To be overridden.
-        */
-       protected Session repositoryLogin(String workspaceName) throws RepositoryException {
-               return repository.login(workspaceName);
-       }
-
-       public String[] getAccessibleWorkspaceNames() {
-               try {
-                       return defaultSession.getWorkspace().getAccessibleWorkspaceNames();
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot retrieve workspace names", e);
-               }
-       }
-
-       public void createWorkspace(String workspaceName) {
-               if (!isConnected())
-                       login();
-               try {
-                       defaultSession.getWorkspace().createWorkspace(workspaceName);
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot create workspace", e);
-               }
-       }
-
-       /** returns the {@link Repository} referenced by the current UI Node */
-       public Repository getRepository() {
-               return repository;
-       }
-
-       public String getAlias() {
-               return alias;
-       }
-
-       public Boolean isConnected() {
-               if (defaultSession != null && defaultSession.isLive())
-                       return true;
-               else
-                       return false;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/SingleJcrNodeElem.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/SingleJcrNodeElem.java
deleted file mode 100644 (file)
index a2584a5..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.argeo.cms.ui.jcr.model;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Workspace;
-
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-
-/**
- * UI Tree component. Wraps a node of a JCR {@link Workspace}. It also keeps a
- * reference to its parent node that can either be a {@link WorkspaceElem}, a
- * {@link SingleJcrNodeElem} or null if the node is "mounted" as the root of the
- * UI tree.
- */
-public class SingleJcrNodeElem extends TreeParent {
-
-       private final Node node;
-       private String alias = null;
-
-       /** Creates a new UiNode in the UI Tree */
-       public SingleJcrNodeElem(TreeParent parent, Node node, String name) {
-               super(name);
-               setParent(parent);
-               this.node = node;
-       }
-
-       /**
-        * Creates a new UiNode in the UI Tree, keeping a reference to the alias of
-        * the corresponding repository in the current UI environment. It is useful
-        * to be able to mount nodes as roots of the UI tree.
-        */
-       public SingleJcrNodeElem(TreeParent parent, Node node, String name, String alias) {
-               super(name);
-               setParent(parent);
-               this.node = node;
-               this.alias = alias;
-       }
-
-       /** Returns the node wrapped by the current UI object */
-       public Node getNode() {
-               return node;
-       }
-
-       protected String getRepositoryAlias() {
-               return alias;
-       }
-
-       /**
-        * Overrides normal behaviour to initialise children only when first
-        * requested
-        */
-       @Override
-       public synchronized Object[] getChildren() {
-               if (isLoaded()) {
-                       return super.getChildren();
-               } else {
-                       // initialize current object
-                       try {
-                               NodeIterator ni = node.getNodes();
-                               while (ni.hasNext()) {
-                                       Node curNode = ni.nextNode();
-                                       addChild(new SingleJcrNodeElem(this, curNode, curNode.getName()));
-                               }
-                               return super.getChildren();
-                       } catch (RepositoryException re) {
-                               throw new EclipseUiException("Cannot initialize SingleJcrNode children", re);
-                       }
-               }
-       }
-
-       @Override
-       public boolean hasChildren() {
-               try {
-                       if (node.getSession().isLive())
-                               return node.hasNodes();
-                       else
-                               return false;
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Cannot check children node existence", re);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/WorkspaceElem.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/WorkspaceElem.java
deleted file mode 100644 (file)
index 2d78666..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.argeo.cms.ui.jcr.model;
-
-import javax.jcr.AccessDeniedException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-// import javax.jcr.Workspace;
-import javax.jcr.Workspace;
-
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.jcr.JcrUtils;
-
-/**
- * UI Tree component. Wraps the root node of a JCR {@link Workspace}. It also
- * keeps a reference to its parent {@link RepositoryElem}, to be able to
- * retrieve alias of the current used repository
- */
-public class WorkspaceElem extends TreeParent {
-       private Session session = null;
-
-       public WorkspaceElem(RepositoryElem parent, String name) {
-               this(parent, name, null);
-       }
-
-       public WorkspaceElem(RepositoryElem parent, String name, Session session) {
-               super(name);
-               this.session = session;
-               setParent(parent);
-       }
-
-       public synchronized Session getSession() {
-               return session;
-       }
-
-       public synchronized Node getRootNode() {
-               try {
-                       if (session != null)
-                               return session.getRootNode();
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot get root node of workspace " + getName(), e);
-               }
-       }
-
-       public synchronized void login() {
-               try {
-                       session = ((RepositoryElem) getParent()).repositoryLogin(getName());
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot connect to repository " + getName(), e);
-               }
-       }
-
-       public Boolean isConnected() {
-               if (session != null && session.isLive())
-                       return true;
-               else
-                       return false;
-       }
-
-       @Override
-       public synchronized void dispose() {
-               logout();
-               super.dispose();
-       }
-
-       /** Logouts the session, does not nothing if there is no live session. */
-       public synchronized void logout() {
-               clearChildren();
-               JcrUtils.logoutQuietly(session);
-               session = null;
-       }
-
-       @Override
-       public synchronized boolean hasChildren() {
-               try {
-                       if (isConnected())
-                               try {
-                                       return session.getRootNode().hasNodes();
-                               } catch (AccessDeniedException e) {
-                                       // current user may not have access to the root node
-                                       return false;
-                               }
-                       else
-                               return false;
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unexpected error while checking children node existence", re);
-               }
-       }
-
-       /** Override normal behaviour to initialize display of the workspace */
-       @Override
-       public synchronized Object[] getChildren() {
-               if (isLoaded()) {
-                       return super.getChildren();
-               } else {
-                       // initialize current object
-                       try {
-                               Node rootNode;
-                               if (session == null)
-                                       return null;
-                               else
-                                       rootNode = session.getRootNode();
-                               NodeIterator ni = rootNode.getNodes();
-                               while (ni.hasNext()) {
-                                       Node node = ni.nextNode();
-                                       addChild(new SingleJcrNodeElem(this, node, node.getName()));
-                               }
-                               return super.getChildren();
-                       } catch (RepositoryException e) {
-                               throw new EclipseUiException("Cannot initialize WorkspaceNode UI object." + getName(), e);
-                       }
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/package-info.java
deleted file mode 100644 (file)
index 8f54744..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Model for SWT/JFace JCR components. */
-package org.argeo.cms.ui.jcr.model;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/package-info.java
deleted file mode 100644 (file)
index 26ae330..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** SWT/JFace JCR components. */
-package org.argeo.cms.ui.jcr;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/package-info.java
deleted file mode 100644 (file)
index 82fdee7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** SWT/JFace components for Argeo CMS. */
-package org.argeo.cms.ui;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsLink.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsLink.java
deleted file mode 100644 (file)
index e91f9ba..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.ux.CmsStyle;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.jcr.JcrException;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.service.ResourceManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.osgi.framework.BundleContext;
-
-/** A link to an internal or external location. */
-public class CmsLink implements CmsUiProvider {
-       private final static CmsLog log = CmsLog.getLog(CmsLink.class);
-       private BundleContext bundleContext;
-
-       private String label;
-       private String style;
-       private String target;
-       private String image;
-       private boolean openNew = false;
-       private MouseListener mouseListener;
-
-       private int horizontalAlignment = SWT.CENTER;
-       private int verticalAlignment = SWT.CENTER;
-
-       private String loggedInLabel = null;
-       private String loggedInTarget = null;
-
-       // internal
-       // private Boolean isUrl = false;
-       private Integer imageWidth, imageHeight;
-
-       public CmsLink() {
-               super();
-       }
-
-       public CmsLink(String label, String target) {
-               this(label, target, (String) null);
-       }
-
-       public CmsLink(String label, String target, CmsStyle style) {
-               this(label, target, style != null ? style.style() : null);
-       }
-
-       public CmsLink(String label, String target, String style) {
-               super();
-               this.label = label;
-               this.target = target;
-               this.style = style;
-               init();
-       }
-
-       public void init() {
-               if (image != null) {
-                       ImageData image = loadImage();
-                       if (imageHeight == null && imageWidth == null) {
-                               imageWidth = image.width;
-                               imageHeight = image.height;
-                       } else if (imageHeight == null) {
-                               imageHeight = (imageWidth * image.height) / image.width;
-                       } else if (imageWidth == null) {
-                               imageWidth = (imageHeight * image.width) / image.height;
-                       }
-               }
-       }
-
-       /** @return {@link Composite} with a single {@link Label} child. */
-       @Override
-       public Control createUi(final Composite parent, Node context) {
-//             if (image != null && (imageWidth == null || imageHeight == null)) {
-//                     throw new CmsException("Image is not properly configured."
-//                                     + " Make sure bundleContext property is set and init() method has been called.");
-//             }
-
-               Composite comp = new Composite(parent, SWT.NONE);
-               comp.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
-               Label link = new Label(comp, SWT.NONE);
-               CmsSwtUtils.markup(link);
-               GridData layoutData = new GridData(horizontalAlignment, verticalAlignment, false, false);
-               if (image != null) {
-                       if (imageHeight != null)
-                               layoutData.heightHint = imageHeight;
-                       if (label == null)
-                               if (imageWidth != null)
-                                       layoutData.widthHint = imageWidth;
-               }
-
-               link.setLayoutData(layoutData);
-               CmsSwtUtils.style(comp, style != null ? style : getDefaultStyle());
-               CmsSwtUtils.style(link, style != null ? style : getDefaultStyle());
-
-               // label
-               StringBuilder labelText = new StringBuilder();
-               if (loggedInTarget != null && isLoggedIn()) {
-                       labelText.append("<a style='color:inherit;text-decoration:inherit;' href=\"");
-                       if (loggedInTarget.equals("")) {
-                               try {
-                                       Node homeNode = CmsJcrUtils.getUserHome(context.getSession());
-                                       String homePath = homeNode.getPath();
-                                       labelText.append("/#" + homePath);
-                               } catch (RepositoryException e) {
-                                       throw new JcrException("Cannot get home path", e);
-                               }
-                       } else {
-                               labelText.append(loggedInTarget);
-                       }
-                       labelText.append("\">");
-               } else if (target != null) {
-                       labelText.append("<a style='color:inherit;text-decoration:inherit;' href='");
-                       labelText.append(target).append("'");
-                       if (openNew) {
-                               labelText.append(" target='_blank'");
-                       }
-                       labelText.append(">");
-               }
-               if (image != null) {
-                       registerImageIfNeeded();
-                       String imageLocation = RWT.getResourceManager().getLocation(image);
-                       labelText.append("<img");
-                       if (imageWidth != null)
-                               labelText.append(" width='").append(imageWidth).append('\'');
-                       if (imageHeight != null)
-                               labelText.append(" height='").append(imageHeight).append('\'');
-                       labelText.append(" src=\"").append(imageLocation).append("\"/>");
-
-               }
-
-               if (loggedInLabel != null && isLoggedIn()) {
-                       labelText.append(' ').append(loggedInLabel);
-               } else if (label != null) {
-                       labelText.append(' ').append(label);
-               }
-
-               if ((loggedInTarget != null && isLoggedIn()) || target != null)
-                       labelText.append("</a>");
-
-               link.setText(labelText.toString());
-
-               if (mouseListener != null)
-                       link.addMouseListener(mouseListener);
-
-               return comp;
-       }
-
-       private void registerImageIfNeeded() {
-               ResourceManager resourceManager = RWT.getResourceManager();
-               if (!resourceManager.isRegistered(image)) {
-                       URL res = getImageUrl();
-                       try (InputStream inputStream = res.openStream()) {
-                               resourceManager.register(image, inputStream);
-                               if (log.isTraceEnabled())
-                                       log.trace("Registered image " + image);
-                       } catch (IOException e) {
-                               throw new RuntimeException("Cannot load image " + image, e);
-                       }
-               }
-       }
-
-       private ImageData loadImage() {
-               URL url = getImageUrl();
-               ImageData result = null;
-               try (InputStream inputStream = url.openStream()) {
-                       result = new ImageData(inputStream);
-                       if (log.isTraceEnabled())
-                               log.trace("Loaded image " + image);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot load image " + image, e);
-               }
-               return result;
-       }
-
-       private URL getImageUrl() {
-               URL url;
-               try {
-                       // pure URL
-                       url = new URL(image);
-               } catch (MalformedURLException e1) {
-                       url = bundleContext.getBundle().getResource(image);
-               }
-
-               if (url == null)
-                       throw new IllegalStateException("No image " + image + " available.");
-
-               return url;
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-       public void setLabel(String label) {
-               this.label = label;
-       }
-
-       public void setStyle(String style) {
-               this.style = style;
-       }
-
-       /** @deprecated Use {@link #setStyle(String)} instead. */
-       @Deprecated
-       public void setCustom(String custom) {
-               this.style = custom;
-       }
-
-       public void setTarget(String target) {
-               this.target = target;
-               // try {
-               // new URL(target);
-               // isUrl = true;
-               // } catch (MalformedURLException e1) {
-               // isUrl = false;
-               // }
-       }
-
-       public void setImage(String image) {
-               this.image = image;
-       }
-
-       public void setLoggedInLabel(String loggedInLabel) {
-               this.loggedInLabel = loggedInLabel;
-       }
-
-       public void setLoggedInTarget(String loggedInTarget) {
-               this.loggedInTarget = loggedInTarget;
-       }
-
-       public void setMouseListener(MouseListener mouseListener) {
-               this.mouseListener = mouseListener;
-       }
-
-       public void setvAlign(String vAlign) {
-               if ("bottom".equals(vAlign)) {
-                       verticalAlignment = SWT.BOTTOM;
-               } else if ("top".equals(vAlign)) {
-                       verticalAlignment = SWT.TOP;
-               } else if ("center".equals(vAlign)) {
-                       verticalAlignment = SWT.CENTER;
-               } else {
-                       throw new IllegalArgumentException(
-                                       "Unsupported vertical alignment " + vAlign + " (must be: top, bottom or center)");
-               }
-       }
-
-       protected boolean isLoggedIn() {
-               return !CurrentUser.isAnonymous();
-       }
-
-       public void setImageWidth(Integer imageWidth) {
-               this.imageWidth = imageWidth;
-       }
-
-       public void setImageHeight(Integer imageHeight) {
-               this.imageHeight = imageHeight;
-       }
-
-       public void setOpenNew(boolean openNew) {
-               this.openNew = openNew;
-       }
-
-       protected String getDefaultStyle() {
-               return SimpleStyle.link.name();
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsPane.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsPane.java
deleted file mode 100644 (file)
index fc0c821..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Composite;
-
-/** The main pane of a CMS display, with QA and support areas. */
-public class CmsPane {
-
-       private Composite mainArea;
-       private Composite qaArea;
-       private Composite supportArea;
-
-       public CmsPane(Composite parent, int style) {
-               parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
-//             qaArea = new Composite(parent, SWT.NONE);
-//             qaArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-//             RowLayout qaLayout = new RowLayout();
-//             qaLayout.spacing = 0;
-//             qaArea.setLayout(qaLayout);
-
-               mainArea = new Composite(parent, SWT.NONE);
-               mainArea.setLayout(new GridLayout());
-               mainArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
-//             supportArea = new Composite(parent, SWT.NONE);
-//             supportArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-//             RowLayout supportLayout = new RowLayout();
-//             supportLayout.spacing = 0;
-//             supportArea.setLayout(supportLayout);
-       }
-
-       public Composite getMainArea() {
-               return mainArea;
-       }
-
-       public Composite getQaArea() {
-               return qaArea;
-       }
-
-       public Composite getSupportArea() {
-               return supportArea;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java
deleted file mode 100644 (file)
index 3522f1b..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.api.cms.ux.CmsView;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiConstants;
-import org.argeo.cms.ux.AbstractImageManager;
-import org.argeo.cms.ux.CmsUxUtils;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.service.ResourceManager;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.layout.RowData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Table;
-
-/** Static utilities for the CMS framework. */
-public class CmsUiUtils {
-       // private final static Log log = LogFactory.getLog(CmsUiUtils.class);
-
-       /*
-        * CMS VIEW
-        */
-
-       /**
-        * The CMS view related to this display, or null if none is available from this
-        * call.
-        * 
-        * @deprecated Use {@link CmsSwtUtils#getCmsView(Composite)} instead.
-        */
-       @Deprecated
-       public static CmsView getCmsView() {
-//             return UiContext.getData(CmsView.class.getName());
-               return CmsSwtUtils.getCmsView(Display.getCurrent().getActiveShell());
-       }
-
-       public static StringBuilder getServerBaseUrl(HttpServletRequest request) {
-               try {
-                       URL url = new URL(request.getRequestURL().toString());
-                       StringBuilder buf = new StringBuilder();
-                       buf.append(url.getProtocol()).append("://").append(url.getHost());
-                       if (url.getPort() != -1)
-                               buf.append(':').append(url.getPort());
-                       return buf;
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot extract server base URL from " + request.getRequestURL(), e);
-               }
-       }
-
-       //
-       public static String getDataUrl(Node node, HttpServletRequest request) {
-               try {
-                       StringBuilder buf = getServerBaseUrl(request);
-                       buf.append(getDataPath(node));
-                       return new URL(buf.toString()).toString();
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot build data URL for " + node, e);
-               }
-       }
-
-       /** A path in the node repository */
-       public static String getDataPath(Node node) {
-               return getDataPath(CmsConstants.EGO_REPOSITORY, node);
-       }
-
-       public static String getDataPath(String cn, Node node) {
-               return CmsJcrUtils.getDataPath(cn, node);
-       }
-
-       /** Clean reserved URL characters for use in HTTP links. */
-       public static String getDataPathForUrl(Node node) {
-               return CmsSwtUtils.cleanPathForUrl(getDataPath(node));
-       }
-
-       /** @deprecated Use rowData16px() instead. GridData should not be reused. */
-       @Deprecated
-       public static RowData ROW_DATA_16px = new RowData(16, 16);
-
-       
-
-       /*
-        * FORM LAYOUT
-        */
-
-       
-
-       @Deprecated
-       public static void setItemHeight(Table table, int height) {
-               table.setData(CmsUiConstants.ITEM_HEIGHT, height);
-       }
-
-       //
-       // JCR
-       //
-       public static Node getOrAddEmptyFile(Node parent, Enum<?> child) throws RepositoryException {
-               if (has(parent, child))
-                       return child(parent, child);
-               return JcrUtils.copyBytesAsFile(parent, child.name(), new byte[0]);
-       }
-
-       public static Node child(Node parent, Enum<?> en) throws RepositoryException {
-               return parent.getNode(en.name());
-       }
-
-       public static Boolean has(Node parent, Enum<?> en) throws RepositoryException {
-               return parent.hasNode(en.name());
-       }
-
-       public static Node getOrAdd(Node parent, Enum<?> en) throws RepositoryException {
-               return getOrAdd(parent, en, null);
-       }
-
-       public static Node getOrAdd(Node parent, Enum<?> en, String primaryType) throws RepositoryException {
-               if (has(parent, en))
-                       return child(parent, en);
-               else if (primaryType == null)
-                       return parent.addNode(en.name());
-               else
-                       return parent.addNode(en.name(), primaryType);
-       }
-
-       // IMAGES
-
-       public static String img(Node fileNode, String width, String height) {
-               return img(null, fileNode, width, height);
-       }
-
-       public static String img(String serverBase, Node fileNode, String width, String height) {
-//             String src = (serverBase != null ? serverBase : "") + NodeUtils.getDataPath(fileNode);
-               String src;
-               src = (serverBase != null ? serverBase : "") + getDataPathForUrl(fileNode);
-               return CmsUxUtils.imgBuilder(src, width, height).append("/>").toString();
-       }
-
-       public static String noImg(Cms2DSize size) {
-               ResourceManager rm = RWT.getResourceManager();
-               return CmsUxUtils.img(rm.getLocation(AbstractImageManager.NO_IMAGE), size);
-       }
-
-       public static String noImg() {
-               return noImg(AbstractImageManager.NO_IMAGE_SIZE);
-       }
-
-//     public static Image noImage(Cms2DSize size) {
-//             ResourceManager rm = RWT.getResourceManager();
-//             InputStream in = null;
-//             try {
-//                     in = rm.getRegisteredContent(AbstractImageManager.NO_IMAGE);
-//                     ImageData id = new ImageData(in);
-//                     ImageData scaled = id.scaledTo(size.getWidth(), size.getHeight());
-//                     Image image = new Image(Display.getCurrent(), scaled);
-//                     return image;
-//             } finally {
-//                     try {
-//                             in.close();
-//                     } catch (IOException e) {
-//                             // silent
-//                     }
-//             }
-//     }
-
-       /** Lorem ipsum text to be used during development. */
-       public final static String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
-                       + " Etiam eleifend hendrerit sem, ac ultricies massa ornare ac."
-                       + " Cras aliquam sodales risus, vitae varius lacus molestie quis."
-                       + " Vivamus consequat, leo id lacinia volutpat, eros diam efficitur urna, finibus interdum risus turpis at nisi."
-                       + " Curabitur vulputate nulla quis scelerisque fringilla. Integer consectetur turpis id lobortis accumsan."
-                       + " Pellentesque commodo turpis ac diam ultricies dignissim."
-                       + " Curabitur sit amet dolor volutpat lacus aliquam ornare quis sed velit."
-                       + " Integer varius quis est et tristique."
-                       + " Suspendisse pharetra porttitor purus, eget condimentum magna."
-                       + " Duis vitae turpis eros. Sed tincidunt lacinia rutrum."
-                       + " Aliquam velit velit, rutrum ut augue sed, condimentum lacinia augue.";
-
-       /** Singleton. */
-       private CmsUiUtils() {
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java
deleted file mode 100644 (file)
index b431fc3..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.argeo.cms.ui.util;
-
-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 java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.cms.swt.AbstractSwtImageManager;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.service.ResourceManager;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.widgets.Display;
-
-/** Manages only public images so far. */
-public class DefaultImageManager extends AbstractSwtImageManager<Node> {
-       private final static CmsLog log = CmsLog.getLog(DefaultImageManager.class);
-
-       /** @return null if not available */
-       @Override
-       public String getImageUrl(Node node) {
-               return CmsUiUtils.getDataPathForUrl(node);
-       }
-
-       protected String getResourceName(Node node) {
-               try {
-                       String workspace = node.getSession().getWorkspace().getName();
-                       if (node.hasNode(JCR_CONTENT))
-                               return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
-                       else
-                               return workspace + '_' + node.getIdentifier();
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-       public Binary getImageBinary(Node node) {
-               try {
-                       if (node.isNodeType(NT_FILE)) {
-                               return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
-                       } else {
-                               return null;
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-       public Image getSwtImage(Node node) {
-               InputStream inputStream = null;
-               Binary binary = getImageBinary(node);
-               if (binary == null)
-                       return null;
-               try {
-                       inputStream = binary.getStream();
-                       return new Image(Display.getCurrent(), inputStream);
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               } finally {
-                       IOUtils.closeQuietly(inputStream);
-                       JcrUtils.closeQuietly(binary);
-               }
-       }
-
-       @Override
-       public String uploadImage(Node context, Node parentNode, String fileName, InputStream in, String contentType) {
-               InputStream inputStream = null;
-               try {
-                       String previousResourceName = null;
-                       if (parentNode.hasNode(fileName)) {
-                               Node node = parentNode.getNode(fileName);
-                               previousResourceName = getResourceName(node);
-                               if (node.hasNode(JCR_CONTENT)) {
-                                       node.getNode(JCR_CONTENT).remove();
-                                       node.addNode(JCR_CONTENT, NT_RESOURCE);
-                               }
-                       }
-
-                       byte[] arr = IOUtils.toByteArray(in);
-                       Node fileNode = JcrUtils.copyBytesAsFile(parentNode, fileName, arr);
-                       inputStream = new ByteArrayInputStream(arr);
-                       ImageData id = new ImageData(inputStream);
-                       processNewImageFile(context, fileNode, id);
-
-                       String mime = contentType != null ? contentType : Files.probeContentType(Paths.get(fileName));
-                       if (mime != null) {
-                               fileNode.getNode(JCR_CONTENT).setProperty(Property.JCR_MIMETYPE, mime);
-                       }
-                       fileNode.getSession().save();
-
-                       // reset resource manager
-                       ResourceManager resourceManager = RWT.getResourceManager();
-                       if (previousResourceName != null && resourceManager.isRegistered(previousResourceName)) {
-                               resourceManager.unregister(previousResourceName);
-                               if (log.isDebugEnabled())
-                                       log.debug("Unregistered image " + previousResourceName);
-                       }
-                       return CmsUiUtils.getDataPath(fileNode);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot upload image " + fileName + " in " + parentNode, e);
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               } finally {
-                       IOUtils.closeQuietly(inputStream);
-               }
-       }
-
-       /** Does nothing by default. */
-       protected void processNewImageFile(Node context, Node fileNode, ImageData id)
-                       throws RepositoryException, IOException {
-       }
-
-       @Override
-       protected String noImg(Cms2DSize size) {
-               return CmsUiUtils.noImg(size);
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/MenuLink.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/MenuLink.java
deleted file mode 100644 (file)
index 284d2bd..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import org.argeo.cms.swt.CmsStyles;
-
-/**
- * Convenience class setting the custom style {@link CmsStyles#CMS_MENU_LINK} on
- * a {@link CmsLink} when simple menus are used.
- */
-public class MenuLink extends CmsLink {
-       public MenuLink() {
-               setCustom(CmsStyles.CMS_MENU_LINK);
-       }
-
-       public MenuLink(String label, String target, String custom) {
-               super(label, target, custom);
-       }
-
-       public MenuLink(String label, String target) {
-               super(label, target, CmsStyles.CMS_MENU_LINK);
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleCmsHeader.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleCmsHeader.java
deleted file mode 100644 (file)
index ab6a29f..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.swt.CmsStyles;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** A header in three parts */
-public class SimpleCmsHeader implements CmsUiProvider {
-       private List<CmsUiProvider> lead = new ArrayList<CmsUiProvider>();
-       private List<CmsUiProvider> center = new ArrayList<CmsUiProvider>();
-       private List<CmsUiProvider> end = new ArrayList<CmsUiProvider>();
-
-       private Boolean subPartsSameWidth = false;
-
-       @Override
-       public Control createUi(Composite parent, Node context) throws RepositoryException {
-               Composite header = new Composite(parent, SWT.NONE);
-               header.setData(RWT.CUSTOM_VARIANT, CmsStyles.CMS_HEADER);
-               header.setBackgroundMode(SWT.INHERIT_DEFAULT);
-               header.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(3, false)));
-
-               configurePart(context, header, lead);
-               configurePart(context, header, center);
-               configurePart(context, header, end);
-               return header;
-       }
-
-       protected void configurePart(Node context, Composite parent, List<CmsUiProvider> partProviders)
-                       throws RepositoryException {
-               final int style;
-               final String custom;
-               if (lead == partProviders) {
-                       style = SWT.LEAD;
-                       custom = CmsStyles.CMS_HEADER_LEAD;
-               } else if (center == partProviders) {
-                       style = SWT.CENTER;
-                       custom = CmsStyles.CMS_HEADER_CENTER;
-               } else if (end == partProviders) {
-                       style = SWT.END;
-                       custom = CmsStyles.CMS_HEADER_END;
-               } else {
-                       throw new CmsException("Unsupported part providers " + partProviders);
-               }
-
-               Composite part = new Composite(parent, SWT.NONE);
-               part.setData(RWT.CUSTOM_VARIANT, custom);
-               GridData gridData = new GridData(style, SWT.FILL, true, true);
-               part.setLayoutData(gridData);
-               part.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(partProviders.size(), subPartsSameWidth)));
-               for (CmsUiProvider uiProvider : partProviders) {
-                       Control subPart = uiProvider.createUi(part, context);
-                       subPart.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               }
-       }
-
-       public void setLead(List<CmsUiProvider> lead) {
-               this.lead = lead;
-       }
-
-       public void setCenter(List<CmsUiProvider> center) {
-               this.center = center;
-       }
-
-       public void setEnd(List<CmsUiProvider> end) {
-               this.end = end;
-       }
-
-       public void setSubPartsSameWidth(Boolean subPartsSameWidth) {
-               this.subPartsSameWidth = subPartsSameWidth;
-       }
-
-       public List<CmsUiProvider> getLead() {
-               return lead;
-       }
-
-       public List<CmsUiProvider> getCenter() {
-               return center;
-       }
-
-       public List<CmsUiProvider> getEnd() {
-               return end;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleDynamicPages.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleDynamicPages.java
deleted file mode 100644 (file)
index c61a2fc..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-
-public class SimpleDynamicPages implements CmsUiProvider {
-
-       @Override
-       public Control createUi(Composite parent, Node context)
-                       throws RepositoryException {
-               if (context == null)
-                       throw new CmsException("Context cannot be null");
-               parent.setLayout(new GridLayout(2, false));
-
-               // parent
-               if (!context.getPath().equals("/")) {
-                       new CmsLink("..", context.getParent().getPath()).createUi(parent,
-                                       context);
-                       new Label(parent, SWT.NONE).setText(context.getParent()
-                                       .getPrimaryNodeType().getName());
-               }
-
-               // context
-               Label contextL = new Label(parent, SWT.NONE);
-               contextL.setData(RWT.MARKUP_ENABLED, true);
-               contextL.setText("<b>" + context.getName() + "</b>");
-               new Label(parent, SWT.NONE).setText(context.getPrimaryNodeType()
-                               .getName());
-
-               // children
-               // Label childrenL = new Label(parent, SWT.NONE);
-               // childrenL.setData(RWT.MARKUP_ENABLED, true);
-               // childrenL.setText("<i>Children:</i>");
-               // childrenL.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false,
-               // false, 2, 1));
-
-               for (NodeIterator nIt = context.getNodes(); nIt.hasNext();) {
-                       Node child = nIt.nextNode();
-                       new CmsLink(child.getName(), child.getPath()).createUi(parent,
-                                       context);
-
-                       new Label(parent, SWT.NONE).setText(child.getPrimaryNodeType()
-                                       .getName());
-               }
-
-               // properties
-               // Label propsL = new Label(parent, SWT.NONE);
-               // propsL.setData(RWT.MARKUP_ENABLED, true);
-               // propsL.setText("<i>Properties:</i>");
-               // propsL.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false,
-               // 2, 1));
-               for (PropertyIterator pIt = context.getProperties(); pIt.hasNext();) {
-                       Property property = pIt.nextProperty();
-
-                       Label label = new Label(parent, SWT.NONE);
-                       label.setText(property.getName());
-                       label.setToolTipText(JcrUtils
-                                       .getPropertyDefinitionAsString(property));
-
-                       new Label(parent, SWT.NONE).setText(getPropAsString(property));
-               }
-
-               return null;
-       }
-
-       private String getPropAsString(Property property)
-                       throws RepositoryException {
-               String result = "";
-               DateFormat timeFormatter = new SimpleDateFormat("");
-               if (property.isMultiple()) {
-                       result = getMultiAsString(property, ", ");
-               } else {
-                       Value value = property.getValue();
-                       if (value.getType() == PropertyType.BINARY)
-                               result = "<binary>";
-                       else if (value.getType() == PropertyType.DATE)
-                               result = timeFormatter.format(value.getDate().getTime());
-                       else
-                               result = value.getString();
-               }
-               return result;
-       }
-
-       private String getMultiAsString(Property property, String separator)
-                       throws RepositoryException {
-               if (separator == null)
-                       separator = "; ";
-               Value[] values = property.getValues();
-               StringBuilder builder = new StringBuilder();
-               for (Value val : values) {
-                       String currStr = val.getString();
-                       if (!"".equals(currStr.trim()))
-                               builder.append(currStr).append(separator);
-               }
-               if (builder.lastIndexOf(separator) >= 0)
-                       return builder.substring(0, builder.length() - separator.length());
-               else
-                       return builder.toString();
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleStaticPage.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleStaticPage.java
deleted file mode 100644 (file)
index 63e504b..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsStyles;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-
-public class SimpleStaticPage implements CmsUiProvider {
-       private String text;
-
-       @Override
-       public Control createUi(Composite parent, Node context)
-                       throws RepositoryException {
-               Label textC = new Label(parent,  SWT.WRAP);
-               textC.setData(RWT.CUSTOM_VARIANT, CmsStyles.CMS_STATIC_TEXT);
-               textC.setData(RWT.MARKUP_ENABLED, Boolean.TRUE);
-               textC.setText(text);
-               
-               return textC;
-       }
-
-       public void setText(String text) {
-               this.text = text;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleStyle.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SimpleStyle.java
deleted file mode 100644 (file)
index b5fca26..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import org.argeo.api.cms.ux.CmsStyle;
-
-/** Simple styles used by the CMS UI utilities. */
-public enum SimpleStyle implements CmsStyle {
-       link;
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/StyleSheetResourceLoader.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/StyleSheetResourceLoader.java
deleted file mode 100644 (file)
index 1e17dc9..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.cms.swt.CmsException;
-import org.eclipse.rap.rwt.service.ResourceLoader;
-import org.osgi.framework.Bundle;
-
-/** {@link ResourceLoader} caching stylesheets. */
-public class StyleSheetResourceLoader implements ResourceLoader {
-       private Bundle themeBundle;
-       private Map<String, StyleSheet> stylesheets = new LinkedHashMap<String, StyleSheet>();
-
-       public StyleSheetResourceLoader(Bundle themeBundle) {
-               this.themeBundle = themeBundle;
-       }
-
-       @Override
-       public InputStream getResourceAsStream(String resourceName) throws IOException {
-               if (!stylesheets.containsKey(resourceName)) {
-                       // TODO deal with other bundles
-                       // Bundle bundle = bundleContext.getBundle();
-                       // String location =
-                       // bundle.getLocation().substring("initial@reference:".length());
-                       // if (location.startsWith("file:")) {
-                       // Path path = null;
-                       // try {
-                       // path = Paths.get(new URI(location));
-                       // } catch (URISyntaxException e) {
-                       // e.printStackTrace();
-                       // }
-                       // if (path != null) {
-                       // Path resourcePath = path.resolve(resourceName);
-                       // if (Files.exists(resourcePath))
-                       // return Files.newInputStream(resourcePath);
-                       // }
-                       // }
-
-                       URL res = themeBundle.getEntry(resourceName);
-                       if (res == null)
-                               throw new CmsException(
-                                               "Entry " + resourceName + " not found in bundle " + themeBundle.getSymbolicName());
-                       ByteArrayOutputStream out = new ByteArrayOutputStream();
-                       IOUtils.copy(res.openStream(), out);
-                       stylesheets.put(resourceName, new StyleSheet(out.toByteArray()));
-               }
-               return new ByteArrayInputStream(stylesheets.get(resourceName).getData());
-               // return res.openStream();
-       }
-
-       private class StyleSheet {
-               private byte[] data;
-
-               public StyleSheet(byte[] data) {
-                       super();
-                       this.data = data;
-               }
-
-               public byte[] getData() {
-                       return data;
-               }
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SystemNotifications.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/SystemNotifications.java
deleted file mode 100644 (file)
index 5a00781..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.swt.CmsStyles;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-/** Shell displaying system notifications such as exceptions */
-public class SystemNotifications extends Shell implements CmsStyles,
-               MouseListener {
-       private static final long serialVersionUID = -8129377525216022683L;
-
-       private Control source;
-
-       public SystemNotifications(Control source) {
-               super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
-               setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU);
-
-               this.source = source;
-
-               // TODO UI
-               // setLocation(source.toDisplay(source.getSize().x - getSize().x,
-               // source.getSize().y));
-               setLayout(new GridLayout());
-               addMouseListener(this);
-
-               addShellListener(new ShellAdapter() {
-                       private static final long serialVersionUID = 5178980294808435833L;
-
-                       @Override
-                       public void shellDeactivated(ShellEvent e) {
-                               close();
-                               dispose();
-                       }
-               });
-
-       }
-
-       public void notifyException(Throwable exception) {
-               Composite pane = this;
-
-               Label lbl = new Label(pane, SWT.NONE);
-               lbl.setText(exception.getLocalizedMessage()
-                               + (exception instanceof CmsException ? "" : "("
-                                               + exception.getClass().getName() + ")") + "\n");
-               lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-               lbl.addMouseListener(this);
-               if (exception.getCause() != null)
-                       appendCause(pane, exception.getCause());
-
-               StringBuilder mailToUrl = new StringBuilder("mailto:?");
-               try {
-                       mailToUrl.append("subject=").append(
-                                       URLEncoder.encode(
-                                                       "Exception "
-                                                                       + new SimpleDateFormat("yyyy-MM-dd hh:mm")
-                                                                                       .format(new Date()), "UTF-8")
-                                                       .replace("+", "%20"));
-
-                       StringWriter sw = new StringWriter();
-                       exception.printStackTrace(new PrintWriter(sw));
-                       IOUtils.closeQuietly(sw);
-
-                       // see
-                       // http://stackoverflow.com/questions/4737841/urlencoder-not-able-to-translate-space-character
-                       String encoded = URLEncoder.encode(sw.toString(), "UTF-8").replace(
-                                       "+", "%20");
-                       mailToUrl.append("&amp;body=").append(encoded);
-               } catch (UnsupportedEncodingException e) {
-                       mailToUrl.append("&amp;body=").append("Could not encode: ")
-                                       .append(e.getMessage());
-               }
-               Label mailTo = new Label(pane, SWT.NONE);
-               CmsSwtUtils.markup(mailTo);
-               mailTo.setText("<a href=\"" + mailToUrl + "\">Send details</a>");
-               mailTo.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
-
-               pack();
-               layout();
-
-               setLocation(source.toDisplay(source.getSize().x - getSize().x,
-                               source.getSize().y - getSize().y));
-               open();
-       }
-
-       private void appendCause(Composite parent, Throwable e) {
-               Label lbl = new Label(parent, SWT.NONE);
-               lbl.setText(" caused by: " + e.getLocalizedMessage() + " ("
-                               + e.getClass().getName() + ")" + "\n");
-               lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-               lbl.addMouseListener(this);
-               if (e.getCause() != null)
-                       appendCause(parent, e.getCause());
-       }
-
-       @Override
-       public void mouseDoubleClick(MouseEvent e) {
-       }
-
-       @Override
-       public void mouseDown(MouseEvent e) {
-               close();
-               dispose();
-       }
-
-       @Override
-       public void mouseUp(MouseEvent e) {
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenu.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenu.java
deleted file mode 100644 (file)
index 09aeff6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import javax.jcr.Node;
-
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.swt.auth.CmsLoginShell;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/** The site-related user menu */
-public class UserMenu extends CmsLoginShell {
-       private final Control source;
-       private final Node context;
-
-       public UserMenu(Control source, Node context) {
-               // FIXME pass CMS context
-               super(CmsUiUtils.getCmsView(), null);
-               this.context = context;
-               createUi();
-               if (source == null)
-                       throw new CmsException("Source control cannot be null.");
-               this.source = source;
-               open();
-       }
-
-       @Override
-       protected Shell createShell() {
-               return new Shell(Display.getCurrent(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
-       }
-
-       @Override
-       public void open() {
-               Shell shell = getShell();
-               shell.pack();
-               shell.layout();
-               shell.setLocation(source.toDisplay(source.getSize().x - shell.getSize().x, source.getSize().y));
-               shell.addShellListener(new ShellAdapter() {
-                       private static final long serialVersionUID = 5178980294808435833L;
-
-                       @Override
-                       public void shellDeactivated(ShellEvent e) {
-                               closeShell();
-                       }
-               });
-               super.open();
-       }
-
-       protected Node getContext() {
-               return context;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenuLink.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenuLink.java
deleted file mode 100644 (file)
index 317a7b5..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import javax.jcr.Node;
-
-import org.argeo.cms.CmsMsg;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.swt.CmsStyles;
-import org.argeo.cms.swt.auth.CmsLoginShell;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-
-/** Open the user menu when clicked */
-public class UserMenuLink extends MenuLink {
-
-       public UserMenuLink() {
-               setCustom(CmsStyles.CMS_USER_MENU_LINK);
-       }
-
-       @Override
-       public Control createUi(Composite parent, Node context) {
-               if (CurrentUser.isAnonymous())
-                       setLabel(CmsMsg.login.lead());
-               else {
-                       setLabel(CurrentUser.getDisplayName());
-               }
-               Label link = (Label) ((Composite) super.createUi(parent, context)).getChildren()[0];
-               link.addMouseListener(new UserMenuLinkController(context));
-               return link.getParent();
-       }
-
-       protected CmsLoginShell createUserMenu(Control source, Node context) {
-               return new UserMenu(source.getParent(), context);
-       }
-
-       private class UserMenuLinkController implements MouseListener, DisposeListener {
-               private static final long serialVersionUID = 3634864186295639792L;
-
-               private CmsLoginShell userMenu = null;
-               private long lastDisposeTS = 0l;
-
-               private final Node context;
-
-               public UserMenuLinkController(Node context) {
-                       this.context = context;
-               }
-
-               //
-               // MOUSE LISTENER
-               //
-               @Override
-               public void mouseDown(MouseEvent e) {
-                       if (e.button == 1) {
-                               Control source = (Control) e.getSource();
-                               if (userMenu == null) {
-                                       long durationSinceLastDispose = System.currentTimeMillis() - lastDisposeTS;
-                                       // avoid to reopen the menu, if one has clicked gain
-                                       if (durationSinceLastDispose > 200) {
-                                               userMenu = createUserMenu(source, context);
-                                               userMenu.getShell().addDisposeListener(this);
-                                       }
-                               }
-                       }
-               }
-
-               @Override
-               public void mouseDoubleClick(MouseEvent e) {
-               }
-
-               @Override
-               public void mouseUp(MouseEvent e) {
-               }
-
-               @Override
-               public void widgetDisposed(DisposeEvent event) {
-                       userMenu = null;
-                       lastDisposeTS = System.currentTimeMillis();
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/VerticalMenu.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/VerticalMenu.java
deleted file mode 100644 (file)
index 7f846c9..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.argeo.cms.ui.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-public class VerticalMenu implements CmsUiProvider {
-       private List<CmsUiProvider> items = new ArrayList<CmsUiProvider>();
-
-       @Override
-       public Control createUi(Composite parent, Node context) throws RepositoryException {
-               Composite part = new Composite(parent, SWT.NONE);
-               part.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false));
-//             part.setData(RWT.CUSTOM_VARIANT, custom);
-               part.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               for (CmsUiProvider uiProvider : items) {
-                       Control subPart = uiProvider.createUi(part, context);
-                       subPart.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false));
-               }
-               return part;
-       }
-
-       public void add(CmsUiProvider uiProvider) {
-               items.add(uiProvider);
-       }
-
-       public List<CmsUiProvider> getItems() {
-               return items;
-       }
-
-       public void setItems(List<CmsUiProvider> items) {
-               this.items = items;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/package-info.java
deleted file mode 100644 (file)
index 566df88..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Argeo CMS UI utilities. */
-package org.argeo.cms.ui.util;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java
deleted file mode 100644 (file)
index e23846e..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-package org.argeo.cms.ui.viewers;
-
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Observable;
-import java.util.Observer;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.ux.CmsEditable;
-import org.argeo.cms.swt.SwtEditablePart;
-import org.argeo.cms.swt.widgets.ScrolledPage;
-import org.argeo.jcr.JcrException;
-import org.eclipse.jface.viewers.ContentViewer;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Widget;
-import org.xml.sax.SAXParseException;
-
-/** Base class for viewers related to a page */
-public abstract class AbstractPageViewer extends ContentViewer implements Observer {
-       private static final long serialVersionUID = 5438688173410341485L;
-
-       private final static CmsLog log = CmsLog.getLog(AbstractPageViewer.class);
-
-       private final boolean readOnly;
-       /** The basis for the layouts, typically a ScrolledPage. */
-       private final Composite page;
-       private final CmsEditable cmsEditable;
-
-       private MouseListener mouseListener;
-       private FocusListener focusListener;
-
-       private SwtEditablePart edited;
-       private ISelection selection = StructuredSelection.EMPTY;
-
-       private AccessControlContext accessControlContext;
-
-       protected AbstractPageViewer(Section parent, int style, CmsEditable cmsEditable) {
-               // read only at UI level
-               readOnly = SWT.READ_ONLY == (style & SWT.READ_ONLY);
-
-               this.cmsEditable = cmsEditable == null ? CmsEditable.NON_EDITABLE : cmsEditable;
-               if (this.cmsEditable instanceof Observable)
-                       ((Observable) this.cmsEditable).addObserver(this);
-
-               if (cmsEditable.canEdit()) {
-                       mouseListener = createMouseListener();
-                       focusListener = createFocusListener();
-               }
-               page = findPage(parent);
-               accessControlContext = AccessController.getContext();
-       }
-
-       /**
-        * Can be called to simplify the called to isModelInitialized() and initModel()
-        */
-       protected void initModelIfNeeded(Node node) {
-               try {
-                       if (!isModelInitialized(node))
-                               if (getCmsEditable().canEdit()) {
-                                       initModel(node);
-                                       node.getSession().save();
-                               }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot initialize model", e);
-               }
-       }
-
-       /** Called if user can edit and model is not initialized */
-       protected Boolean isModelInitialized(Node node) throws RepositoryException {
-               return true;
-       }
-
-       /** Called if user can edit and model is not initialized */
-       protected void initModel(Node node) throws RepositoryException {
-       }
-
-       /** Create (retrieve) the MouseListener to use. */
-       protected MouseListener createMouseListener() {
-               return new MouseAdapter() {
-                       private static final long serialVersionUID = 1L;
-               };
-       }
-
-       /** Create (retrieve) the FocusListener to use. */
-       protected FocusListener createFocusListener() {
-               return new FocusListener() {
-                       private static final long serialVersionUID = 1L;
-
-                       @Override
-                       public void focusLost(FocusEvent event) {
-                       }
-
-                       @Override
-                       public void focusGained(FocusEvent event) {
-                       }
-               };
-       }
-
-       protected Composite findPage(Composite composite) {
-               if (composite instanceof ScrolledPage) {
-                       return (ScrolledPage) composite;
-               } else {
-                       if (composite.getParent() == null)
-                               return composite;
-                       return findPage(composite.getParent());
-               }
-       }
-
-       public void layoutPage() {
-               if (page != null)
-                       page.layout(true, true);
-       }
-
-       protected void showControl(Control control) {
-               if (page != null && (page instanceof ScrolledPage))
-                       ((ScrolledPage) page).showControl(control);
-       }
-
-       @Override
-       public void update(Observable o, Object arg) {
-               if (o == cmsEditable)
-                       editingStateChanged(cmsEditable);
-       }
-
-       /** To be overridden in order to provide the actual refresh */
-       protected void refresh(Control control) throws RepositoryException {
-       }
-
-       /** To be overridden.Save the edited part. */
-       protected void save(SwtEditablePart part) throws RepositoryException {
-       }
-
-       /** Prepare the edited part */
-       protected void prepare(SwtEditablePart part, Object caretPosition) {
-       }
-
-       /** Notified when the editing state changed. Does nothing, to be overridden */
-       protected void editingStateChanged(CmsEditable cmsEditable) {
-       }
-
-       @Override
-       public void refresh() {
-               // TODO check actual context in order to notice a discrepancy
-               Subject viewerSubject = getViewerSubject();
-               Subject.doAs(viewerSubject, (PrivilegedAction<Void>) () -> {
-                       try {
-                               if (cmsEditable.canEdit() && !readOnly)
-                                       mouseListener = createMouseListener();
-                               else
-                                       mouseListener = null;
-                               refresh(getControl());
-                               // layout(getControl());
-                               if (!getControl().isDisposed())
-                                       layoutPage();
-                       } catch (RepositoryException e) {
-                               throw new JcrException("Cannot refresh", e);
-                       }
-                       return null;
-               });
-       }
-
-       @Override
-       public void setSelection(ISelection selection, boolean reveal) {
-               this.selection = selection;
-       }
-
-       protected void updateContent(SwtEditablePart part) throws RepositoryException {
-       }
-
-       // LOW LEVEL EDITION
-       protected void edit(SwtEditablePart part, Object caretPosition) {
-               try {
-                       if (edited == part)
-                               return;
-
-                       if (edited != null && edited != part) {
-                               SwtEditablePart previouslyEdited = edited;
-                               try {
-                                       stopEditing(true);
-                               } catch (Exception e) {
-                                       notifyEditionException(e);
-                                       edit(previouslyEdited, caretPosition);
-                                       return;
-                               }
-                       }
-
-                       part.startEditing();
-                       edited = part;
-                       updateContent(part);
-                       prepare(part, caretPosition);
-                       edited.getControl().addFocusListener(new FocusListener() {
-                               private static final long serialVersionUID = 6883521812717097017L;
-
-                               @Override
-                               public void focusLost(FocusEvent event) {
-                                       stopEditing(true);
-                               }
-
-                               @Override
-                               public void focusGained(FocusEvent event) {
-                               }
-                       });
-
-                       layout(part.getControl());
-                       showControl(part.getControl());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot edit " + part, e);
-               }
-       }
-
-       protected void stopEditing(Boolean save) {
-               if (edited instanceof Widget && ((Widget) edited).isDisposed()) {
-                       edited = null;
-                       return;
-               }
-
-               assert edited != null;
-               if (edited == null) {
-                       if (log.isTraceEnabled())
-                               log.warn("Told to stop editing while not editing anything");
-                       return;
-               }
-
-               try {
-                       if (save)
-                               save(edited);
-
-                       edited.stopEditing();
-                       SwtEditablePart editablePart = edited;
-                       Control control = ((SwtEditablePart) edited).getControl();
-                       edited = null;
-                       // TODO make edited state management more robust
-                       updateContent(editablePart);
-                       layout(control);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot stop editing", e);
-               } finally {
-                       edited = null;
-               }
-       }
-
-       // METHODS AVAILABLE TO EXTENDING CLASSES
-       protected void saveEdit() {
-               if (edited != null)
-                       stopEditing(true);
-       }
-
-       protected void cancelEdit() {
-               if (edited != null)
-                       stopEditing(false);
-       }
-
-       /** Layout this controls from the related base page. */
-       public void layout(Control... controls) {
-               page.layout(controls);
-       }
-
-       /**
-        * Find the first {@link SwtEditablePart} in the parents hierarchy of this control
-        */
-       protected SwtEditablePart findDataParent(Control parent) {
-               if (parent instanceof SwtEditablePart) {
-                       return (SwtEditablePart) parent;
-               }
-               if (parent.getParent() != null)
-                       return findDataParent(parent.getParent());
-               else
-                       throw new IllegalStateException("No data parent found");
-       }
-
-       // UTILITIES
-       /** Check whether the edited part is in a proper state */
-       protected void checkEdited() {
-               if (edited == null || (edited instanceof Widget) && ((Widget) edited).isDisposed())
-                       throw new IllegalStateException("Edited should not be null or disposed at this stage");
-       }
-
-       /** Persist all changes. */
-       protected void persistChanges(Session session) throws RepositoryException {
-               session.save();
-               session.refresh(false);
-               // TODO notify that changes have been persisted
-       }
-
-       /** Convenience method using a Node in order to save the underlying session. */
-       protected void persistChanges(Node anyNode) throws RepositoryException {
-               persistChanges(anyNode.getSession());
-       }
-
-       /** Notify edition exception */
-       protected void notifyEditionException(Throwable e) {
-               Throwable eToLog = e;
-               if (e instanceof IllegalArgumentException)
-                       if (e.getCause() instanceof SAXParseException)
-                               eToLog = e.getCause();
-               log.error(eToLog.getMessage(), eToLog);
-//             if (log.isTraceEnabled())
-//                     log.trace("Full stack of " + eToLog.getMessage(), e);
-               // TODO Light error notification popup
-       }
-
-       protected Subject getViewerSubject() {
-               Subject res = null;
-               if (accessControlContext != null) {
-                       res = Subject.getSubject(accessControlContext);
-               }
-               if (res == null)
-                       throw new IllegalStateException("No subject associated with this viewer");
-               return res;
-       }
-
-       // GETTERS / SETTERS
-       public boolean isReadOnly() {
-               return readOnly;
-       }
-
-       protected SwtEditablePart getEdited() {
-               return edited;
-       }
-
-       public MouseListener getMouseListener() {
-               return mouseListener;
-       }
-
-       public FocusListener getFocusListener() {
-               return focusListener;
-       }
-
-       public CmsEditable getCmsEditable() {
-               return cmsEditable;
-       }
-
-       @Override
-       public ISelection getSelection() {
-               return selection;
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/ItemPart.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/ItemPart.java
deleted file mode 100644 (file)
index 4ca45d1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.argeo.cms.ui.viewers;
-
-import javax.jcr.Item;
-import javax.jcr.RepositoryException;
-
-/** An editable part related to a JCR Item */
-public interface ItemPart<T extends Item> {
-       public Item getItem() throws RepositoryException;
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/JcrVersionCmsEditable.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/JcrVersionCmsEditable.java
deleted file mode 100644 (file)
index 298fbde..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.argeo.cms.ui.viewers;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.version.VersionManager;
-
-import org.argeo.api.cms.ux.CmsEditionEvent;
-import org.argeo.cms.ux.AbstractCmsEditable;
-import org.argeo.jcr.JcrException;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-
-/** Provides the CmsEditable semantic based on JCR versioning. */
-public class JcrVersionCmsEditable extends AbstractCmsEditable {
-       private final String nodePath;// cache
-       private final VersionManager versionManager;
-       private final Boolean canEdit;
-
-       public JcrVersionCmsEditable(Node node) throws RepositoryException {
-               this.nodePath = node.getPath();
-               if (node.getSession().hasPermission(node.getPath(), Session.ACTION_SET_PROPERTY)) {
-                       // was Session.ACTION_ADD_NODE
-                       canEdit = true;
-                       if (!node.isNodeType(NodeType.MIX_VERSIONABLE)) {
-                               node.addMixin(NodeType.MIX_VERSIONABLE);
-                               node.getSession().save();
-                       }
-                       versionManager = node.getSession().getWorkspace().getVersionManager();
-               } else {
-                       canEdit = false;
-                       versionManager = null;
-               }
-
-               // bind keys
-               if (canEdit) {
-                       Display display = Display.getCurrent();
-                       display.setData(RWT.ACTIVE_KEYS, new String[] { "CTRL+RETURN", "CTRL+E" });
-                       display.addFilter(SWT.KeyDown, new Listener() {
-                               private static final long serialVersionUID = -4378653870463187318L;
-
-                               public void handleEvent(Event e) {
-                                       boolean ctrlPressed = (e.stateMask & SWT.CTRL) != 0;
-                                       if (ctrlPressed && e.keyCode == '\r')
-                                               stopEditing();
-                                       else if (ctrlPressed && e.keyCode == 'E')
-                                               stopEditing();
-                               }
-                       });
-               }
-       }
-
-       @Override
-       public Boolean canEdit() {
-               return canEdit;
-       }
-
-       public Boolean isEditing() {
-               try {
-                       if (!canEdit())
-                               return false;
-                       return versionManager.isCheckedOut(nodePath);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check whether " + nodePath + " is editing", e);
-               }
-       }
-
-       @Override
-       public void startEditing() {
-               try {
-                       versionManager.checkout(nodePath);
-//                     setChanged();
-               } catch (RepositoryException e1) {
-                       throw new JcrException("Cannot publish " + nodePath, e1);
-               }
-               notifyListeners(new CmsEditionEvent(nodePath, CmsEditionEvent.START_EDITING, this));
-       }
-
-       @Override
-       public void stopEditing() {
-               try {
-                       versionManager.checkin(nodePath);
-//                     setChanged();
-               } catch (RepositoryException e1) {
-                       throw new JcrException("Cannot publish " + nodePath, e1);
-               }
-               notifyListeners(new CmsEditionEvent(nodePath, CmsEditionEvent.STOP_EDITING, this));
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/NodePart.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/NodePart.java
deleted file mode 100644 (file)
index b51d4fc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.cms.ui.viewers;
-
-import javax.jcr.Node;
-
-/** An editable part related to a node */
-public interface NodePart extends ItemPart<Node> {
-       public Node getNode();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/PropertyPart.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/PropertyPart.java
deleted file mode 100644 (file)
index 793079e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.cms.ui.viewers;
-
-import javax.jcr.Property;
-
-/** An editable part related to a JCR Property */
-public interface PropertyPart extends ItemPart<Property> {
-       public Property getProperty();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/Section.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/Section.java
deleted file mode 100644 (file)
index b27fa38..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-package org.argeo.cms.ui.viewers;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.SwtEditablePart;
-import org.argeo.cms.ui.widgets.JcrComposite;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** A structured UI related to a JCR context. */
-public class Section extends JcrComposite {
-       private static final long serialVersionUID = -5933796173755739207L;
-
-       private final Section parentSection;
-       private Composite sectionHeader;
-       private final Integer relativeDepth;
-
-       public Section(Composite parent, int style, Node node) {
-               this(parent, findSection(parent), style, node);
-       }
-
-       public Section(Section section, int style, Node node) {
-               this(section, section, style, node);
-       }
-
-       protected Section(Composite parent, Section parentSection, int style, Node node) {
-               super(parent, style, node);
-               try {
-                       this.parentSection = parentSection;
-                       if (parentSection != null) {
-                               relativeDepth = getNode().getDepth() - parentSection.getNode().getDepth();
-                       } else {
-                               relativeDepth = 0;
-                       }
-                       setLayout(CmsSwtUtils.noSpaceGridLayout());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Cannot create section from " + node, e);
-               }
-       }
-
-       public Map<String, Section> getSubSections() throws RepositoryException {
-               LinkedHashMap<String, Section> result = new LinkedHashMap<String, Section>();
-               for (Control child : getChildren()) {
-                       if (child instanceof Composite) {
-                               collectDirectSubSections((Composite) child, result);
-                       }
-               }
-               return Collections.unmodifiableMap(result);
-       }
-
-       private void collectDirectSubSections(Composite composite, LinkedHashMap<String, Section> subSections)
-                       throws RepositoryException {
-               if (composite == sectionHeader || composite instanceof SwtEditablePart)
-                       return;
-               if (composite instanceof Section) {
-                       Section section = (Section) composite;
-                       subSections.put(section.getNodeId(), section);
-                       return;
-               }
-
-               for (Control child : composite.getChildren())
-                       if (child instanceof Composite)
-                               collectDirectSubSections((Composite) child, subSections);
-       }
-
-       public Composite createHeader() {
-               return createHeader(this);
-       }
-
-       public Composite createHeader(Composite parent) {
-               if (sectionHeader != null)
-                       sectionHeader.dispose();
-
-               sectionHeader = new Composite(parent, SWT.NONE);
-               sectionHeader.setLayoutData(CmsSwtUtils.fillWidth());
-               sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               // sectionHeader.moveAbove(null);
-               // layout();
-               return sectionHeader;
-       }
-
-       public Composite getHeader() {
-               if (sectionHeader != null && sectionHeader.isDisposed())
-                       sectionHeader = null;
-               return sectionHeader;
-       }
-
-       // SECTION PARTS
-       public SectionPart getSectionPart(String partId) {
-               for (Control child : getChildren()) {
-                       if (child instanceof SectionPart) {
-                               SectionPart sectionPart = (SectionPart) child;
-                               if (sectionPart.getPartId().equals(partId))
-                                       return sectionPart;
-                       }
-               }
-               return null;
-       }
-
-       public SectionPart nextSectionPart(SectionPart sectionPart) {
-               Control[] children = getChildren();
-               for (int i = 0; i < children.length; i++) {
-                       if (sectionPart == children[i]) {
-                               for (int j = i + 1; j < children.length; j++) {
-                                       if (children[i + 1] instanceof SectionPart) {
-                                               return (SectionPart) children[i + 1];
-                                       }
-                               }
-
-//                             if (i + 1 < children.length) {
-//                                     Composite next = (Composite) children[i + 1];
-//                                     return (SectionPart) next;
-//                             } else {
-//                                     // next section
-//                             }
-                       }
-               }
-               return null;
-       }
-
-       public SectionPart previousSectionPart(SectionPart sectionPart) {
-               Control[] children = getChildren();
-               for (int i = 0; i < children.length; i++) {
-                       if (sectionPart == children[i])
-                               if (i != 0) {
-                                       Composite previous = (Composite) children[i - 1];
-                                       return (SectionPart) previous;
-                               } else {
-                                       // previous section
-                               }
-               }
-               return null;
-       }
-
-       @Override
-       public String toString() {
-               if (parentSection == null)
-                       return "Main section " + getNode();
-               return "Section " + getNode();
-       }
-
-       public Section getParentSection() {
-               return parentSection;
-       }
-
-       public Integer getRelativeDepth() {
-               return relativeDepth;
-       }
-
-       /** Recursively finds the related section in the parents (can be itself) */
-       public static Section findSection(Control control) {
-               if (control == null)
-                       return null;
-               if (control instanceof Section)
-                       return (Section) control;
-               else
-                       return findSection(control.getParent());
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/SectionPart.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/SectionPart.java
deleted file mode 100644 (file)
index 4278c83..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.argeo.cms.ui.viewers;
-
-import org.argeo.cms.swt.SwtEditablePart;
-
-/** An editable part dynamically related to a Section */
-public interface SectionPart extends SwtEditablePart, NodePart {
-       public String getPartId();
-
-       public Section getSection();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/package-info.java
deleted file mode 100644 (file)
index 2f07931..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Argeo CMS generic viewers, based on JFace. */
-package org.argeo.cms.ui.viewers;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/EditableImage.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/EditableImage.java
deleted file mode 100644 (file)
index 95d9e8e..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.argeo.cms.ui.widgets;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-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 CmsLog log = CmsLog.getLog(EditableImage.class);
-
-       private Cms2DSize preferredImageSize;
-       private Boolean loaded = false;
-
-       public EditableImage(Composite parent, int swtStyle) {
-               super(parent, swtStyle);
-       }
-
-       public EditableImage(Composite parent, int swtStyle, Cms2DSize preferredImageSize) {
-               super(parent, swtStyle);
-               this.preferredImageSize = preferredImageSize;
-       }
-
-       public EditableImage(Composite parent, int style, Node node, boolean cacheImmediately, Cms2DSize preferredImageSize)
-                       throws RepositoryException {
-               super(parent, style, node, cacheImmediately);
-               this.preferredImageSize = preferredImageSize;
-       }
-
-       @Override
-       protected void setContainerLayoutData(Composite composite) {
-               // composite.setLayoutData(fillWidth());
-       }
-
-       @Override
-       protected void setControlLayoutData(Control control) {
-               // control.setLayoutData(fillWidth());
-       }
-
-       /** To be overriden. */
-       protected String createImgTag() throws RepositoryException {
-               return CmsUiUtils
-                               .noImg(preferredImageSize != null ? preferredImageSize : new Cms2DSize(getSize().x, getSize().y));
-       }
-
-       protected Label createLabel(Composite box, String style) {
-               Label lbl = new Label(box, getStyle());
-               // lbl.setLayoutData(CmsUiUtils.fillWidth());
-               CmsSwtUtils.markup(lbl);
-               CmsSwtUtils.style(lbl, style);
-               if (mouseListener != null)
-                       lbl.addMouseListener(mouseListener);
-               load(lbl);
-               return lbl;
-       }
-
-       /** To be overriden. */
-       protected synchronized Boolean load(Control control) {
-               String imgTag;
-               try {
-                       imgTag = createImgTag();
-               } catch (Exception e) {
-                       // throw new CmsException("Cannot retrieve image", e);
-                       log.error("Cannot retrieve image", e);
-                       imgTag = CmsUiUtils.noImg(preferredImageSize);
-                       loaded = false;
-               }
-
-               if (imgTag == null) {
-                       loaded = false;
-                       imgTag = CmsUiUtils.noImg(preferredImageSize);
-               } else
-                       loaded = true;
-               if (control != null) {
-                       ((Label) control).setText(imgTag);
-                       control.setSize(preferredImageSize != null
-                                       ? new Point(preferredImageSize.getWidth(), preferredImageSize.getHeight())
-                                       : getSize());
-               } else {
-                       loaded = false;
-               }
-               getParent().layout();
-               return loaded;
-       }
-
-       public void setPreferredSize(Cms2DSize size) {
-               this.preferredImageSize = size;
-               if (!loaded) {
-                       load((Label) getControl());
-               }
-       }
-
-       protected Text createText(Composite box, String style) {
-               Text text = new Text(box, getStyle());
-               CmsSwtUtils.style(text, style);
-               return text;
-       }
-
-       public Cms2DSize getPreferredImageSize() {
-               return preferredImageSize;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/EditableText.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/EditableText.java
deleted file mode 100644 (file)
index e3499ac..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-package org.argeo.cms.ui.widgets;
-
-import javax.jcr.Item;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** Editable text part displaying styled text. */
-public class EditableText extends StyledControl {
-       private static final long serialVersionUID = -6372283442330912755L;
-
-       private boolean editable = true;
-
-       private Color highlightColor;
-       private Composite highlight;
-
-       private boolean useTextAsLabel = false;
-
-       public EditableText(Composite parent, int style) {
-               super(parent, style);
-               editable = !(SWT.READ_ONLY == (style & SWT.READ_ONLY));
-               highlightColor = parent.getDisplay().getSystemColor(SWT.COLOR_GRAY);
-       }
-
-       public EditableText(Composite parent, int style, Item item) throws RepositoryException {
-               this(parent, style, item, false);
-       }
-
-       public EditableText(Composite parent, int style, Item item, boolean cacheImmediately) throws RepositoryException {
-               super(parent, style, item, cacheImmediately);
-               editable = !(SWT.READ_ONLY == (style & SWT.READ_ONLY));
-               highlightColor = parent.getDisplay().getSystemColor(SWT.COLOR_GRAY);
-       }
-
-       @Override
-       protected Control createControl(Composite box, String style) {
-               if (isEditing() && getEditable()) {
-                       return createText(box, style, true);
-               } else {
-                       if (useTextAsLabel) {
-                               return createTextLabel(box, style);
-                       } else {
-                               return createLabel(box, style);
-                       }
-               }
-       }
-
-       protected Label createLabel(Composite box, String style) {
-               Label lbl = new Label(box, getStyle() | SWT.WRAP);
-               lbl.setLayoutData(CmsSwtUtils.fillWidth());
-               if (style != null)
-                       CmsSwtUtils.style(lbl, style);
-               CmsSwtUtils.markup(lbl);
-               if (mouseListener != null)
-                       lbl.addMouseListener(mouseListener);
-               return lbl;
-       }
-
-       protected Text createTextLabel(Composite box, String style) {
-               Text lbl = new Text(box, getStyle() | SWT.MULTI);
-               lbl.setEditable(false);
-               lbl.setLayoutData(CmsSwtUtils.fillWidth());
-               if (style != null)
-                       CmsSwtUtils.style(lbl, style);
-               CmsSwtUtils.markup(lbl);
-               if (mouseListener != null)
-                       lbl.addMouseListener(mouseListener);
-               return lbl;
-       }
-
-       protected Text createText(Composite box, String style, boolean editable) {
-               highlight = new Composite(box, SWT.NONE);
-               highlight.setBackground(highlightColor);
-               GridData highlightGd = new GridData(SWT.FILL, SWT.FILL, false, false);
-               highlightGd.widthHint = 5;
-               highlightGd.heightHint = 3;
-               highlight.setLayoutData(highlightGd);
-
-               final Text text = new Text(box, getStyle() | SWT.MULTI | SWT.WRAP);
-               text.setEditable(editable);
-               GridData textLayoutData = CmsSwtUtils.fillWidth();
-               // textLayoutData.heightHint = preferredHeight;
-               text.setLayoutData(textLayoutData);
-               if (style != null)
-                       CmsSwtUtils.style(text, style);
-               text.setFocus();
-               return text;
-       }
-
-       @Override
-       protected void clear(boolean deep) {
-               if (highlight != null)
-                       highlight.dispose();
-               super.clear(deep);
-       }
-
-       public void setText(String text) {
-               Control child = getControl();
-               if (child instanceof Label)
-                       ((Label) child).setText(text);
-               else if (child instanceof Text)
-                       ((Text) child).setText(text);
-       }
-
-       public Text getAsText() {
-               return (Text) getControl();
-       }
-
-       public Label getAsLabel() {
-               return (Label) getControl();
-       }
-
-       public String getText() {
-               Control child = getControl();
-
-               if (child instanceof Label)
-                       return ((Label) child).getText();
-               else if (child instanceof Text)
-                       return ((Text) child).getText();
-               else
-                       throw new IllegalStateException("Unsupported control " + child.getClass());
-       }
-
-       /** @deprecated Use {@link #isEditable()} instead. */
-       @Deprecated
-       public boolean getEditable() {
-               return isEditable();
-       }
-
-       public boolean isEditable() {
-               return editable;
-       }
-
-       public void setUseTextAsLabel(boolean useTextAsLabel) {
-               this.useTextAsLabel = useTextAsLabel;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/Img.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/Img.java
deleted file mode 100644 (file)
index 41063fa..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-package org.argeo.cms.ui.widgets;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.api.cms.ux.CmsImageManager;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.internal.JcrFileUploadReceiver;
-import org.argeo.cms.ui.viewers.NodePart;
-import org.argeo.cms.ui.viewers.Section;
-import org.argeo.cms.ui.viewers.SectionPart;
-import org.argeo.jcr.Jcr;
-import org.argeo.jcr.JcrException;
-import org.eclipse.rap.fileupload.FileUploadHandler;
-import org.eclipse.rap.fileupload.FileUploadListener;
-import org.eclipse.rap.fileupload.FileUploadReceiver;
-import org.eclipse.rap.rwt.service.ServerPushSession;
-import org.eclipse.rap.rwt.widgets.FileUpload;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** An image within the Argeo Text framework */
-public class Img extends EditableImage implements SectionPart, NodePart {
-       private static final long serialVersionUID = 6233572783968188476L;
-
-       private final Section section;
-
-       private final CmsImageManager<Control, Node> imageManager;
-       private FileUploadHandler currentUploadHandler = null;
-       private FileUploadListener fileUploadListener;
-
-       public Img(Composite parent, int swtStyle, Node imgNode, Cms2DSize preferredImageSize) throws RepositoryException {
-               this(Section.findSection(parent), parent, swtStyle, imgNode, preferredImageSize, null);
-               setStyle(TextStyles.TEXT_IMAGE);
-       }
-
-       public Img(Composite parent, int swtStyle, Node imgNode) throws RepositoryException {
-               this(Section.findSection(parent), parent, swtStyle, imgNode, null, null);
-               setStyle(TextStyles.TEXT_IMAGE);
-       }
-
-       public Img(Composite parent, int swtStyle, Node imgNode, CmsImageManager<Control, Node> imageManager)
-                       throws RepositoryException {
-               this(Section.findSection(parent), parent, swtStyle, imgNode, null, imageManager);
-               setStyle(TextStyles.TEXT_IMAGE);
-       }
-
-       Img(Section section, Composite parent, int swtStyle, Node imgNode, Cms2DSize preferredImageSize,
-                       CmsImageManager<Control, Node> imageManager) throws RepositoryException {
-               super(parent, swtStyle, imgNode, false, preferredImageSize);
-               this.section = section;
-               this.imageManager = imageManager != null ? imageManager
-                               : (CmsImageManager<Control, Node>) CmsSwtUtils.getCmsView(section).getImageManager();
-               CmsSwtUtils.style(this, TextStyles.TEXT_IMG);
-       }
-
-       @Override
-       protected Control createControl(Composite box, String style) {
-               if (isEditing()) {
-                       try {
-                               return createImageChooser(box, style);
-                       } catch (RepositoryException e) {
-                               throw new JcrException("Cannot create image chooser", e);
-                       }
-               } else {
-                       return createLabel(box, style);
-               }
-       }
-
-       @Override
-       public synchronized void stopEditing() {
-               super.stopEditing();
-               fileUploadListener = null;
-       }
-
-       @Override
-       protected synchronized Boolean load(Control lbl) {
-               Node imgNode = getNode();
-               boolean loaded = imageManager.load(imgNode, lbl, getPreferredImageSize());
-               // getParent().layout();
-               return loaded;
-       }
-
-       protected Node getUploadFolder() {
-               return Jcr.getParent(getNode());
-       }
-
-       protected String getUploadName() {
-               Node node = getNode();
-               return Jcr.getName(node) + '[' + Jcr.getIndex(node) + ']';
-       }
-
-       protected CmsImageManager<Control, Node> getImageManager() {
-               return imageManager;
-       }
-
-       protected Control createImageChooser(Composite box, String style) throws RepositoryException {
-               JcrFileUploadReceiver receiver = new JcrFileUploadReceiver(this, getUploadFolder(), getUploadName(),
-                               imageManager);
-               if (currentUploadHandler != null)
-                       currentUploadHandler.dispose();
-               currentUploadHandler = prepareUpload(receiver);
-               final ServerPushSession pushSession = new ServerPushSession();
-               final FileUpload fileUpload = new FileUpload(box, SWT.NONE);
-               CmsSwtUtils.style(fileUpload, style);
-               fileUpload.addSelectionListener(new SelectionAdapter() {
-                       private static final long serialVersionUID = -9158471843941668562L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               pushSession.start();
-                               fileUpload.submit(currentUploadHandler.getUploadUrl());
-                       }
-               });
-               return fileUpload;
-       }
-
-       protected FileUploadHandler prepareUpload(FileUploadReceiver receiver) {
-               final FileUploadHandler uploadHandler = new FileUploadHandler(receiver);
-               if (fileUploadListener != null)
-                       uploadHandler.addUploadListener(fileUploadListener);
-               return uploadHandler;
-       }
-
-       @Override
-       public Section getSection() {
-               return section;
-       }
-
-       public void setFileUploadListener(FileUploadListener fileUploadListener) {
-               this.fileUploadListener = fileUploadListener;
-               if (currentUploadHandler != null)
-                       currentUploadHandler.addUploadListener(fileUploadListener);
-       }
-
-       @Override
-       public Node getItem() throws RepositoryException {
-               return getNode();
-       }
-
-       @Override
-       public String getPartId() {
-               return getNodeId();
-       }
-
-       @Override
-       public String toString() {
-               return "Img #" + getPartId();
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/JcrComposite.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/JcrComposite.java
deleted file mode 100644 (file)
index 6b54c0a..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-package org.argeo.cms.ui.widgets;
-
-import javax.jcr.Item;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.jcr.JcrException;
-import org.eclipse.swt.widgets.Composite;
-
-/** A composite which can (optionally) manage a JCR Item. */
-public class JcrComposite extends Composite {
-       private static final long serialVersionUID = -1447009015451153367L;
-
-       private Session session;
-
-       private String nodeId;
-       private String property = null;
-       private Node cache;
-
-       /** Regular composite constructor. No layout is set. */
-       public JcrComposite(Composite parent, int style) {
-               super(parent, style);
-               session = null;
-               nodeId = null;
-       }
-
-       public JcrComposite(Composite parent, int style, Item item) {
-               this(parent, style, item, false);
-       }
-
-       public JcrComposite(Composite parent, int style, Item item, boolean cacheImmediately) {
-               super(parent, style);
-               if (item != null)
-                       try {
-                               this.session = item.getSession();
-//                             if (!cacheImmediately && (SWT.READ_ONLY == (style & SWT.READ_ONLY))) {
-//                                     // (useless?) optimization: we only save a pointer to the session,
-//                                     // not even a reference to the item
-//                                     this.nodeId = null;
-//                             } else {
-                               Node node;
-                               Property property = null;
-                               if (item instanceof Node) {
-                                       node = (Node) item;
-                               } else {// Property
-                                       property = (Property) item;
-                                       if (property.isMultiple())// TODO manage property index
-                                               throw new UnsupportedOperationException("Multiple properties not supported yet.");
-                                       this.property = property.getName();
-                                       node = property.getParent();
-                               }
-                               this.nodeId = node.getIdentifier();
-                               if (cacheImmediately)
-                                       this.cache = node;
-//                             }
-                               setLayout(CmsSwtUtils.noSpaceGridLayout());
-                       } catch (RepositoryException e) {
-                               throw new IllegalStateException("Cannot create composite from " + item, e);
-                       }
-       }
-
-       public synchronized Node getNode() {
-               try {
-                       if (!itemIsNode())
-                               throw new IllegalStateException("Item is not a Node");
-                       return getNodeInternal();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get node " + nodeId, e);
-               }
-       }
-
-       private synchronized Node getNodeInternal() throws RepositoryException {
-               if (cache != null)
-                       return cache;
-               else if (session != null)
-                       if (nodeId != null)
-                               return session.getNodeByIdentifier(nodeId);
-                       else
-                               return null;
-               else
-                       return null;
-       }
-
-       public synchronized String getPropertyName() {
-               try {
-                       return getProperty().getName();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get property name", e);
-               }
-       }
-
-       public synchronized Node getPropertyNode() {
-               try {
-                       return getProperty().getNode();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get property name", e);
-               }
-       }
-
-       public synchronized Property getProperty() {
-               try {
-                       if (itemIsNode())
-                               throw new IllegalStateException("Item is not a Property");
-                       Node node = getNodeInternal();
-                       if (!node.hasProperty(property))
-                               throw new IllegalStateException("Property " + property + " is not set on " + node);
-                       return node.getProperty(property);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get property " + property + " from node " + nodeId, e);
-               }
-       }
-
-       public synchronized boolean itemIsNode() {
-               return property == null;
-       }
-
-       public synchronized boolean itemExists() {
-               if (session == null)
-                       return false;
-               try {
-                       Node n = session.getNodeByIdentifier(nodeId);
-                       if (!itemIsNode())
-                               return n.hasProperty(property);
-                       else
-                               return true;
-               } catch (ItemNotFoundException e) {
-                       return false;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check whether node exists", e);
-               }
-       }
-
-       /** Set/update the cache or change the node */
-       public synchronized void setNode(Node node) {
-               if (!itemIsNode())
-                       throw new IllegalArgumentException("Cannot set a Node on a Property");
-
-               if (node == null) {// clear cache
-                       this.cache = null;
-                       return;
-               }
-
-               try {
-//                     if (session != null || session != node.getSession())// check session
-//                             throw new IllegalArgumentException("Uncompatible session");
-//                     if (session == null)
-                       session = node.getSession();
-                       if (nodeId == null || !nodeId.equals(node.getIdentifier())) {
-                               nodeId = node.getIdentifier();
-                               cache = node;
-                               itemUpdated();
-                       } else {
-                               cache = node;// set/update cache
-                       }
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException(e);
-               }
-       }
-
-       /** Set/update the cache or change the property */
-       public synchronized void setProperty(Property prop) {
-               if (itemIsNode())
-                       throw new IllegalArgumentException("Cannot set a Property on a Node");
-
-               if (prop == null) {// clear cache
-                       this.cache = null;
-                       return;
-               }
-
-               try {
-                       if (session == null || session != prop.getSession())// check session
-                               throw new IllegalArgumentException("Uncompatible session");
-
-                       Node node = prop.getNode();
-                       if (nodeId == null || !nodeId.equals(node.getIdentifier()) || !property.equals(prop.getName())) {
-                               nodeId = node.getIdentifier();
-                               property = prop.getName();
-                               cache = node;
-                               itemUpdated();
-                       } else {
-                               cache = node;// set/update cache
-                       }
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException(e);
-               }
-       }
-
-       public synchronized String getNodeId() {
-               return nodeId;
-       }
-
-       /** Change the node, does nothing if same. */
-       public synchronized void setNodeId(String nodeId) throws RepositoryException {
-               if (this.nodeId != null && this.nodeId.equals(nodeId))
-                       return;
-               this.nodeId = nodeId;
-               if (cache != null)
-                       cache = session.getNodeByIdentifier(this.nodeId);
-               itemUpdated();
-       }
-
-       protected synchronized void itemUpdated() {
-               layout();
-       }
-
-//     public Session getSession() {
-//             return session;
-//     }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/StyledControl.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/StyledControl.java
deleted file mode 100644 (file)
index e3a5cb4..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-package org.argeo.cms.ui.widgets;
-
-import javax.jcr.Item;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiConstants;
-import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.MouseListener;
-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 CmsUiConstants {
-       private static final long serialVersionUID = -6372283442330912755L;
-       private Control control;
-
-       private Composite container;
-       private Composite box;
-
-       protected MouseListener mouseListener;
-       protected FocusListener focusListener;
-
-       private Boolean editing = Boolean.FALSE;
-
-       private Composite ancestorToLayout;
-
-       public StyledControl(Composite parent, int swtStyle) {
-               super(parent, swtStyle);
-               setLayout(CmsSwtUtils.noSpaceGridLayout());
-       }
-
-       public StyledControl(Composite parent, int style, Item item) {
-               super(parent, style, item);
-       }
-
-       public StyledControl(Composite parent, int style, Item item, boolean cacheImmediately) {
-               super(parent, style, item, cacheImmediately);
-       }
-
-       protected abstract Control createControl(Composite box, String style);
-
-       protected Composite createBox() {
-               Composite box = new Composite(container, SWT.INHERIT_DEFAULT);
-               setContainerLayoutData(box);
-               box.setLayout(CmsSwtUtils.noSpaceGridLayout(3));
-               return box;
-       }
-
-       protected Composite createContainer() {
-               Composite container = new Composite(this, SWT.INHERIT_DEFAULT);
-               setContainerLayoutData(container);
-               container.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               return container;
-       }
-
-       public Control getControl() {
-               return control;
-       }
-
-       protected synchronized Boolean isEditing() {
-               return editing;
-       }
-
-       public synchronized void startEditing() {
-               assert !isEditing();
-               editing = true;
-               // int height = control.getSize().y;
-               String style = (String) EclipseUiSpecificUtils.getStyleData(control);
-               clear(false);
-               refreshControl(style);
-
-               // add the focus listener to the newly created edition control
-               if (focusListener != null)
-                       control.addFocusListener(focusListener);
-       }
-
-       public synchronized void stopEditing() {
-               assert isEditing();
-               editing = false;
-               String style = (String) EclipseUiSpecificUtils.getStyleData(control);
-               clear(false);
-               refreshControl(style);
-       }
-
-       protected void refreshControl(String style) {
-               control = createControl(box, style);
-               setControlLayoutData(control);
-               if (ancestorToLayout != null)
-                       ancestorToLayout.layout(true, true);
-               else
-                       getParent().layout(true, true);
-       }
-
-       public void setStyle(String style) {
-               Object currentStyle = null;
-               if (control != null)
-                       currentStyle = EclipseUiSpecificUtils.getStyleData(control);
-               if (currentStyle != null && currentStyle.equals(style))
-                       return;
-
-               clear(true);
-               refreshControl(style);
-
-               if (style != null) {
-                       CmsSwtUtils.style(box, style + "_box");
-                       CmsSwtUtils.style(container, style + "_container");
-               }
-       }
-
-       /** To be overridden */
-       protected void setControlLayoutData(Control control) {
-               control.setLayoutData(CmsSwtUtils.fillWidth());
-       }
-
-       /** To be overridden */
-       protected void setContainerLayoutData(Composite composite) {
-               composite.setLayoutData(CmsSwtUtils.fillWidth());
-       }
-
-       protected void clear(boolean deep) {
-               if (deep) {
-                       for (Control control : getChildren())
-                               control.dispose();
-                       container = createContainer();
-                       box = createBox();
-               } else {
-                       control.dispose();
-               }
-       }
-
-       public void setMouseListener(MouseListener mouseListener) {
-               if (this.mouseListener != null && control != null)
-                       control.removeMouseListener(this.mouseListener);
-               this.mouseListener = mouseListener;
-               if (control != null && this.mouseListener != null)
-                       control.addMouseListener(mouseListener);
-       }
-
-       public void setFocusListener(FocusListener focusListener) {
-               if (this.focusListener != null && control != null)
-                       control.removeFocusListener(this.focusListener);
-               this.focusListener = focusListener;
-               if (control != null && this.focusListener != null)
-                       control.addFocusListener(focusListener);
-       }
-
-       public void setAncestorToLayout(Composite ancestorToLayout) {
-               this.ancestorToLayout = ancestorToLayout;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/TextStyles.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/TextStyles.java
deleted file mode 100644 (file)
index e461ed0..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.argeo.cms.ui.widgets;
-
-/** Styles references in the CSS. */
-public interface TextStyles {
-       /** The whole page area */
-       public final static String TEXT_AREA = "text_area";
-       /** Area providing controls for editing text */
-       public final static String TEXT_EDITOR_HEADER = "text_editor_header";
-       /** The styled composite for editing the text */
-       public final static String TEXT_STYLED_COMPOSITE = "text_styled_composite";
-       /** A section */
-       public final static String TEXT_SECTION = "text_section";
-       /** A paragraph */
-       public final static String TEXT_PARAGRAPH = "text_paragraph";
-       /** An image */
-       public final static String TEXT_IMG = "text_img";
-       /** The dialog to edit styled paragraph */
-       public final static String TEXT_STYLED_TOOLS_DIALOG = "text_styled_tools_dialog";
-
-       /*
-        * DEFAULT TEXT STYLES
-        */
-       /** Default style for text body */
-       public final static String TEXT_DEFAULT = "text_default";
-       /** Fixed-width, typically code */
-       public final static String TEXT_PRE = "text_pre";
-       /** Quote */
-       public final static String TEXT_QUOTE = "text_quote";
-       /** Title */
-       public final static String TEXT_TITLE = "text_title";
-       /** Header (to be dynamically completed with the depth, e.g. text_h1) */
-       public final static String TEXT_H = "text_h";
-
-       /** Default style for images */
-       public final static String TEXT_IMAGE = "text_image";
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/widgets/package-info.java
deleted file mode 100644 (file)
index 514f753..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Argeo CMS generic widgets, based on SWT. */
-package org.argeo.cms.ui.widgets;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java
deleted file mode 100644 (file)
index fdafa98..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.eclipse.ui.AbstractTreeContentProvider;
-import org.argeo.eclipse.ui.EclipseUiException;
-
-/** Canonical implementation of tree content provider manipulating JCR nodes. */
-public abstract class AbstractNodeContentProvider extends
-               AbstractTreeContentProvider {
-       private static final long serialVersionUID = -4905836490027272569L;
-
-       private final static CmsLog log = CmsLog
-                       .getLog(AbstractNodeContentProvider.class);
-
-       private Session session;
-
-       public AbstractNodeContentProvider(Session session) {
-               this.session = session;
-       }
-
-       /**
-        * Whether this path is a base path (and thus has no parent). By default it
-        * returns true if path is '/' (root node)
-        */
-       protected Boolean isBasePath(String path) {
-               // root node
-               return path.equals("/");
-       }
-
-       @Override
-       public Object[] getChildren(Object element) {
-               Object[] children;
-               if (element instanceof Node) {
-                       try {
-                               Node node = (Node) element;
-                               children = getChildren(node);
-                       } catch (RepositoryException e) {
-                               throw new EclipseUiException("Cannot get children of " + element, e);
-                       }
-               } else if (element instanceof WrappedNode) {
-                       WrappedNode wrappedNode = (WrappedNode) element;
-                       try {
-                               children = getChildren(wrappedNode.getNode());
-                       } catch (RepositoryException e) {
-                               throw new EclipseUiException("Cannot get children of "
-                                               + wrappedNode, e);
-                       }
-               } else if (element instanceof NodesWrapper) {
-                       NodesWrapper node = (NodesWrapper) element;
-                       children = node.getChildren();
-               } else {
-                       children = super.getChildren(element);
-               }
-
-               children = sort(element, children);
-               return children;
-       }
-
-       /** Do not sort by default. To be overidden to provide custom sort. */
-       protected Object[] sort(Object parent, Object[] children) {
-               return children;
-       }
-
-       /**
-        * To be overridden in order to filter out some nodes. Does nothing by
-        * default. The provided list is a temporary one and can thus be modified
-        * directly . (e.g. via an iterator)
-        */
-       protected List<Node> filterChildren(List<Node> children)
-                       throws RepositoryException {
-               return children;
-       }
-
-       protected Object[] getChildren(Node node) throws RepositoryException {
-               List<Node> nodes = new ArrayList<Node>();
-               for (NodeIterator nit = node.getNodes(); nit.hasNext();)
-                       nodes.add(nit.nextNode());
-               nodes = filterChildren(nodes);
-               return nodes.toArray();
-       }
-
-       @Override
-       public Object getParent(Object element) {
-               if (element instanceof Node) {
-                       Node node = (Node) element;
-                       try {
-                               String path = node.getPath();
-                               if (isBasePath(path))
-                                       return null;
-                               else
-                                       return node.getParent();
-                       } catch (RepositoryException e) {
-                               log.warn("Cannot get parent of " + element + ": " + e);
-                               return null;
-                       }
-               } else if (element instanceof WrappedNode) {
-                       WrappedNode wrappedNode = (WrappedNode) element;
-                       return wrappedNode.getParent();
-               } else if (element instanceof NodesWrapper) {
-                       NodesWrapper nodesWrapper = (NodesWrapper) element;
-                       return this.getParent(nodesWrapper.getNode());
-               }
-               return super.getParent(element);
-       }
-
-       @Override
-       public boolean hasChildren(Object element) {
-               try {
-                       if (element instanceof Node) {
-                               Node node = (Node) element;
-                               return node.hasNodes();
-                       } else if (element instanceof WrappedNode) {
-                               WrappedNode wrappedNode = (WrappedNode) element;
-                               return wrappedNode.getNode().hasNodes();
-                       } else if (element instanceof NodesWrapper) {
-                               NodesWrapper nodesWrapper = (NodesWrapper) element;
-                               return nodesWrapper.hasChildren();
-                       }
-
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot check whether " + element
-                                       + " has children", e);
-               }
-               return super.hasChildren(element);
-       }
-
-       public Session getSession() {
-               return session;
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java
deleted file mode 100644 (file)
index b880a63..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventIterator;
-import javax.jcr.observation.EventListener;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * {@link EventListener} which simplifies running actions within the UI thread.
- */
-public abstract class AsyncUiEventListener implements EventListener {
-       // private final static Log logSuper = LogFactory
-       // .getLog(AsyncUiEventListener.class);
-       private final CmsLog logThis = CmsLog.getLog(getClass());
-
-       private final Display display;
-
-       public AsyncUiEventListener(Display display) {
-               super();
-               this.display = display;
-       }
-
-       /** Called asynchronously in the UI thread. */
-       protected abstract void onEventInUiThread(List<Event> events) throws RepositoryException;
-
-       /**
-        * Whether these events should be processed in the UI or skipped with no UI
-        * job created.
-        */
-       protected Boolean willProcessInUiThread(List<Event> events) throws RepositoryException {
-               return true;
-       }
-
-       protected CmsLog getLog() {
-               return logThis;
-       }
-
-       public final void onEvent(final EventIterator eventIterator) {
-               final List<Event> events = new ArrayList<Event>();
-               while (eventIterator.hasNext())
-                       events.add(eventIterator.nextEvent());
-
-               if (logThis.isTraceEnabled())
-                       logThis.trace("Received " + events.size() + " events");
-
-               try {
-                       if (!willProcessInUiThread(events))
-                               return;
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot test skip events " + events, e);
-               }
-
-               // Job job = new Job("JCR Events") {
-               // protected IStatus run(IProgressMonitor monitor) {
-               // if (display.isDisposed()) {
-               // logSuper.warn("Display is disposed cannot update UI");
-               // return Status.CANCEL_STATUS;
-               // }
-
-               if (!display.isDisposed())
-                       display.asyncExec(new Runnable() {
-                               public void run() {
-                                       try {
-                                               onEventInUiThread(events);
-                                       } catch (RepositoryException e) {
-                                               throw new EclipseUiException("Cannot process events " + events, e);
-                                       }
-                               }
-                       });
-
-               // return Status.OK_STATUS;
-               // }
-               // };
-               // job.schedule();
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java
deleted file mode 100644 (file)
index 22ffeaf..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * Default label provider to manage node and corresponding UI objects. It
- * provides reasonable overwrite-able default for known JCR types.
- */
-public class DefaultNodeLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = 1216182332792151235L;
-
-       public String getText(Object element) {
-               try {
-                       if (element instanceof Node) {
-                               return getText((Node) element);
-                       } else if (element instanceof WrappedNode) {
-                               return getText(((WrappedNode) element).getNode());
-                       } else if (element instanceof NodesWrapper) {
-                               return getText(((NodesWrapper) element).getNode());
-                       }
-                       return super.getText(element);
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot get text for of " + element, e);
-               }
-       }
-
-       protected String getText(Node node) throws RepositoryException {
-               if (node.isNodeType(NodeType.MIX_TITLE)
-                               && node.hasProperty(Property.JCR_TITLE))
-                       return node.getProperty(Property.JCR_TITLE).getString();
-               else
-                       return node.getName();
-       }
-
-       @Override
-       public Image getImage(Object element) {
-               try {
-                       if (element instanceof Node) {
-                               return getImage((Node) element);
-                       } else if (element instanceof WrappedNode) {
-                               return getImage(((WrappedNode) element).getNode());
-                       } else if (element instanceof NodesWrapper) {
-                               return getImage(((NodesWrapper) element).getNode());
-                       }
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot retrieve image for " + element, e);
-               }
-               return super.getImage(element);
-       }
-
-       protected Image getImage(Node node) throws RepositoryException {
-               // FIXME who uses that?
-               return null;
-       }
-
-       @Override
-       public String getToolTipText(Object element) {
-               try {
-                       if (element instanceof Node) {
-                               return getToolTipText((Node) element);
-                       } else if (element instanceof WrappedNode) {
-                               return getToolTipText(((WrappedNode) element).getNode());
-                       } else if (element instanceof NodesWrapper) {
-                               return getToolTipText(((NodesWrapper) element).getNode());
-                       }
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot get tooltip for " + element, e);
-               }
-               return super.getToolTipText(element);
-       }
-
-       protected String getToolTipText(Node node) throws RepositoryException {
-               return null;
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/JcrUiUtils.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/JcrUiUtils.java
deleted file mode 100644 (file)
index 420154b..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import java.util.Calendar;
-
-import javax.jcr.Node;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator;
-import org.argeo.eclipse.ui.jcr.lists.RowViewerComparator;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.widgets.Table;
-
-/** Utility methods to simplify UI development using SWT (or RWT), jface  and JCR. */
-public class JcrUiUtils {
-
-       /**
-        * Centralizes management of updating property value. Among other to avoid
-        * infinite loop when the new value is the same as the ones that is already
-        * stored in JCR.
-        * 
-        * @return true if the value as changed
-        */
-       public static boolean setJcrProperty(Node node, String propName,
-                       int propertyType, Object value) {
-               try {
-                       switch (propertyType) {
-                       case PropertyType.STRING:
-                               if ("".equals((String) value)
-                                               && (!node.hasProperty(propName) || node
-                                                               .hasProperty(propName)
-                                                               && "".equals(node.getProperty(propName)
-                                                                               .getString())))
-                                       // workaround the fact that the Text widget value cannot be
-                                       // set to null
-                                       return false;
-                               else if (node.hasProperty(propName)
-                                               && node.getProperty(propName).getString()
-                                                               .equals((String) value))
-                                       // nothing changed yet
-                                       return false;
-                               else {
-                                       node.setProperty(propName, (String) value);
-                                       return true;
-                               }
-                       case PropertyType.BOOLEAN:
-                               if (node.hasProperty(propName)
-                                               && node.getProperty(propName).getBoolean() == (Boolean) value)
-                                       // nothing changed yet
-                                       return false;
-                               else {
-                                       node.setProperty(propName, (Boolean) value);
-                                       return true;
-                               }
-                       case PropertyType.DATE:
-                               if (node.hasProperty(propName)
-                                               && node.getProperty(propName).getDate()
-                                                               .equals((Calendar) value))
-                                       // nothing changed yet
-                                       return false;
-                               else {
-                                       node.setProperty(propName, (Calendar) value);
-                                       return true;
-                               }
-                       case PropertyType.LONG:
-                               Long lgValue = (Long) value;
-
-                               if (lgValue == null)
-                                       lgValue = 0L;
-
-                               if (node.hasProperty(propName)
-                                               && node.getProperty(propName).getLong() == lgValue)
-                                       // nothing changed yet
-                                       return false;
-                               else {
-                                       node.setProperty(propName, lgValue);
-                                       return true;
-                               }
-
-                       default:
-                               throw new EclipseUiException("Unimplemented property save");
-                       }
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unexpected error while setting property",
-                                       re);
-               }
-       }
-
-       /**
-        * Creates a new selection adapter in order to provide sorting abitily on a
-        * SWT Table that display a row list
-        **/
-       public static SelectionAdapter getRowSelectionAdapter(final int index,
-                       final int propertyType, final String selectorName,
-                       final String propertyName, final RowViewerComparator comparator,
-                       final TableViewer viewer) {
-               SelectionAdapter selectionAdapter = new SelectionAdapter() {
-                       private static final long serialVersionUID = -5738918304901437720L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               Table table = viewer.getTable();
-                               comparator.setColumn(propertyType, selectorName, propertyName);
-                               int dir = table.getSortDirection();
-                               if (table.getSortColumn() == table.getColumn(index)) {
-                                       dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
-                               } else {
-                                       dir = SWT.DOWN;
-                               }
-                               table.setSortDirection(dir);
-                               table.setSortColumn(table.getColumn(index));
-                               viewer.refresh();
-                       }
-               };
-               return selectionAdapter;
-       }
-
-       /**
-        * Creates a new selection adapter in order to provide sorting abitily on a
-        * swt table that display a row list
-        **/
-       public static SelectionAdapter getNodeSelectionAdapter(final int index,
-                       final int propertyType, final String propertyName,
-                       final NodeViewerComparator comparator, final TableViewer viewer) {
-               SelectionAdapter selectionAdapter = new SelectionAdapter() {
-                       private static final long serialVersionUID = -1683220869195484625L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               Table table = viewer.getTable();
-                               comparator.setColumn(propertyType, propertyName);
-                               int dir = table.getSortDirection();
-                               if (table.getSortColumn() == table.getColumn(index)) {
-                                       dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
-                               } else {
-                                       dir = SWT.DOWN;
-                               }
-                               table.setSortDirection(dir);
-                               table.setSortColumn(table.getColumn(index));
-                               viewer.refresh();
-                       }
-               };
-               return selectionAdapter;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeColumnLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeColumnLabelProvider.java
deleted file mode 100644 (file)
index 7e12bec..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-
-/** Simplifies writing JCR-based column label provider. */
-public class NodeColumnLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = -6586692836928505358L;
-
-       protected String getNodeText(Node node) throws RepositoryException {
-               return super.getText(node);
-       }
-
-       protected String getNodeToolTipText(Node node) throws RepositoryException {
-               return super.getToolTipText(node);
-       }
-
-       protected Image getNodeImage(Node node) throws RepositoryException {
-               return super.getImage(node);
-       }
-
-       protected Font getNodeFont(Node node) throws RepositoryException {
-               return super.getFont(node);
-       }
-
-       public Color getNodeBackground(Node node) throws RepositoryException {
-               return super.getBackground(node);
-       }
-
-       public Color getNodeForeground(Node node) throws RepositoryException {
-               return super.getForeground(node);
-       }
-
-       @Override
-       public String getText(Object element) {
-               try {
-                       if (element instanceof Node)
-                               return getNodeText((Node) element);
-                       else if (element instanceof NodeElement)
-                               return getNodeText(((NodeElement) element).getNode());
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Image getImage(Object element) {
-               try {
-                       if (element instanceof Node)
-                               return getNodeImage((Node) element);
-                       else if (element instanceof NodeElement)
-                               return getNodeImage(((NodeElement) element).getNode());
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public String getToolTipText(Object element) {
-               try {
-                       if (element instanceof Node)
-                               return getNodeToolTipText((Node) element);
-                       else if (element instanceof NodeElement)
-                               return getNodeToolTipText(((NodeElement) element).getNode());
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Font getFont(Object element) {
-               try {
-                       if (element instanceof Node)
-                               return getNodeFont((Node) element);
-                       else if (element instanceof NodeElement)
-                               return getNodeFont(((NodeElement) element).getNode());
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Color getBackground(Object element) {
-               try {
-                       if (element instanceof Node)
-                               return getNodeBackground((Node) element);
-                       else if (element instanceof NodeElement)
-                               return getNodeBackground(((NodeElement) element).getNode());
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Color getForeground(Object element) {
-               try {
-                       if (element instanceof Node)
-                               return getNodeForeground((Node) element);
-                       else if (element instanceof NodeElement)
-                               return getNodeForeground(((NodeElement) element).getNode());
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeElement.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeElement.java
deleted file mode 100644 (file)
index 787c92e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.Node;
-
-/** An element which is related to a JCR {@link Node}. */
-public interface NodeElement {
-       Node getNode();
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeElementComparer.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodeElementComparer.java
deleted file mode 100644 (file)
index 2f3d64d..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.argeo.eclipse.ui.jcr;\r
-\r
-import javax.jcr.Node;\r
-import javax.jcr.RepositoryException;\r
-\r
-import org.argeo.eclipse.ui.EclipseUiException;\r
-import org.eclipse.jface.viewers.IElementComparer;\r
-\r
-/** Element comparer for JCR node, to be used in JFace viewers. */\r
-public class NodeElementComparer implements IElementComparer {\r
-\r
-       public boolean equals(Object a, Object b) {\r
-               try {\r
-                       if ((a instanceof Node) && (b instanceof Node)) {\r
-                               Node nodeA = (Node) a;\r
-                               Node nodeB = (Node) b;\r
-                               return nodeA.getIdentifier().equals(nodeB.getIdentifier());\r
-                       } else {\r
-                               return a.equals(b);\r
-                       }\r
-               } catch (RepositoryException e) {\r
-                       throw new EclipseUiException("Cannot compare nodes", e);\r
-               }\r
-       }\r
-\r
-       public int hashCode(Object element) {\r
-               try {\r
-                       if (element instanceof Node)\r
-                               return ((Node) element).getIdentifier().hashCode();\r
-                       return element.hashCode();\r
-               } catch (RepositoryException e) {\r
-                       throw new EclipseUiException("Cannot get hash code", e);\r
-               }\r
-       }\r
-\r
-}\r
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodesWrapper.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/NodesWrapper.java
deleted file mode 100644 (file)
index 2f808a5..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-
-/**
- * Element of tree which is based on a node, but whose children are not
- * necessarily this node children.
- */
-public class NodesWrapper {
-       private final Node node;
-
-       public NodesWrapper(Node node) {
-               super();
-               this.node = node;
-       }
-
-       protected NodeIterator getNodeIterator() throws RepositoryException {
-               return node.getNodes();
-       }
-
-       protected List<WrappedNode> getWrappedNodes() throws RepositoryException {
-               List<WrappedNode> nodes = new ArrayList<WrappedNode>();
-               for (NodeIterator nit = getNodeIterator(); nit.hasNext();)
-                       nodes.add(new WrappedNode(this, nit.nextNode()));
-               return nodes;
-       }
-
-       public Object[] getChildren() {
-               try {
-                       return getWrappedNodes().toArray();
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot get wrapped children", e);
-               }
-       }
-
-       /**
-        * @return true by default because we don't want to compute the wrapped
-        *         nodes twice
-        */
-       public Boolean hasChildren() {
-               return true;
-       }
-
-       public Node getNode() {
-               return node;
-       }
-
-       @Override
-       public int hashCode() {
-               return node.hashCode();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (obj instanceof NodesWrapper)
-                       return node.equals(((NodesWrapper) obj).getNode());
-               else
-                       return false;
-       }
-
-       public String toString() {
-               return "nodes wrapper based on " + node;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/QueryTableContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/QueryTableContentProvider.java
deleted file mode 100644 (file)
index 934fa67..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.query.Query;
-
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/** Content provider based on a JCR {@link Query}. */
-public class QueryTableContentProvider implements IStructuredContentProvider {
-       private static final long serialVersionUID = 760371460907204722L;
-
-       @Override
-       public void dispose() {
-       }
-
-       @Override
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-       }
-
-       @Override
-       public Object[] getElements(Object inputElement) {
-               Query query = (Query) inputElement;
-               try {
-                       NodeIterator nit = query.execute().getNodes();
-                       return JcrUtils.nodeIteratorToList(nit).toArray();
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/RowColumnLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/RowColumnLabelProvider.java
deleted file mode 100644 (file)
index 70c71ef..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.query.Row;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-
-/** Simplifies writing JCR-based column label provider. */
-public class RowColumnLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = -6586692836928505358L;
-
-       protected String getRowText(Row row) throws RepositoryException {
-               return super.getText(row);
-       }
-
-       protected String getRowToolTipText(Row row) throws RepositoryException {
-               return super.getToolTipText(row);
-       }
-
-       protected Image getRowImage(Row row) throws RepositoryException {
-               return super.getImage(row);
-       }
-
-       protected Font getRowFont(Row row) throws RepositoryException {
-               return super.getFont(row);
-       }
-
-       public Color getRowBackground(Row row) throws RepositoryException {
-               return super.getBackground(row);
-       }
-
-       public Color getRowForeground(Row row) throws RepositoryException {
-               return super.getForeground(row);
-       }
-
-       @Override
-       public String getText(Object element) {
-               try {
-                       if (element instanceof Row)
-                               return getRowText((Row) element);
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Image getImage(Object element) {
-               try {
-                       if (element instanceof Row)
-                               return getRowImage((Row) element);
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public String getToolTipText(Object element) {
-               try {
-                       if (element instanceof Row)
-                               return getRowToolTipText((Row) element);
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Font getFont(Object element) {
-               try {
-                       if (element instanceof Row)
-                               return getRowFont((Row) element);
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Color getBackground(Object element) {
-               try {
-                       if (element instanceof Row)
-                               return getRowBackground((Row) element);
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Color getForeground(Object element) {
-               try {
-                       if (element instanceof Row)
-                               return getRowForeground((Row) element);
-                       else
-                               throw new IllegalArgumentException("Unsupported element type " + element.getClass());
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Repository exception when accessing " + element, e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/SimpleNodeContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/SimpleNodeContentProvider.java
deleted file mode 100644 (file)
index cb235d7..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.jcr.JcrUtils;
-
-/** Simple JCR node content provider taking a list of String as base path. */
-public class SimpleNodeContentProvider extends AbstractNodeContentProvider {
-       private static final long serialVersionUID = -8245193308831384269L;
-       private final List<String> basePaths;
-       private Boolean mkdirs = false;
-
-       public SimpleNodeContentProvider(Session session, String... basePaths) {
-               this(session, Arrays.asList(basePaths));
-       }
-
-       public SimpleNodeContentProvider(Session session, List<String> basePaths) {
-               super(session);
-               this.basePaths = basePaths;
-       }
-
-       @Override
-       protected Boolean isBasePath(String path) {
-               if (basePaths.contains(path))
-                       return true;
-               return super.isBasePath(path);
-       }
-
-       public Object[] getElements(Object inputElement) {
-               try {
-                       List<Node> baseNodes = new ArrayList<Node>();
-                       for (String basePath : basePaths)
-                               if (mkdirs && !getSession().itemExists(basePath))
-                                       baseNodes.add(JcrUtils.mkdirs(getSession(), basePath));
-                               else
-                                       baseNodes.add(getSession().getNode(basePath));
-                       return baseNodes.toArray();
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot get base nodes for " + basePaths,
-                                       e);
-               }
-       }
-
-       public List<String> getBasePaths() {
-               return basePaths;
-       }
-
-       public void setMkdirs(Boolean mkdirs) {
-               this.mkdirs = mkdirs;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/VersionColumnLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/VersionColumnLabelProvider.java
deleted file mode 100644 (file)
index 1ce3154..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.version.Version;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.graphics.Image;
-
-/** Simplifies writing JCR-based column label provider. */
-public class VersionColumnLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = -6117690082313161159L;
-
-       protected String getVersionText(Version version) throws RepositoryException {
-               return super.getText(version);
-       }
-
-       protected String getVersionToolTipText(Version version) throws RepositoryException {
-               return super.getToolTipText(version);
-       }
-
-       protected Image getVersionImage(Version version) throws RepositoryException {
-               return super.getImage(version);
-       }
-
-       protected String getUserName(Version version) throws RepositoryException {
-               Node node = version.getFrozenNode();
-               if(node.hasProperty(Property.JCR_LAST_MODIFIED_BY))
-                       return node.getProperty(Property.JCR_LAST_MODIFIED_BY).getString();
-               if(node.hasProperty(Property.JCR_CREATED_BY))
-                       return node.getProperty(Property.JCR_CREATED_BY).getString();
-               return null;
-       }
-       
-//     protected String getActivityTitle(Version version) throws RepositoryException {
-//             Node activity = getActivity(version);
-//             if (activity == null)
-//                     return null;
-//             if (activity.hasProperty("jcr:activityTitle"))
-//                     return activity.getProperty("jcr:activityTitle").getString();
-//             else
-//                     return activity.getName();
-//     }
-//
-//     protected Node getActivity(Version version) throws RepositoryException {
-//             if (version.hasProperty(Property.JCR_ACTIVITY)) {
-//                     return version.getProperty(Property.JCR_ACTIVITY).getNode();
-//             } else
-//                     return null;
-//     }
-
-       @Override
-       public String getText(Object element) {
-               try {
-                       return getVersionText((Version) element);
-               } catch (RepositoryException e) {
-                       throw new RuntimeException("Runtime repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public Image getImage(Object element) {
-               try {
-                       return getVersionImage((Version) element);
-               } catch (RepositoryException e) {
-                       throw new RuntimeException("Runtime repository exception when accessing " + element, e);
-               }
-       }
-
-       @Override
-       public String getToolTipText(Object element) {
-               try {
-                       return getVersionToolTipText((Version) element);
-               } catch (RepositoryException e) {
-                       throw new RuntimeException("Runtime repository exception when accessing " + element, e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/VersionHistoryContentProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/VersionHistoryContentProvider.java
deleted file mode 100644 (file)
index 32e5d30..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.version.VersionHistory;
-
-import org.argeo.jcr.Jcr;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/** Content provider based on a {@link VersionHistory}. */
-public class VersionHistoryContentProvider implements IStructuredContentProvider {
-       private static final long serialVersionUID = -4921107883428887012L;
-
-       @Override
-       public void dispose() {
-       }
-
-       @Override
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-       }
-
-       @Override
-       public Object[] getElements(Object inputElement) {
-               VersionHistory versionHistory = (VersionHistory) inputElement;
-               return Jcr.getLinearVersions(versionHistory).toArray();
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/WrappedNode.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/WrappedNode.java
deleted file mode 100644 (file)
index 43df1fe..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.argeo.eclipse.ui.jcr;
-
-import javax.jcr.Node;
-
-/** Wrap a node (created from a {@link NodesWrapper}) */
-public class WrappedNode {
-       private final NodesWrapper parent;
-       private final Node node;
-
-       public WrappedNode(NodesWrapper parent, Node node) {
-               super();
-               this.parent = parent;
-               this.node = node;
-       }
-
-       public NodesWrapper getParent() {
-               return parent;
-       }
-
-       public Node getNode() {
-               return node;
-       }
-
-       public String toString() {
-               return "wrapped " + node;
-       }
-
-       @Override
-       public int hashCode() {
-               return node.hashCode();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (obj instanceof WrappedNode)
-                       return node.equals(((WrappedNode) obj).getNode());
-               else
-                       return false;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/JcrColumnDefinition.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/JcrColumnDefinition.java
deleted file mode 100644 (file)
index c5dd733..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.argeo.eclipse.ui.jcr.lists;
-
-import javax.jcr.Node;
-import javax.jcr.query.Row;
-
-import org.argeo.eclipse.ui.ColumnDefinition;
-
-/**
- * Utility object to manage column in various tables and extracts displaying
- * data from JCR
- */
-public class JcrColumnDefinition extends ColumnDefinition {
-       private final static int DEFAULT_COLUMN_SIZE = 120;
-
-       private String selectorName;
-       private String propertyName;
-       private int propertyType;
-       private int columnSize;
-
-       /**
-        * Use this kind of columns to configure a table that displays JCR
-        * {@link Row}
-        * 
-        * @param selectorName
-        * @param propertyName
-        * @param propertyType
-        * @param headerLabel
-        */
-       public JcrColumnDefinition(String selectorName, String propertyName,
-                       int propertyType, String headerLabel) {
-               super(new SimpleJcrRowLabelProvider(selectorName, propertyName),
-                               headerLabel);
-               this.selectorName = selectorName;
-               this.propertyName = propertyName;
-               this.propertyType = propertyType;
-               this.columnSize = DEFAULT_COLUMN_SIZE;
-       }
-
-       /**
-        * Use this kind of columns to configure a table that displays JCR
-        * {@link Row}
-        * 
-        * @param selectorName
-        * @param propertyName
-        * @param propertyType
-        * @param headerLabel
-        * @param columnSize
-        */
-       public JcrColumnDefinition(String selectorName, String propertyName,
-                       int propertyType, String headerLabel, int columnSize) {
-               super(new SimpleJcrRowLabelProvider(selectorName, propertyName),
-                               headerLabel, columnSize);
-               this.selectorName = selectorName;
-               this.propertyName = propertyName;
-               this.propertyType = propertyType;
-               this.columnSize = columnSize;
-       }
-
-       /**
-        * Use this kind of columns to configure a table that displays JCR
-        * {@link Node}
-        * 
-        * @param propertyName
-        * @param propertyType
-        * @param headerLabel
-        * @param columnSize
-        */
-       public JcrColumnDefinition(String propertyName, int propertyType,
-                       String headerLabel, int columnSize) {
-               super(new SimpleJcrNodeLabelProvider(propertyName), headerLabel,
-                               columnSize);
-               this.propertyName = propertyName;
-               this.propertyType = propertyType;
-               this.columnSize = columnSize;
-       }
-
-       public String getSelectorName() {
-               return selectorName;
-       }
-
-       public void setSelectorName(String selectorName) {
-               this.selectorName = selectorName;
-       }
-
-       public String getPropertyName() {
-               return propertyName;
-       }
-
-       public void setPropertyName(String propertyName) {
-               this.propertyName = propertyName;
-       }
-
-       public int getPropertyType() {
-               return propertyType;
-       }
-
-       public void setPropertyType(int propertyType) {
-               this.propertyType = propertyType;
-       }
-
-       public int getColumnSize() {
-               return columnSize;
-       }
-
-       public void setColumnSize(int columnSize) {
-               this.columnSize = columnSize;
-       }
-
-       public String getHeaderLabel() {
-               return super.getLabel();
-       }
-
-       public void setHeaderLabel(String headerLabel) {
-               super.setLabel(headerLabel);
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/NodeViewerComparator.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/NodeViewerComparator.java
deleted file mode 100644 (file)
index d990460..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-package org.argeo.eclipse.ui.jcr.lists;
-
-import java.math.BigDecimal;
-import java.util.Calendar;
-
-import javax.jcr.Node;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.ValueFormatException;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerComparator;
-
-/**
- * Base comparator to enable ordering on Table or Tree viewer that display Jcr
- * Nodes.
- * 
- * Note that the following snippet must be added before setting the comparator
- * to the corresponding control: <code>
- * // IMPORTANT: initialize comparator before setting it
- * JcrColumnDefinition firstCol = colDefs.get(0);
- * comparator.setColumn(firstCol.getPropertyType(),
- * firstCol.getPropertyName());
- * viewer.setComparator(comparator); </code>
- */
-public class NodeViewerComparator extends ViewerComparator {
-       private static final long serialVersionUID = -7782916140737279027L;
-
-       protected String propertyName;
-
-       protected int propertyType;
-       public static final int ASCENDING = 0, DESCENDING = 1;
-       protected int direction = DESCENDING;
-
-       public NodeViewerComparator() {
-       }
-
-       /**
-        * e1 and e2 must both be Jcr nodes.
-        * 
-        * @param viewer
-        * @param e1
-        * @param e2
-        * @return the comparison
-        */
-       @Override
-       public int compare(Viewer viewer, Object e1, Object e2) {
-               int rc = 0;
-               long lc = 0;
-
-               try {
-                       Node n1 = (Node) e1;
-                       Node n2 = (Node) e2;
-
-                       Value v1 = null;
-                       Value v2 = null;
-                       if (n1.hasProperty(propertyName))
-                               v1 = n1.getProperty(propertyName).getValue();
-                       if (n2.hasProperty(propertyName))
-                               v2 = n2.getProperty(propertyName).getValue();
-
-                       if (v2 == null && v1 == null)
-                               return 0;
-                       else if (v2 == null)
-                               return -1;
-                       else if (v1 == null)
-                               return 1;
-
-                       switch (propertyType) {
-                       case PropertyType.STRING:
-                               rc = v1.getString().compareTo(v2.getString());
-                               break;
-                       case PropertyType.BOOLEAN:
-                               boolean b1 = v1.getBoolean();
-                               boolean b2 = v2.getBoolean();
-                               if (b1 == b2)
-                                       rc = 0;
-                               else
-                                       // we assume true is greater than false
-                                       rc = b1 ? 1 : -1;
-                               break;
-                       case PropertyType.DATE:
-                               Calendar c1 = v1.getDate();
-                               Calendar c2 = v2.getDate();
-                               if (c1 == null || c2 == null)
-                                       // log.trace("undefined date");
-                                       ;
-                               lc = c1.getTimeInMillis() - c2.getTimeInMillis();
-                               if (lc < Integer.MIN_VALUE)
-                                       rc = -1;
-                               else if (lc > Integer.MAX_VALUE)
-                                       rc = 1;
-                               else
-                                       rc = (int) lc;
-                               break;
-                       case PropertyType.LONG:
-                               long l1;
-                               long l2;
-                               // TODO Sometimes an empty string is set instead of a long
-                               try {
-                                       l1 = v1.getLong();
-                               } catch (ValueFormatException ve) {
-                                       l1 = 0;
-                               }
-                               try {
-                                       l2 = v2.getLong();
-                               } catch (ValueFormatException ve) {
-                                       l2 = 0;
-                               }
-
-                               lc = l1 - l2;
-                               if (lc < Integer.MIN_VALUE)
-                                       rc = -1;
-                               else if (lc > Integer.MAX_VALUE)
-                                       rc = 1;
-                               else
-                                       rc = (int) lc;
-                               break;
-                       case PropertyType.DECIMAL:
-                               BigDecimal bd1 = v1.getDecimal();
-                               BigDecimal bd2 = v2.getDecimal();
-                               rc = bd1.compareTo(bd2);
-                               break;
-                       case PropertyType.DOUBLE:
-                               Double d1 = v1.getDouble();
-                               Double d2 = v2.getDouble();
-                               rc = d1.compareTo(d2);
-                               break;
-                       default:
-                               throw new EclipseUiException(
-                                               "Unimplemented comparaison for PropertyType "
-                                                               + propertyType);
-                       }
-                       // If descending order, flip the direction
-                       if (direction == DESCENDING) {
-                               rc = -rc;
-                       }
-
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unexpected error "
-                                       + "while comparing nodes", re);
-               }
-               return rc;
-       }
-
-       /**
-        * @param propertyType
-        *            Corresponding JCR type
-        * @param propertyName
-        *            name of the property to use.
-        */
-       public void setColumn(int propertyType, String propertyName) {
-               if (this.propertyName != null && this.propertyName.equals(propertyName)) {
-                       // Same column as last sort; toggle the direction
-                       direction = 1 - direction;
-               } else {
-                       // New column; do an ascending sort
-                       this.propertyType = propertyType;
-                       this.propertyName = propertyName;
-                       direction = ASCENDING;
-               }
-       }
-
-       // Getters and setters
-       protected String getPropertyName() {
-               return propertyName;
-       }
-
-       protected void setPropertyName(String propertyName) {
-               this.propertyName = propertyName;
-       }
-
-       protected int getPropertyType() {
-               return propertyType;
-       }
-
-       protected void setPropertyType(int propertyType) {
-               this.propertyType = propertyType;
-       }
-
-       protected int getDirection() {
-               return direction;
-       }
-
-       protected void setDirection(int direction) {
-               this.direction = direction;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/RowViewerComparator.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/RowViewerComparator.java
deleted file mode 100644 (file)
index 60d637d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.argeo.eclipse.ui.jcr.lists;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.query.Row;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Base comparator to enable ordering on Table or Tree viewer that display Jcr
- * rows
- */
-public class RowViewerComparator extends NodeViewerComparator {
-       private static final long serialVersionUID = 7020939505172625113L;
-       protected String selectorName;
-
-       public RowViewerComparator() {
-       }
-
-       /**
-        * e1 and e2 must both be Jcr rows.
-        * 
-        * @param viewer
-        * @param e1
-        * @param e2
-        * @return the comparison
-        */
-       @Override
-       public int compare(Viewer viewer, Object e1, Object e2) {
-               try {
-                       Node n1 = ((Row) e1).getNode(selectorName);
-                       Node n2 = ((Row) e2).getNode(selectorName);
-                       return super.compare(viewer, n1, n2);
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unexpected error "
-                                       + "while comparing nodes", re);
-               }
-       }
-
-       /**
-        * @param propertyType
-        *            Corresponding JCR type
-        * @param propertyName
-        *            name of the property to use.
-        */
-       public void setColumn(int propertyType, String selectorName,
-                       String propertyName) {
-               if (this.selectorName != null && getPropertyName() != null
-                               && this.selectorName.equals(selectorName)
-                               && this.getPropertyName().equals(propertyName)) {
-                       // Same column as last sort; toggle the direction
-                       setDirection(1 - getDirection());
-               } else {
-                       // New column; do a descending sort
-                       setPropertyType(propertyType);
-                       setPropertyName(propertyName);
-                       this.selectorName = selectorName;
-                       setDirection(NodeViewerComparator.ASCENDING);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrNodeLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrNodeLabelProvider.java
deleted file mode 100644 (file)
index aa2e337..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-package org.argeo.eclipse.ui.jcr.lists;
-
-import java.text.DateFormat;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.text.SimpleDateFormat;
-
-import javax.jcr.Node;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-
-/** Base implementation of a label provider for controls that display JCR Nodes */
-public class SimpleJcrNodeLabelProvider extends ColumnLabelProvider {
-       private static final long serialVersionUID = -5215787695436221993L;
-
-       private final static String DEFAULT_DATE_FORMAT = "EEE, dd MMM yyyy";
-       private final static String DEFAULT_NUMBER_FORMAT = "#,##0.0";
-
-       private DateFormat dateFormat;
-       private NumberFormat numberFormat;
-
-       final private String propertyName;
-
-       /**
-        * Default Label provider for a given property of a node. Using default
-        * pattern for date and number formating
-        */
-       public SimpleJcrNodeLabelProvider(String propertyName) {
-               this.propertyName = propertyName;
-               dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
-               numberFormat = DecimalFormat.getInstance();
-               ((DecimalFormat) numberFormat).applyPattern(DEFAULT_NUMBER_FORMAT);
-       }
-
-       /**
-        * Label provider for a given property of a node optionally precising date
-        * and/or number format patterns
-        */
-       public SimpleJcrNodeLabelProvider(String propertyName,
-                       String dateFormatPattern, String numberFormatPattern) {
-               this.propertyName = propertyName;
-               dateFormat = new SimpleDateFormat(
-                               dateFormatPattern == null ? DEFAULT_DATE_FORMAT
-                                               : dateFormatPattern);
-               numberFormat = DecimalFormat.getInstance();
-               ((DecimalFormat) numberFormat)
-                               .applyPattern(numberFormatPattern == null ? DEFAULT_NUMBER_FORMAT
-                                               : numberFormatPattern);
-       }
-
-       @Override
-       public String getText(Object element) {
-               try {
-                       Node currNode = (Node) element;
-
-                       if (currNode.hasProperty(propertyName)) {
-                               if (currNode.getProperty(propertyName).isMultiple()) {
-                                       StringBuilder builder = new StringBuilder();
-                                       for (Value value : currNode.getProperty(propertyName)
-                                                       .getValues()) {
-                                               String currStr = getSingleValueAsString(value);
-                                               if (notEmptyString(currStr))
-                                                       builder.append(currStr).append("; ");
-                                       }
-                                       if (builder.length() > 0)
-                                               builder.deleteCharAt(builder.length() - 2);
-
-                                       return builder.toString();
-                               } else
-                                       return getSingleValueAsString(currNode.getProperty(
-                                                       propertyName).getValue());
-                       } else
-                               return "";
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unable to get text from row", re);
-               }
-       }
-
-       private String getSingleValueAsString(Value value)
-                       throws RepositoryException {
-               switch (value.getType()) {
-               case PropertyType.STRING:
-                       return value.getString();
-               case PropertyType.BOOLEAN:
-                       return "" + value.getBoolean();
-               case PropertyType.DATE:
-                       return dateFormat.format(value.getDate().getTime());
-               case PropertyType.LONG:
-                       return "" + value.getLong();
-               case PropertyType.DECIMAL:
-                       return numberFormat.format(value.getDecimal());
-               case PropertyType.DOUBLE:
-                       return numberFormat.format(value.getDouble());
-               case PropertyType.NAME:
-                       return value.getString();
-               default:
-                       throw new EclipseUiException("Unimplemented label provider "
-                                       + "for property type " + value.getType()
-                                       + " while getting property " + propertyName + " - value: "
-                                       + value.getString());
-
-               }
-       }
-
-       private boolean notEmptyString(String string) {
-               return string != null && !"".equals(string.trim());
-       }
-
-       public void setDateFormat(String dateFormatPattern) {
-               dateFormat = new SimpleDateFormat(dateFormatPattern);
-       }
-
-       public void setNumberFormat(String numberFormatPattern) {
-               ((DecimalFormat) numberFormat).applyPattern(numberFormatPattern);
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrRowLabelProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrRowLabelProvider.java
deleted file mode 100644 (file)
index 5d421f6..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.argeo.eclipse.ui.jcr.lists;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.query.Row;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-
-/**
- * Base implementation of a label provider for widgets that display JCR Rows.
- */
-public class SimpleJcrRowLabelProvider extends SimpleJcrNodeLabelProvider {
-       private static final long serialVersionUID = -3414654948197181740L;
-
-       final private String selectorName;
-
-       /**
-        * Default Label provider for a given property of a row. Using default
-        * pattern for date and number formating
-        */
-       public SimpleJcrRowLabelProvider(String selectorName, String propertyName) {
-               super(propertyName);
-               this.selectorName = selectorName;
-       }
-
-       /**
-        * Label provider for a given property of a node optionally precising date
-        * and/or number format patterns
-        */
-       public SimpleJcrRowLabelProvider(String selectorName, String propertyName,
-                       String dateFormatPattern, String numberFormatPattern) {
-               super(propertyName, dateFormatPattern, numberFormatPattern);
-               this.selectorName = selectorName;
-       }
-
-       @Override
-       public String getText(Object element) {
-               try {
-                       Row currRow = (Row) element;
-                       Node currNode = currRow.getNode(selectorName);
-                       return super.getText(currNode);
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Unable to get Node " + selectorName
-                                       + " from row " + element, re);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/lists/package-info.java
deleted file mode 100644 (file)
index 3678aab..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Generic SWT/JFace JCR utilities for lists. */
-package org.argeo.eclipse.ui.jcr.lists;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/package-info.java
deleted file mode 100644 (file)
index 19e3cc3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Generic SWT/JFace JCR utilities. */
-package org.argeo.eclipse.ui.jcr;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/JcrFileProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/JcrFileProvider.java
deleted file mode 100644 (file)
index c82e666..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.argeo.eclipse.ui.jcr.util;
-
-import java.io.InputStream;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.FileProvider;
-
-/**
- * Implements a FileProvider for UI purposes. Note that it might not be very
- * reliable as long as we have not fixed login and multi repository issues that
- * will be addressed in the next version.
- * 
- * NOTE: id used here is the real id of the JCR Node, not the JCR Path
- * 
- * Relies on common approach for JCR file handling implementation.
- * 
- */
-@SuppressWarnings("deprecation")
-public class JcrFileProvider implements FileProvider {
-
-       // private Object[] rootNodes;
-       private Node refNode;
-
-       /**
-        * Must be set in order for the provider to be able to get current session
-        * and thus have the ability to get the file node corresponding to a given
-        * file ID
-        * 
-        * @param refNode
-        */
-       public void setReferenceNode(Node refNode) {
-               // FIXME : this introduces some concurrency ISSUES.
-               this.refNode = refNode;
-       }
-
-       public byte[] getByteArrayFileFromId(String fileId) {
-               InputStream fis = null;
-               byte[] ba = null;
-               Node child = getFileNodeFromId(fileId);
-               try {
-                       fis = (InputStream) child.getProperty(Property.JCR_DATA).getBinary().getStream();
-                       ba = IOUtils.toByteArray(fis);
-
-               } catch (Exception e) {
-                       throw new EclipseUiException("Stream error while opening file", e);
-               } finally {
-                       IOUtils.closeQuietly(fis);
-               }
-               return ba;
-       }
-
-       public InputStream getInputStreamFromFileId(String fileId) {
-               try {
-                       InputStream fis = null;
-
-                       Node child = getFileNodeFromId(fileId);
-                       fis = (InputStream) child.getProperty(Property.JCR_DATA).getBinary().getStream();
-                       return fis;
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Cannot get stream from file node for Id " + fileId, re);
-               }
-       }
-
-       /**
-        * Throws an exception if the node is not found in the current repository (a
-        * bit like a FileNotFoundException)
-        * 
-        * @param fileId
-        * @return Returns the child node of the nt:file node. It is the child node
-        *         that have the jcr:data property where actual file is stored.
-        *         never null
-        */
-       private Node getFileNodeFromId(String fileId) {
-               try {
-                       Node result = refNode.getSession().getNodeByIdentifier(fileId);
-
-                       // rootNodes: for (int j = 0; j < rootNodes.length; j++) {
-                       // // in case we have a classic JCR Node
-                       // if (rootNodes[j] instanceof Node) {
-                       // Node curNode = (Node) rootNodes[j];
-                       // if (result != null)
-                       // break rootNodes;
-                       // } // Case of a repository Node
-                       // else if (rootNodes[j] instanceof RepositoryNode) {
-                       // Object[] nodes = ((RepositoryNode) rootNodes[j])
-                       // .getChildren();
-                       // for (int i = 0; i < nodes.length; i++) {
-                       // Node node = (Node) nodes[i];
-                       // result = node.getSession().getNodeByIdentifier(fileId);
-                       // if (result != null)
-                       // break rootNodes;
-                       // }
-                       // }
-                       // }
-
-                       // Sanity checks
-                       if (result == null)
-                               throw new EclipseUiException("File node not found for ID" + fileId);
-
-                       Node child = null;
-
-                       boolean isValid = true;
-                       if (!result.isNodeType(NodeType.NT_FILE))
-                               // useless: mandatory child node
-                               // || !result.hasNode(Property.JCR_CONTENT))
-                               isValid = false;
-                       else {
-                               child = result.getNode(Property.JCR_CONTENT);
-                               if (!(child.isNodeType(NodeType.NT_RESOURCE) || child.hasProperty(Property.JCR_DATA)))
-                                       isValid = false;
-                       }
-
-                       if (!isValid)
-                               throw new EclipseUiException("ERROR: In the current implemented model, '" + NodeType.NT_FILE
-                                               + "' file node must have a child node named jcr:content "
-                                               + "that has a BINARY Property named jcr:data " + "where the actual data is stored");
-                       return child;
-
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Erreur while getting file node of ID " + fileId, re);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/JcrItemsComparator.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/JcrItemsComparator.java
deleted file mode 100644 (file)
index fb12399..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.argeo.eclipse.ui.jcr.util;
-
-import java.util.Comparator;
-
-import javax.jcr.Item;
-import javax.jcr.RepositoryException;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-
-/** Compares two JCR items (node or properties) based on their names. */
-public class JcrItemsComparator implements Comparator<Item> {
-       public int compare(Item o1, Item o2) {
-               try {
-                       // TODO: put folder before files
-                       return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
-               } catch (RepositoryException e) {
-                       throw new EclipseUiException("Cannot compare " + o1 + " and " + o2, e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/NodeViewerComparer.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/NodeViewerComparer.java
deleted file mode 100644 (file)
index 54b795f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.argeo.eclipse.ui.jcr.util;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.viewers.IElementComparer;
-
-/** Compare JCR nodes based on their JCR identifiers, for use in JFace viewers. */
-public class NodeViewerComparer implements IElementComparer {
-
-       // force comparison on Node IDs only.
-       public boolean equals(Object elementA, Object elementB) {
-               if (!(elementA instanceof Node) || !(elementB instanceof Node)) {
-                       return elementA == null ? elementB == null : elementA
-                                       .equals(elementB);
-               } else {
-
-                       boolean result = false;
-                       try {
-                               String idA = ((Node) elementA).getIdentifier();
-                               String idB = ((Node) elementB).getIdentifier();
-                               result = idA == null ? idB == null : idA.equals(idB);
-                       } catch (RepositoryException re) {
-                               throw new EclipseUiException("cannot compare nodes", re);
-                       }
-
-                       return result;
-               }
-       }
-
-       public int hashCode(Object element) {
-               // TODO enhanced this method.
-               return element.getClass().toString().hashCode();
-       }
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/SingleSessionFileProvider.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/SingleSessionFileProvider.java
deleted file mode 100644 (file)
index 291d579..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.argeo.eclipse.ui.jcr.util;
-
-import java.io.InputStream;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.FileProvider;
-
-/**
- * Implements a FileProvider for UI purposes. Unlike the
- * <code> JcrFileProvider </code>, it relies on a single session and manages
- * nodes with path only.
- * 
- * Note that considered id is the JCR path
- * 
- * Relies on common approach for JCR file handling implementation.
- */
-@SuppressWarnings("deprecation")
-public class SingleSessionFileProvider implements FileProvider {
-
-       private Session session;
-
-       public SingleSessionFileProvider(Session session) {
-               this.session = session;
-       }
-
-       public byte[] getByteArrayFileFromId(String fileId) {
-               InputStream fis = null;
-               byte[] ba = null;
-               Node child = getFileNodeFromId(fileId);
-               try {
-                       fis = (InputStream) child.getProperty(Property.JCR_DATA)
-                                       .getBinary().getStream();
-                       ba = IOUtils.toByteArray(fis);
-
-               } catch (Exception e) {
-                       throw new EclipseUiException("Stream error while opening file", e);
-               } finally {
-                       IOUtils.closeQuietly(fis);
-               }
-               return ba;
-       }
-
-       public InputStream getInputStreamFromFileId(String fileId) {
-               try {
-                       InputStream fis = null;
-
-                       Node child = getFileNodeFromId(fileId);
-                       fis = (InputStream) child.getProperty(Property.JCR_DATA)
-                                       .getBinary().getStream();
-                       return fis;
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Cannot get stream from file node for Id "
-                                       + fileId, re);
-               }
-       }
-
-       /**
-        * 
-        * @param fileId
-        * @return Returns the child node of the nt:file node. It is the child node
-        *         that have the jcr:data property where actual file is stored.
-        *         never null
-        */
-       private Node getFileNodeFromId(String fileId) {
-               try {
-                       Node result = null;
-                       result = session.getNode(fileId);
-
-                       // Sanity checks
-                       if (result == null)
-                               throw new EclipseUiException("File node not found for ID" + fileId);
-
-                       // Ensure that the node have the correct type.
-                       if (!result.isNodeType(NodeType.NT_FILE))
-                               throw new EclipseUiException(
-                                               "Cannot open file children Node that are not of "
-                                                               + NodeType.NT_RESOURCE + " type.");
-
-                       Node child = result.getNodes().nextNode();
-                       if (child == null || !child.isNodeType(NodeType.NT_RESOURCE))
-                               throw new EclipseUiException(
-                                               "ERROR: IN the current implemented model, "
-                                                               + NodeType.NT_FILE
-                                                               + "  file node must have one and only one child of the nt:ressource, where actual data is stored");
-                       return child;
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Erreur while getting file node of ID "
-                                       + fileId, re);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/package-info.java b/jcr/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/jcr/util/package-info.java
deleted file mode 100644 (file)
index 016348c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Generic SWT/JFace JCR helpers. */
-package org.argeo.eclipse.ui.jcr.util;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/.classpath b/jcr/org.argeo.cms.jcr/.classpath
deleted file mode 100644 (file)
index 3628e33..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
-               <attributes>
-                       <attribute name="module" value="true"/>
-               </attributes>
-       </classpathentry>
-       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/jcr/org.argeo.cms.jcr/.project b/jcr/org.argeo.cms.jcr/.project
deleted file mode 100644 (file)
index 3e470f8..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>org.argeo.cms.jcr</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.ManifestBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.SchemaBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.ds.core.builder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.pde.PluginNature</nature>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-       </natures>
-</projectDescription>
diff --git a/jcr/org.argeo.cms.jcr/.settings/org.eclipse.jdt.core.prefs b/jcr/org.argeo.cms.jcr/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644 (file)
index 7e2e119..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.problem.APILeak=warning
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
-org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
-org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
-org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/dataServletContext.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/dataServletContext.xml
deleted file mode 100644 (file)
index f5fc8de..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="org.argeo.cms.dataServletContext">
-   <implementation class="org.argeo.cms.jcr.internal.servlet.DataServletContext"/>
-   <service>
-      <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
-   </service>
-   <property name="osgi.http.whiteboard.context.name" type="String" value="dataServletContext"/>
-   <property name="osgi.http.whiteboard.context.path" type="String" value="/data"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/filesServlet.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/filesServlet.xml
deleted file mode 100644 (file)
index a283ef0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.argeo.cms.filesServlet">
-   <implementation class="org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet"/>
-   <service>
-      <provide interface="javax.servlet.Servlet"/>
-   </service>
-   <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/*"/>
-   <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=filesServletContext)"/>
-   <property name="servlet.init.resource-config" type="String" value="/org/argeo/cms/jcr/internal/servlet/webdav-config.xml"/>  
-   <property name="servlet.init.resource-path-prefix" type="String" value="/files"/>
-   <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" policy="static" target="(cn=ego)"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/filesServletContext.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/filesServletContext.xml
deleted file mode 100644 (file)
index 5fb56e3..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="org.argeo.cms.filesServletContext">
-   <implementation class="org.argeo.cms.jcr.internal.servlet.JcrServletContext"/>
-   <service>
-      <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
-   </service>
-   <property name="osgi.http.whiteboard.context.name" type="String" value="filesServletContext"/>
-   <property name="osgi.http.whiteboard.context.path" type="String" value="/files"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrContentProvider.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrContentProvider.xml
deleted file mode 100644 (file)
index 47d724a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" name="JCR Content Provider">
-   <implementation class="org.argeo.cms.jcr.acr.JcrContentProvider"/>
-   <reference bind="setJcrRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=ego)"/>
-   <property name="acr.mount.path" type="String" value="/sys"/>
-   <service>
-      <provide interface="org.argeo.api.acr.spi.ContentProvider"/>
-      <provide interface="org.argeo.cms.jcr.acr.JcrContentProvider"/>
-   </service>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml
deleted file mode 100644 (file)
index 033ddbd..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" name="JCR Deployment">
-   <implementation class="org.argeo.cms.jcr.internal.CmsJcrDeployment"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrFsProvider.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrFsProvider.xml
deleted file mode 100644 (file)
index e26453b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="JCR FS Provider">
-   <implementation class="org.argeo.cms.jcr.internal.CmsJcrFsProvider"/>
-   <property name="service.pid" type="String" value="org.argeo.api.fsProvider"/>
-   <service>
-      <provide interface="java.nio.file.spi.FileSystemProvider"/>
-   </service>
-   <reference bind="setRepositoryFactory" cardinality="1..1" interface="javax.jcr.RepositoryFactory" name="RepositoryFactory" policy="static"/>
-   <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrRepositoryFactory.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrRepositoryFactory.xml
deleted file mode 100644 (file)
index b43b519..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="JCR Repository Factory">
-   <implementation class="org.argeo.cms.jcr.internal.JcrRepositoryFactory"/>
-   <service>
-      <provide interface="javax.jcr.RepositoryFactory"/>
-   </service>
-   <reference cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrServletContext.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrServletContext.xml
deleted file mode 100644 (file)
index a0885bb..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="org.argeo.cms.jcrServletContext">
-   <implementation class="org.argeo.cms.jcr.internal.servlet.JcrServletContext"/>
-   <service>
-      <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
-   </service>
-   <property name="osgi.http.whiteboard.context.name" type="String" value="jcrServletContext"/>
-   <property name="osgi.http.whiteboard.context.path" type="String" value="/jcr"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/repositoryContextsFactory.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/repositoryContextsFactory.xml
deleted file mode 100644 (file)
index 2d06aca..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Jackrabbit Repository Contexts Factory">
-   <implementation class="org.argeo.cms.jcr.internal.RepositoryContextsFactory"/>
-   <property name="service.pid" type="String" value="org.argeo.api.repos"/>
-   <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
-</scr:component>
diff --git a/jcr/org.argeo.cms.jcr/bnd.bnd b/jcr/org.argeo.cms.jcr/bnd.bnd
deleted file mode 100644 (file)
index 01446c1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-Bundle-Activator: org.argeo.cms.jcr.internal.osgi.CmsJcrActivator
-
-Provide-Capability:\
-cms.datamodel; name=jcrx; cnd=/org/argeo/jcr/jcrx.cnd; abstract=true,\
-cms.datamodel; name=argeo; cnd=/org/argeo/cms/jcr/argeo.cnd; abstract=true,\
-cms.datamodel;name=ldap; cnd=/org/argeo/cms/jcr/ldap.cnd; abstract=true,\
-osgi.service;objectClass="javax.jcr.Repository"
-
-Import-Package:\
-org.argeo.cms.servlet,\
-javax.jcr.security,\
-org.h2;resolution:=optional;version="[1,3)",\
-org.postgresql;version="[42,43)";resolution:=optional,\
-org.apache.commons.httpclient.cookie;resolution:=optional,\
-org.osgi.framework.namespace;version=0.0.0,\
-org.osgi.*;version=0.0.0,\
-org.osgi.service.http.whiteboard,\
-org.apache.jackrabbit.api.stats;version="[1,4)",\
-org.apache.jackrabbit.api;version="[1,4)",\
-org.apache.jackrabbit.commons;version="[1,4)",\
-org.apache.jackrabbit.spi;version="[1,4)",\
-org.apache.jackrabbit.spi2dav;version="[1,4)",\
-org.apache.jackrabbit.spi2davex;version="[1,4)",\
-org.apache.jackrabbit.webdav.jcr;version="[1,4)",\
-org.apache.jackrabbit.webdav.server;version="[1,4)",\
-org.apache.jackrabbit.webdav.simple;version="[1,4)",\
-org.apache.jackrabbit.*;version="[1,4)",\
-junit.*;resolution:=optional,\
-javax.servlet.*;version="[3,5)",\
-*
-
-Service-Component:\
-OSGI-INF/repositoryContextsFactory.xml,\
-OSGI-INF/jcrRepositoryFactory.xml,\
-OSGI-INF/jcrFsProvider.xml,\
-OSGI-INF/jcrDeployment.xml,\
-OSGI-INF/jcrServletContext.xml,\
-OSGI-INF/dataServletContext.xml,\
-OSGI-INF/filesServletContext.xml,\
-OSGI-INF/filesServlet.xml,\
diff --git a/jcr/org.argeo.cms.jcr/build.properties b/jcr/org.argeo.cms.jcr/build.properties
deleted file mode 100644 (file)
index 859c241..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-output.. = bin/
-bin.includes = META-INF/,\
-               .,\
-               OSGI-INF/,\
-               OSGI-INF/jcrContentProvider.xml
-source.. = src/
-additional.bundles = org.apache.jackrabbit.data,\
-                     org.apache.jackrabbit.spi.commons
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java
deleted file mode 100644 (file)
index 40d38ee..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.argeo.cms.fs;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.FileSystem;
-import java.nio.file.Path;
-import java.nio.file.spi.FileSystemProvider;
-
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
-
-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 = CmsConstants.SYS_WORKSPACE;
-
-       public static Node getNode(Repository repository, Path path) {
-               String workspaceName = path.getNameCount() == 0 ? baseWorkspaceName : path.getName(0).toString();
-               String jcrPath = '/' + path.subpath(1, path.getNameCount()).toString();
-               try {
-                       Session newSession;
-                       try {
-                               newSession = repository.login(workspaceName);
-                       } catch (NoSuchWorkspaceException e) {
-                               // base workspace
-                               newSession = repository.login(baseWorkspaceName);
-                               jcrPath = path.toString();
-                       }
-                       return newSession.getNode(jcrPath);
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Cannot get node from path " + path, e);
-               }
-       }
-
-       public static NodeIterator getLastUpdatedDocuments(Session session) {
-               try {
-                       String qStr = "//element(*, nt:file)";
-                       qStr += " order by @jcr:lastModified descending";
-                       QueryManager queryManager = session.getWorkspace().getQueryManager();
-                       @SuppressWarnings("deprecation")
-                       Query xpathQuery = queryManager.createQuery(qStr, Query.XPATH);
-                       xpathQuery.setLimit(8);
-                       NodeIterator nit = xpathQuery.execute().getNodes();
-                       return nit;
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Unable to retrieve last updated documents", e);
-               }
-       }
-
-       public static Path getPath(FileSystemProvider nodeFileSystemProvider, URI uri) {
-               try {
-                       FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri);
-                       if (fileSystem == null)
-                               fileSystem = nodeFileSystemProvider.newFileSystem(uri, null);
-                       String path = uri.getPath();
-                       return fileSystem.getPath(path);
-               } catch (IOException e) {
-                       throw new IllegalStateException("Unable to initialise file system for " + uri, e);
-               }
-       }
-
-       public static Path getPath(FileSystemProvider nodeFileSystemProvider, Node node) {
-               String workspaceName = Jcr.getWorkspaceName(node);
-               String fullPath = baseWorkspaceName.equals(workspaceName) ? Jcr.getPath(node)
-                               : '/' + workspaceName + Jcr.getPath(node);
-               URI uri;
-               try {
-                       uri = new URI(CmsConstants.SCHEME_NODE, null, fullPath, null);
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException("Cannot interpret " + fullPath + " as an URI", e);
-               }
-               return getPath(nodeFileSystemProvider, uri);
-       }
-
-       /** Singleton. */
-       private CmsFsUtils() {
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/CustomRepositoryConfigurationParser.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/CustomRepositoryConfigurationParser.java
deleted file mode 100644 (file)
index c289857..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.argeo.cms.internal.jcr;
-
-import java.util.Properties;
-
-import org.apache.jackrabbit.core.config.BeanConfig;
-import org.apache.jackrabbit.core.config.ConfigurationException;
-import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
-import org.apache.jackrabbit.core.config.WorkspaceSecurityConfig;
-import org.apache.jackrabbit.core.util.db.ConnectionFactory;
-import org.w3c.dom.Element;
-
-/**
- * A {@link RepositoryConfigurationParser} providing more flexibility with
- * classloaders.
- */
-@SuppressWarnings("restriction")
-class CustomRepositoryConfigurationParser extends RepositoryConfigurationParser {
-       private ClassLoader classLoader = null;
-
-       public CustomRepositoryConfigurationParser(Properties variables) {
-               super(variables);
-       }
-
-       public CustomRepositoryConfigurationParser(Properties variables, ConnectionFactory connectionFactory) {
-               super(variables, connectionFactory);
-       }
-
-       @Override
-       protected RepositoryConfigurationParser createSubParser(Properties variables) {
-               Properties props = new Properties(getVariables());
-               props.putAll(variables);
-               CustomRepositoryConfigurationParser subParser = new CustomRepositoryConfigurationParser(props,
-                               connectionFactory);
-               subParser.setClassLoader(classLoader);
-               return subParser;
-       }
-
-       @Override
-       public WorkspaceSecurityConfig parseWorkspaceSecurityConfig(Element parent) throws ConfigurationException {
-               WorkspaceSecurityConfig workspaceSecurityConfig = super.parseWorkspaceSecurityConfig(parent);
-               workspaceSecurityConfig.getAccessControlProviderConfig().setClassLoader(classLoader);
-               return workspaceSecurityConfig;
-       }
-
-       @Override
-       protected BeanConfig parseBeanConfig(Element parent, String name) throws ConfigurationException {
-               BeanConfig beanConfig = super.parseBeanConfig(parent, name);
-               if (beanConfig.getClassName().startsWith("org.argeo")) {
-                       beanConfig.setClassLoader(classLoader);
-               }
-               return beanConfig;
-       }
-
-       public void setClassLoader(ClassLoader classLoader) {
-               this.classLoader = classLoader;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JackrabbitType.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JackrabbitType.java
deleted file mode 100644 (file)
index 40c83f6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.argeo.cms.internal.jcr;
-
-/** Pre-defined Jackrabbit repository configurations. */
-enum JackrabbitType {
-       /** Local file system */
-       localfs,
-       /** Embedded Java H2 database */
-       h2,
-       /** Embedded Java H2 database in PostgreSQL compatibility mode */
-       h2_postgresql,
-       /** PostgreSQL */
-       postgresql,
-       /** PostgreSQL with datastore */
-       postgresql_ds,
-       /** PostgreSQL with cluster */
-       postgresql_cluster,
-       /** PostgreSQL with cluster and datastore */
-       postgresql_cluster_ds,
-       /** Memory */
-       memory;
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/LocalFsDataStore.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/LocalFsDataStore.java
deleted file mode 100644 (file)
index dba005c..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.argeo.cms.internal.jcr;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import org.apache.jackrabbit.core.data.DataIdentifier;
-import org.apache.jackrabbit.core.data.DataRecord;
-import org.apache.jackrabbit.core.data.DataStoreException;
-import org.apache.jackrabbit.core.data.FileDataStore;
-
-/**
- * <b>experimental</b> Duplicate added entries in another directory (typically a
- * remote mount).
- */
-@SuppressWarnings("restriction")
-public class LocalFsDataStore extends FileDataStore {
-       String redundantPath;
-       FileDataStore redundantStore;
-
-       @Override
-       public void init(String homeDir) {
-               // init primary first
-               super.init(homeDir);
-
-               if (redundantPath != null) {
-                       // redundant directory must be created first
-                       // TODO implement some polling?
-                       if (Files.exists(Paths.get(redundantPath))) {
-                               redundantStore = new FileDataStore();
-                               redundantStore.setPath(redundantPath);
-                               redundantStore.init(homeDir);
-                       }
-               }
-       }
-
-       @Override
-       public DataRecord addRecord(InputStream input) throws DataStoreException {
-               DataRecord dataRecord = super.addRecord(input);
-               syncRedundantRecord(dataRecord);
-               return dataRecord;
-       }
-
-       @Override
-       public DataRecord getRecord(DataIdentifier identifier) throws DataStoreException {
-               DataRecord dataRecord = super.getRecord(identifier);
-               syncRedundantRecord(dataRecord);
-               return dataRecord;
-       }
-
-       protected void syncRedundantRecord(DataRecord dataRecord) throws DataStoreException {
-               if (redundantStore == null)
-                       return;
-               if (redundantStore.getRecordIfStored(dataRecord.getIdentifier()) == null) {
-                       try (InputStream redundant = dataRecord.getStream()) {
-                               redundantStore.addRecord(redundant);
-                       } catch (IOException e) {
-                               throw new DataStoreException("Cannot add redundant record.", e);
-                       }
-               }
-       }
-
-       public void setRedundantPath(String redundantPath) {
-               this.redundantPath = redundantPath;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java
deleted file mode 100644 (file)
index 336ec82..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.argeo.cms.internal.jcr;
-
-import org.argeo.api.cms.CmsConstants;
-
-/** JCR repository configuration */
-public enum RepoConf {
-       /** Repository type */
-       type("h2"),
-       /** Default workspace */
-       defaultWorkspace(CmsConstants.SYS_WORKSPACE),
-       /** Database URL */
-       dburl(null),
-       /** Database user */
-       dbuser(null),
-       /** Database password */
-       dbpassword(null),
-
-       /** The identifier (can be an URL locating the repo) */
-       labeledUri(null),
-       //
-       // JACKRABBIT SPECIFIC
-       //
-       /** Maximum database pool size */
-       maxPoolSize(10),
-       /** Maximum cache size in MB */
-       maxCacheMB(null),
-       /** Bundle cache size in MB */
-       bundleCacheMB(8),
-       /** Extractor pool size */
-       extractorPoolSize(0),
-       /** Search cache size */
-       searchCacheSize(1000),
-       /** Max volatile index size */
-       maxVolatileIndexSize(1048576),
-       /** Cluster id (if appropriate configuration) */
-       clusterId("default"),
-       /** Indexes base path */
-       indexesBase(null);
-
-       /** The default value. */
-       private Object def;
-
-       RepoConf(String oid, Object def) {
-               this.def = def;
-       }
-
-       RepoConf(Object def) {
-               this.def = def;
-       }
-
-       public Object getDefault() {
-               return def;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java
deleted file mode 100644 (file)
index 3db9716..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-package org.argeo.cms.internal.jcr;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.util.UUID;
-
-import javax.jcr.RepositoryException;
-
-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.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 CmsLog log = CmsLog.getLog(RepositoryBuilder.class);
-
-       public RepositoryContext createRepositoryContext(Dictionary<String, ?> properties)
-                       throws RepositoryException, IOException {
-               RepositoryConfig repositoryConfig = createRepositoryConfig(properties);
-               RepositoryContext repositoryContext = createJackrabbitRepository(repositoryConfig);
-               RepositoryImpl repository = repositoryContext.getRepository();
-
-               // cache
-               Object maxCacheMbStr = prop(properties, RepoConf.maxCacheMB);
-               if (maxCacheMbStr != null) {
-                       Integer maxCacheMB = Integer.parseInt(maxCacheMbStr.toString());
-                       CacheManager cacheManager = repository.getCacheManager();
-                       cacheManager.setMaxMemory(maxCacheMB * 1024l * 1024l);
-                       cacheManager.setMaxMemoryPerCache((maxCacheMB / 4) * 1024l * 1024l);
-               }
-
-               return repositoryContext;
-       }
-
-       RepositoryConfig createRepositoryConfig(Dictionary<String, ?> properties) throws RepositoryException, IOException {
-               JackrabbitType type = JackrabbitType.valueOf(prop(properties, RepoConf.type).toString());
-               ClassLoader cl = getClass().getClassLoader();
-               final String base = "/org/argeo/cms/internal/jcr";
-               try (InputStream in = cl.getResourceAsStream(base + "/repository-" + type.name() + ".xml")) {
-                       if (in == null)
-                               throw new IllegalArgumentException("Repository configuration not found");
-                       InputSource config = new InputSource(in);
-                       Properties jackrabbitVars = getConfigurationProperties(type, properties);
-                       // RepositoryConfig repositoryConfig = RepositoryConfig.create(config,
-                       // jackrabbitVars);
-
-                       // custom configuration parser
-                       CustomRepositoryConfigurationParser parser = new CustomRepositoryConfigurationParser(jackrabbitVars);
-                       parser.setClassLoader(cl);
-                       RepositoryConfig repositoryConfig = parser.parseRepositoryConfig(config);
-                       repositoryConfig.init();
-
-                       // set the proper classloaders
-                       repositoryConfig.getSecurityConfig().getSecurityManagerConfig().setClassLoader(cl);
-                       repositoryConfig.getSecurityConfig().getAccessManagerConfig().setClassLoader(cl);
-//                     for (WorkspaceConfig workspaceConfig : repositoryConfig.getWorkspaceConfigs()) {
-//                             workspaceConfig.getSecurityConfig().getAccessControlProviderConfig().setClassLoader(cl);
-//                     }
-                       return repositoryConfig;
-               }
-       }
-
-       private Properties getConfigurationProperties(JackrabbitType type, Dictionary<String, ?> properties) {
-               Properties props = new Properties();
-               for (Enumeration<String> keys = properties.keys(); keys.hasMoreElements();) {
-                       String key = keys.nextElement();
-                       props.put(key, properties.get(key));
-               }
-
-               // cluster id
-               // cf. https://wiki.apache.org/jackrabbit/Clustering
-               // TODO deal with multiple repos
-               String clusterId = System.getProperty("org.apache.jackrabbit.core.cluster.node_id");
-               String clusterIdProp = props.getProperty(RepoConf.clusterId.name());
-               if (clusterId != null) {
-                       if (clusterIdProp != null)
-                               throw new IllegalArgumentException("Cluster id defined as System properties and in deploy config");
-                       props.put(RepoConf.clusterId.name(), clusterId);
-               } else {
-                       clusterId = clusterIdProp;
-               }
-
-               // home
-               String homeUri = props.getProperty(RepoConf.labeledUri.name());
-               Path homePath;
-               if (homeUri == null) {
-                       String cn = props.getProperty(CmsConstants.CN);
-                       assert cn != null;
-                       if (clusterId != null) {
-                               homePath = CmsPaths.getRepoDirPath(cn + '/' + clusterId);
-                       } else {
-                               homePath = CmsPaths.getRepoDirPath(cn);
-                       }
-               } else {
-                       try {
-                               URI uri = new URI(homeUri);
-                               String host = uri.getHost();
-                               if (host == null || host.trim().equals("")) {
-                                       homePath = Paths.get(uri).toAbsolutePath();
-                               } else {
-                                       // TODO remote at this stage?
-                                       throw new IllegalArgumentException("Cannot manage repository path for host " + host);
-                               }
-                       } catch (URISyntaxException e) {
-                               throw new IllegalArgumentException("Invalid repository home URI", e);
-                       }
-               }
-               // TODO use Jackrabbit API (?)
-               Path rootUuidPath = homePath.resolve("repository/meta/rootUUID");
-               try {
-                       if (!Files.exists(rootUuidPath)) {
-                               Files.createDirectories(rootUuidPath.getParent());
-                               Files.write(rootUuidPath, UUID.randomUUID().toString().getBytes());
-                       }
-                       // File homeDir = homePath.toFile();
-                       // homeDir.mkdirs();
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot set up repository  home " + homePath, e);
-               }
-               // home cannot be overridden
-               props.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, homePath.toString());
-
-               setProp(props, RepoConf.indexesBase, CmsPaths.getRepoIndexesBase().toString());
-               // common
-               setProp(props, RepoConf.defaultWorkspace);
-               setProp(props, RepoConf.maxPoolSize);
-               // Jackrabbit defaults
-               setProp(props, RepoConf.bundleCacheMB);
-               // See http://wiki.apache.org/jackrabbit/Search
-               setProp(props, RepoConf.extractorPoolSize);
-               setProp(props, RepoConf.searchCacheSize);
-               setProp(props, RepoConf.maxVolatileIndexSize);
-
-               // specific
-               String dburl;
-               switch (type) {
-               case h2:
-                       dburl = "jdbc:h2:" + homePath.toAbsolutePath() + "/h2/repository";
-                       setProp(props, RepoConf.dburl, dburl);
-                       setProp(props, RepoConf.dbuser, "sa");
-                       setProp(props, RepoConf.dbpassword, "");
-                       break;
-               case h2_postgresql:
-                       dburl = "jdbc:h2:" + homePath.toAbsolutePath() + "/h2/repository;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE";
-                       setProp(props, RepoConf.dburl, dburl);
-                       setProp(props, RepoConf.dbuser, "sa");
-                       setProp(props, RepoConf.dbpassword, "");
-                       break;
-               case postgresql:
-               case postgresql_ds:
-               case postgresql_cluster:
-               case postgresql_cluster_ds:
-                       dburl = "jdbc:postgresql://localhost/demo";
-                       setProp(props, RepoConf.dburl, dburl);
-                       setProp(props, RepoConf.dbuser, "argeo");
-                       setProp(props, RepoConf.dbpassword, "argeo");
-                       break;
-               case memory:
-                       break;
-               case localfs:
-                       break;
-               default:
-                       throw new IllegalArgumentException("Unsupported node type " + type);
-               }
-               return props;
-       }
-
-       private void setProp(Properties props, RepoConf key, String def) {
-               Object value = props.get(key.name());
-               if (value == null)
-                       value = def;
-               if (value == null)
-                       value = key.getDefault();
-               if (value != null)
-                       props.put(key.name(), value.toString());
-       }
-
-       private void setProp(Properties props, RepoConf key) {
-               setProp(props, key, null);
-       }
-
-       private String prop(Dictionary<String, ?> properties, RepoConf key) {
-               Object value = properties.get(key.name());
-               if (value == null)
-                       return key.getDefault() != null ? key.getDefault().toString() : null;
-               else
-                       return value.toString();
-       }
-
-       private RepositoryContext createJackrabbitRepository(RepositoryConfig repositoryConfig) throws RepositoryException {
-               ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
-               Thread.currentThread().setContextClassLoader(RepositoryBuilder.class.getClassLoader());
-               try {
-                       long begin = System.currentTimeMillis();
-                       //
-                       // Actual repository creation
-                       //
-                       RepositoryContext repositoryContext = RepositoryContext.create(repositoryConfig);
-
-                       double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
-                       if (log.isDebugEnabled())
-                               log.debug(
-                                               "Created Jackrabbit repository in " + duration + " s, home: " + repositoryConfig.getHomeDir());
-
-                       return repositoryContext;
-               } finally {
-                       Thread.currentThread().setContextClassLoader(currentContextCl);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-h2.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-h2.xml
deleted file mode 100644 (file)
index ace0fa5..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.h2.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="h2" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="default" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-       <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
-               <param name="path" value="${rep.home}/datastore" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-<!--                   <param name="tikaConfigPath" value="${indexesBase}/${cn}/tika-config.xml" /> -->
-                       <param name="supportHighlighting" value="true" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-<!--           <param name="tikaConfigPath" value="${indexesBase}/${cn}/tika-config.xml" /> -->
-               <param name="supportHighlighting" value="true" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-h2_postgresql.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-h2_postgresql.xml
deleted file mode 100644 (file)
index 4303676..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.h2.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="postgresql" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="default" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-       <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
-               <param name="path" value="${rep.home}/datastore" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-<!--                   <param name="tikaConfigPath" value="${indexesBase}/${cn}/tika-config.xml" /> -->
-                       <param name="supportHighlighting" value="true" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-<!--           <param name="tikaConfigPath" value="${indexesBase}/${cn}/tika-config.xml" /> -->
-               <param name="supportHighlighting" value="true" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-localfs.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-localfs.xml
deleted file mode 100644 (file)
index b889079..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-               <param name="path" value="${rep.home}/repository" />
-       </FileSystem>
-       <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
-               <param name="path" value="${rep.home}/datastore" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-                       <param name="path" value="${wsp.home}" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-                       <param name="path" value="${rep.home}/version" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-memory.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-memory.xml
deleted file mode 100644 (file)
index 3630a14..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" configRootPath="/workspaces" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="blobFSBlockSize" value="1" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="directoryManagerClass"
-                               value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-                       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="blobFSBlockSize" value="1" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="directoryManagerClass"
-                       value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql.xml
deleted file mode 100644 (file)
index de2f245..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.postgresql.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="postgresql" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="postgresql" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_cluster.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_cluster.xml
deleted file mode 100644 (file)
index 488ad6b..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.postgresql.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="postgresql" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="postgresql" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-
-       <!-- Clustering -->
-       <Cluster id="${clusterId}">
-               <Journal class="org.apache.jackrabbit.core.journal.DatabaseJournal">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="journal_" />
-               </Journal>
-       </Cluster>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_cluster_ds.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_cluster_ds.xml
deleted file mode 100644 (file)
index b430674..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.postgresql.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="postgresql" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem
-               class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="postgresql" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-       <DataStore
-               class="org.argeo.cms.internal.jcr.LocalFsDataStore">
-               <param name="path" value="${rep.home}/../datastore" />
-               <param name="redundantPath" value="${rep.home}/../datastorer" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem
-                       class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex
-                       class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path"
-                               value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize"
-                               value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem
-                       class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex
-               class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize"
-                       value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager
-                       class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager
-                       class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-
-       <!-- Clustering -->
-       <Cluster id="${clusterId}" syncDelay="100">
-               <Journal
-                       class="org.apache.jackrabbit.core.journal.DatabaseJournal">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="journal_" />
-               </Journal>
-       </Cluster>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_ds.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/repository-postgresql_ds.xml
deleted file mode 100644 (file)
index 5229d16..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.postgresql.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="postgresql" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="postgresql" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-       <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
-               <param name="path" value="${rep.home}/datastore" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${indexesBase}/${cn}/${wsp.name}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${indexesBase}/${cn}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java
deleted file mode 100644 (file)
index 7fde177..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-package org.argeo.cms.jcr;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-import javax.security.auth.AuthPermission;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-import org.argeo.api.cms.CmsAuth;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.util.CurrentSubject;
-
-/** Utilities related to Argeo model in JCR */
-public class CmsJcrUtils {
-       /**
-        * Wraps the call to the repository factory based on parameter
-        * {@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(CmsConstants.CN, alias);
-                       return repositoryFactory.getRepository(parameters);
-               } catch (RepositoryException e) {
-                       throw new RuntimeException("Unexpected exception when trying to retrieve repository with alias " + alias,
-                                       e);
-               }
-       }
-
-       /**
-        * Wraps the call to the repository factory based on parameter
-        * {@link CmsConstants#LABELED_URI} in order to simplify it and protect against
-        * future API changes.
-        */
-       public static Repository getRepositoryByUri(RepositoryFactory repositoryFactory, String uri) {
-               return getRepositoryByUri(repositoryFactory, uri, null);
-       }
-
-       /**
-        * Wraps the call to the repository factory based on parameter
-        * {@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(CmsConstants.LABELED_URI, uri);
-                       if (alias != null)
-                               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);
-               }
-       }
-
-       /**
-        * Returns the home node of the user or null if none was found.
-        * 
-        * @param session  the session to use in order to perform the search, this can
-        *                 be a session with a different user ID than the one searched,
-        *                 typically when a system or admin session is used.
-        * @param username the username of the user
-        */
-       public static Node getUserHome(Session session, String username) {
-//             try {
-//                     QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
-//                     Selector sel = qomf.selector(NodeTypes.NODE_USER_HOME, "sel");
-//                     DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_UID);
-//                     StaticOperand sop = qomf.literal(session.getValueFactory().createValue(username));
-//                     Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
-//                     Query query = qomf.createQuery(sel, constraint, null, null);
-//                     return querySingleNode(query);
-//             } catch (RepositoryException e) {
-//                     throw new RuntimeException("Cannot find home for user " + username, e);
-//             }
-
-               try {
-                       checkUserWorkspace(session, username);
-                       String homePath = getHomePath(username);
-                       if (session.itemExists(homePath))
-                               return session.getNode(homePath);
-                       // legacy
-                       homePath = "/home/" + username;
-                       if (session.itemExists(homePath))
-                               return session.getNode(homePath);
-                       return null;
-               } catch (RepositoryException e) {
-                       throw new RuntimeException("Cannot find home for user " + username, e);
-               }
-       }
-
-       private static String getHomePath(String username) {
-               LdapName dn;
-               try {
-                       dn = new LdapName(username);
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Invalid name " + username, e);
-               }
-               String userId = dn.getRdn(dn.size() - 1).getValue().toString();
-               return '/' + userId;
-       }
-
-       private static void checkUserWorkspace(Session session, String username) {
-               String workspaceName = session.getWorkspace().getName();
-               if (!CmsConstants.HOME_WORKSPACE.equals(workspaceName))
-                       throw new IllegalArgumentException(workspaceName + " is not the home workspace for user " + username);
-       }
-
-       /**
-        * Returns the home node of the user or null if none was found.
-        * 
-        * @param session   the session to use in order to perform the search, this can
-        *                  be a session with a different user ID than the one searched,
-        *                  typically when a system or admin session is used.
-        * @param groupname the name of the group
-        */
-       public static Node getGroupHome(Session session, String groupname) {
-//             try {
-//                     QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
-//                     Selector sel = qomf.selector(NodeTypes.NODE_GROUP_HOME, "sel");
-//                     DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_CN);
-//                     StaticOperand sop = qomf.literal(session.getValueFactory().createValue(cn));
-//                     Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
-//                     Query query = qomf.createQuery(sel, constraint, null, null);
-//                     return querySingleNode(query);
-//             } catch (RepositoryException e) {
-//                     throw new RuntimeException("Cannot find home for group " + cn, e);
-//             }
-
-               try {
-                       checkGroupWorkspace(session, groupname);
-                       String homePath = getGroupPath(groupname);
-                       if (session.itemExists(homePath))
-                               return session.getNode(homePath);
-                       // legacy
-                       homePath = "/groups/" + groupname;
-                       if (session.itemExists(homePath))
-                               return session.getNode(homePath);
-                       return null;
-               } catch (RepositoryException e) {
-                       throw new RuntimeException("Cannot find home for group " + groupname, e);
-               }
-
-       }
-
-       private static String getGroupPath(String groupname) {
-               String cn;
-               try {
-                       LdapName dn = new LdapName(groupname);
-                       cn = dn.getRdn(dn.size() - 1).getValue().toString();
-               } catch (InvalidNameException e) {
-                       cn = groupname;
-               }
-               return '/' + cn;
-       }
-
-       private static void checkGroupWorkspace(Session session, String groupname) {
-               String workspaceName = session.getWorkspace().getName();
-               if (!CmsConstants.SRV_WORKSPACE.equals(workspaceName))
-                       throw new IllegalArgumentException(workspaceName + " is not the group workspace for group " + groupname);
-       }
-
-       /**
-        * Queries one single node.
-        * 
-        * @return one single node or null if none was found
-        * @throws ArgeoJcrException if more than one node was found
-        */
-//     private static Node querySingleNode(Query query) {
-//             NodeIterator nodeIterator;
-//             try {
-//                     QueryResult queryResult = query.execute();
-//                     nodeIterator = queryResult.getNodes();
-//             } catch (RepositoryException e) {
-//                     throw new RuntimeException("Cannot execute query " + query, e);
-//             }
-//             Node node;
-//             if (nodeIterator.hasNext())
-//                     node = nodeIterator.nextNode();
-//             else
-//                     return null;
-//
-//             if (nodeIterator.hasNext())
-//                     throw new RuntimeException("Query returned more than one node.");
-//             return node;
-//     }
-
-       /** Returns the home node of the session user or null if none was found. */
-       public static Node getUserHome(Session session) {
-               String userID = session.getUserID();
-               return getUserHome(session, userID);
-       }
-
-       /** Whether this node is the home of the user of the underlying session. */
-       public static boolean isUserHome(Node node) {
-               try {
-                       String userID = node.getSession().getUserID();
-                       return node.hasProperty(Property.JCR_ID) && node.getProperty(Property.JCR_ID).getString().equals(userID);
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException(e);
-               }
-       }
-
-       /**
-        * Translate the path to this node into a path containing the name of the
-        * repository and the name of the workspace.
-        */
-       public static String getDataPath(String cn, Node node) {
-               assert node != null;
-               StringBuilder buf = new StringBuilder(CmsConstants.PATH_DATA);
-               try {
-                       return buf.append('/').append(cn).append('/').append(node.getSession().getWorkspace().getName())
-                                       .append(node.getPath()).toString();
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Cannot get data path for " + node + " in repository " + cn, e);
-               }
-       }
-
-       /**
-        * Translate the path to this node into a path containing the name of the
-        * repository and the name of the workspace.
-        */
-       public static String getDataPath(Node node) {
-               return getDataPath(CmsConstants.NODE, node);
-       }
-
-       /**
-        * Open a JCR session with full read/write rights on the data, as
-        * {@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) {
-               LoginContext loginContext;
-               try {
-                       loginContext = CmsAuth.DATA_ADMIN.newLoginContext();
-                       loginContext.login();
-               } catch (LoginException e1) {
-                       throw new RuntimeException("Could not login as data admin", e1);
-               } finally {
-               }
-
-               ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
-               try {
-                       Thread.currentThread().setContextClassLoader(CmsJcrUtils.class.getClassLoader());
-                       return CurrentSubject.callAs(loginContext.getSubject(), () -> {
-                               try {
-                                       return JcrUtils.loginOrCreateWorkspace(repository, workspaceName);
-                               } catch (NoSuchWorkspaceException e) {// should not happen
-                                       throw new IllegalArgumentException("No workspace " + workspaceName + " available", e);
-                               } catch (RepositoryException e) {
-                                       throw new RuntimeException("Cannot open data admin session", e);
-                               }
-                       }
-
-                       );
-               } finally {
-                       Thread.currentThread().setContextClassLoader(currentCl);
-               }
-       }
-
-       /** Singleton. */
-       private CmsJcrUtils() {
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java
deleted file mode 100644 (file)
index a4af35b..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-package org.argeo.cms.jcr.acr;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ForkJoinPool;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeType;
-import javax.xml.namespace.QName;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.acr.NamespaceUtils;
-import org.argeo.api.acr.spi.ContentProvider;
-import org.argeo.api.acr.spi.ProvidedSession;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.acr.AbstractContent;
-import org.argeo.cms.acr.ContentUtils;
-import org.argeo.jcr.Jcr;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-
-/** A JCR {@link Node} accessed as {@link Content}. */
-public class JcrContent extends AbstractContent {
-//     private Node jcrNode;
-
-       private JcrContentProvider provider;
-
-       private String jcrWorkspace;
-       private String jcrPath;
-
-       protected JcrContent(ProvidedSession session, JcrContentProvider provider, String jcrWorkspace, String jcrPath) {
-               super(session);
-               this.provider = provider;
-               this.jcrWorkspace = jcrWorkspace;
-               this.jcrPath = jcrPath;
-       }
-
-       @Override
-       public QName getName() {
-               String name = Jcr.getName(getJcrNode());
-               if (name.equals("")) {// root
-                       String mountPath = provider.getMountPath();
-                       name = ContentUtils.getParentPath(mountPath)[1];
-                       // name = Jcr.getWorkspaceName(getJcrNode());
-               }
-               return NamespaceUtils.parsePrefixedName(provider, name);
-       }
-
-       @SuppressWarnings("unchecked")
-       @Override
-       public <A> Optional<A> get(QName key, Class<A> clss) {
-               if (isDefaultAttrTypeRequested(clss)) {
-                       return Optional.of((A) get(getJcrNode(), key.toString()));
-               }
-               return Optional.of((A) Jcr.get(getJcrNode(), key.toString()));
-       }
-
-       @Override
-       public Iterator<Content> iterator() {
-               try {
-                       return new JcrContentIterator(getJcrNode().getNodes());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot list children of " + getJcrNode(), e);
-               }
-       }
-
-       @Override
-       protected Iterable<QName> keys() {
-               try {
-                       Set<QName> keys = new HashSet<>();
-                       for (PropertyIterator propertyIterator = getJcrNode().getProperties(); propertyIterator.hasNext();) {
-                               Property property = propertyIterator.nextProperty();
-                               // TODO convert standard names
-                               // TODO skip technical properties
-                               QName name = NamespaceUtils.parsePrefixedName(provider, property.getName());
-                               keys.add(name);
-                       }
-                       return keys;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot list properties of " + getJcrNode(), e);
-               }
-       }
-
-       public Node getJcrNode() {
-               try {
-                       // TODO caching?
-                       return provider.getJcrSession(getSession(), jcrWorkspace).getNode(jcrPath);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve " + jcrPath + " from workspace " + jcrWorkspace, e);
-               }
-       }
-
-       /** Cast to a standard Java object. */
-       static Object get(Node node, String property) {
-               try {
-                       Property p = node.getProperty(property);
-                       if (p.isMultiple()) {
-                               Value[] values = p.getValues();
-                               List<Object> lst = new ArrayList<>();
-                               for (Value value : values) {
-                                       lst.add(convertSingleValue(value));
-                               }
-                               return lst;
-                       } else {
-                               Value value = node.getProperty(property).getValue();
-                               return convertSingleValue(value);
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot cast value from " + property + " of node " + node, e);
-               }
-       }
-
-       static Object convertSingleValue(Value value) throws RepositoryException {
-               switch (value.getType()) {
-               case PropertyType.STRING:
-                       return value.getString();
-               case PropertyType.DOUBLE:
-                       return (Double) value.getDouble();
-               case PropertyType.LONG:
-                       return (Long) value.getLong();
-               case PropertyType.BOOLEAN:
-                       return (Boolean) value.getBoolean();
-               case PropertyType.DATE:
-                       Calendar calendar = value.getDate();
-                       return calendar.toInstant();
-               case PropertyType.BINARY:
-                       throw new IllegalArgumentException("Binary is not supported as an attribute");
-               default:
-                       return value.getString();
-               }
-       }
-
-       class JcrContentIterator implements Iterator<Content> {
-               private final NodeIterator nodeIterator;
-               // we keep track in order to be able to delete it
-               private JcrContent current = null;
-
-               protected JcrContentIterator(NodeIterator nodeIterator) {
-                       this.nodeIterator = nodeIterator;
-               }
-
-               @Override
-               public boolean hasNext() {
-                       return nodeIterator.hasNext();
-               }
-
-               @Override
-               public Content next() {
-                       current = new JcrContent(getSession(), provider, jcrWorkspace, Jcr.getPath(nodeIterator.nextNode()));
-                       return current;
-               }
-
-               @Override
-               public void remove() {
-                       if (current != null) {
-                               Jcr.remove(current.getJcrNode());
-                       }
-               }
-
-       }
-
-       @Override
-       public String getPath() {
-               try {
-                       // Note: it is important to to use the default way (recursing through parents),
-                       // since the session may not have access to parent nodes
-                       return ContentUtils.ROOT_SLASH + jcrWorkspace + getJcrNode().getPath();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get depth of " + getJcrNode(), e);
-               }
-       }
-
-       @Override
-       public int getDepth() {
-               try {
-                       return getJcrNode().getDepth() + 1;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get depth of " + getJcrNode(), e);
-               }
-       }
-
-       @Override
-       public Content getParent() {
-               if (Jcr.isRoot(getJcrNode())) // root
-                       return null;
-               return new JcrContent(getSession(), provider, jcrWorkspace, Jcr.getParentPath(getJcrNode()));
-       }
-
-       @Override
-       public Content add(QName name, QName... classes) {
-               if (classes.length > 0) {
-                       QName primaryType = classes[0];
-                       Node child = Jcr.addNode(getJcrNode(), name.toString(), primaryType.toString());
-                       for (int i = 1; i < classes.length; i++) {
-                               try {
-                                       child.addMixin(classes[i].toString());
-                               } catch (RepositoryException e) {
-                                       throw new JcrException("Cannot add child to " + getJcrNode(), e);
-                               }
-                       }
-
-               } else {
-                       Jcr.addNode(getJcrNode(), name.toString(), NodeType.NT_UNSTRUCTURED);
-               }
-               return null;
-       }
-
-       @Override
-       public void remove() {
-               Jcr.remove(getJcrNode());
-       }
-
-       @Override
-       protected void removeAttr(QName key) {
-               Property property = Jcr.getProperty(getJcrNode(), key.toString());
-               if (property != null) {
-                       try {
-                               property.remove();
-                       } catch (RepositoryException e) {
-                               throw new JcrException("Cannot remove property " + key + " from " + getJcrNode(), e);
-                       }
-               }
-
-       }
-
-       boolean exists() {
-               try {
-                       return provider.getJcrSession(getSession(), jcrWorkspace).itemExists(jcrPath);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check whether " + jcrPath + " exists", e);
-               }
-       }
-
-       /*
-        * ADAPTERS
-        */
-       @SuppressWarnings("unchecked")
-       public <A> A adapt(Class<A> clss) {
-               if (Source.class.isAssignableFrom(clss)) {
-//                     try {
-                       PipedInputStream in = new PipedInputStream();
-
-                       ForkJoinPool.commonPool().execute(() -> {
-                               try (PipedOutputStream out = new PipedOutputStream(in)) {
-                                       provider.getJcrSession(getSession(), jcrWorkspace).exportDocumentView(jcrPath, out, true, false);
-                                       out.flush();
-                               } catch (IOException | RepositoryException e) {
-                                       throw new RuntimeException("Cannot export " + jcrPath + " in workspace " + jcrWorkspace, e);
-                               }
-
-                       });
-                       return (A) new StreamSource(in);
-//                     } catch (IOException e) {
-//                             throw new RuntimeException("Cannot adapt " + JcrContent.this + " to " + clss, e);
-//                     }
-               } else
-
-                       return super.adapt(clss);
-       }
-
-       @SuppressWarnings("unchecked")
-       @Override
-       public <C extends Closeable> C open(Class<C> clss) throws IOException, IllegalArgumentException {
-               if (InputStream.class.isAssignableFrom(clss)) {
-                       Node node = getJcrNode();
-                       if (Jcr.isNodeType(node, NodeType.NT_FILE)) {
-                               try {
-                                       return (C) JcrUtils.getFileAsStream(node);
-                               } catch (RepositoryException e) {
-                                       throw new JcrException("Cannot open " + jcrPath + " in workspace " + jcrWorkspace, e);
-                               }
-                       }
-               }
-               return super.open(clss);
-       }
-
-       @Override
-       public ContentProvider getProvider() {
-               return provider;
-       }
-
-       @Override
-       public String getSessionLocalId() {
-               try {
-                       return getJcrNode().getIdentifier();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get identifier for " + getJcrNode(), e);
-               }
-       }
-
-       /*
-        * TYPING
-        */
-       @Override
-       public List<QName> getContentClasses() {
-               try {
-//                     Node node = getJcrNode();
-//                     List<QName> res = new ArrayList<>();
-//                     res.add(nodeTypeToQName(node.getPrimaryNodeType()));
-//                     for (NodeType mixin : node.getMixinNodeTypes()) {
-//                             res.add(nodeTypeToQName(mixin));
-//                     }
-//                     return res;
-                       Node context = getJcrNode();
-
-                       List<QName> res = new ArrayList<>();
-                       // primary node type
-                       NodeType primaryType = context.getPrimaryNodeType();
-                       res.add(nodeTypeToQName(primaryType));
-
-                       Set<QName> secondaryTypes = new TreeSet<>(NamespaceUtils.QNAME_COMPARATOR);
-                       for (NodeType mixinType : context.getMixinNodeTypes()) {
-                               secondaryTypes.add(nodeTypeToQName(mixinType));
-                       }
-                       for (NodeType superType : primaryType.getDeclaredSupertypes()) {
-                               secondaryTypes.add(nodeTypeToQName(superType));
-                       }
-                       // mixins
-                       for (NodeType mixinType : context.getMixinNodeTypes()) {
-                               for (NodeType superType : mixinType.getDeclaredSupertypes()) {
-                                       secondaryTypes.add(nodeTypeToQName(superType));
-                               }
-                       }
-//             // entity type
-//             if (context.isNodeType(EntityType.entity.get())) {
-//                     if (context.hasProperty(EntityNames.ENTITY_TYPE)) {
-//                             String entityTypeName = context.getProperty(EntityNames.ENTITY_TYPE).getString();
-//                             if (byType.containsKey(entityTypeName)) {
-//                                     types.add(entityTypeName);
-//                             }
-//                     }
-//             }
-                       res.addAll(secondaryTypes);
-                       return res;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot list node types from " + getJcrNode(), e);
-               }
-       }
-
-       private QName nodeTypeToQName(NodeType nodeType) {
-               String name = nodeType.getName();
-               return QName.valueOf(name);
-       }
-
-       @Override
-       public int getSiblingIndex() {
-               return Jcr.getIndex(getJcrNode());
-       }
-
-       /*
-        * STATIC UTLITIES
-        */
-       public static Content nodeToContent(Node node) {
-               if (node == null)
-                       return null;
-               try {
-                       ProvidedSession contentSession = (ProvidedSession) node.getSession()
-                                       .getAttribute(ProvidedSession.class.getName());
-                       if (contentSession == null)
-                               throw new IllegalArgumentException(
-                                               "Cannot adapt " + node + " to content, because it was not loaded from a content session");
-                       return contentSession.get(ContentUtils.SLASH + CmsConstants.SYS_WORKSPACE + node.getPath());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot adapt " + node + " to a content", e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java
deleted file mode 100644 (file)
index eaa27b7..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.argeo.cms.jcr.acr;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Objects;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.xml.namespace.NamespaceContext;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.acr.spi.ContentProvider;
-import org.argeo.api.acr.spi.ProvidedContent;
-import org.argeo.api.acr.spi.ProvidedSession;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.acr.ContentUtils;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-
-/** A JCR workspace accessed as an {@link ContentProvider}. */
-public class JcrContentProvider implements ContentProvider, NamespaceContext {
-
-       private Repository jcrRepository;
-       private Session adminSession;
-
-       private String mountPath;
-
-       // cache
-       private String jcrWorkspace;
-
-       private Map<ProvidedSession, JcrSessionAdapter> sessionAdapters = Collections.synchronizedMap(new HashMap<>());
-
-       public void start(Map<String, String> properties) {
-               mountPath = properties.get(CmsConstants.ACR_MOUNT_PATH);
-               if ("/".equals(mountPath))
-                       throw new IllegalArgumentException("JCR content provider cannot be root /");
-               Objects.requireNonNull(mountPath);
-               jcrWorkspace = ContentUtils.getParentPath(mountPath)[1];
-               adminSession = CmsJcrUtils.openDataAdminSession(jcrRepository, jcrWorkspace);
-       }
-
-       public void stop() {
-               if (adminSession.isLive())
-                       JcrUtils.logoutQuietly(adminSession);
-       }
-
-       public void setJcrRepository(Repository jcrRepository) {
-               this.jcrRepository = jcrRepository;
-       }
-
-       @Override
-       public ProvidedContent get(ProvidedSession contentSession, String relativePath) {
-               String jcrPath = "/" + relativePath;
-               return new JcrContent(contentSession, this, jcrWorkspace, jcrPath);
-       }
-
-       @Override
-       public boolean exists(ProvidedSession contentSession, String relativePath) {
-               String jcrWorkspace = ContentUtils.getParentPath(mountPath)[1];
-               String jcrPath = "/" + relativePath;
-               return new JcrContent(contentSession, this, jcrWorkspace, jcrPath).exists();
-       }
-
-       public Session getJcrSession(ProvidedSession contentSession, String jcrWorkspace) {
-               JcrSessionAdapter sessionAdapter = sessionAdapters.get(contentSession);
-               if (sessionAdapter == null) {
-                       final JcrSessionAdapter newSessionAdapter = new JcrSessionAdapter(jcrRepository, contentSession,
-                                       contentSession.getSubject());
-                       sessionAdapters.put(contentSession, newSessionAdapter);
-                       contentSession.onClose().thenAccept((s) -> newSessionAdapter.close());
-                       sessionAdapter = newSessionAdapter;
-               }
-
-               Session jcrSession = sessionAdapter.getSession(jcrWorkspace);
-               return jcrSession;
-       }
-
-       public Session getJcrSession(Content content, String jcrWorkspace) {
-               return getJcrSession(((ProvidedContent) content).getSession(), jcrWorkspace);
-       }
-
-       @Override
-       public String getMountPath() {
-               return mountPath;
-       }
-
-       /*
-        * NAMESPACE CONTEXT
-        */
-       @Override
-       public String getNamespaceURI(String prefix) {
-               try {
-                       return adminSession.getNamespaceURI(prefix);
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-       @Override
-       public String getPrefix(String namespaceURI) {
-               try {
-                       return adminSession.getNamespacePrefix(namespaceURI);
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-       @Override
-       public Iterator<String> getPrefixes(String namespaceURI) {
-               try {
-                       return Arrays.asList(adminSession.getNamespacePrefix(namespaceURI)).iterator();
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java
deleted file mode 100644 (file)
index 25e54b3..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-package org.argeo.cms.jcr.acr;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeType;
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Source;
-import javax.xml.transform.dom.DOMSource;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.acr.ContentName;
-import org.argeo.api.acr.CrName;
-import org.argeo.api.acr.DName;
-import org.argeo.api.acr.NamespaceUtils;
-import org.argeo.api.acr.spi.ProvidedContent;
-import org.argeo.api.acr.spi.ProvidedSession;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.jcr.Jcr;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-/** Utilities around integration between JCR and ACR. */
-public class JcrContentUtils {
-       private final static CmsLog log = CmsLog.getLog(JcrContentUtils.class);
-
-       public static void copyFiles(Node folder, Content collection, String... additionalCollectionTypes) {
-               try {
-                       log.debug("Copy collection " + collection);
-
-                       NamespaceContext jcrNamespaceContext = new JcrSessionNamespaceContext(folder.getSession());
-
-                       nodes: for (NodeIterator it = folder.getNodes(); it.hasNext();) {
-                               Node node = it.nextNode();
-                               String name = node.getName();
-                               if (node.isNodeType(NodeType.NT_FILE)) {
-                                       Content file = collection.anyOrAddChild(new ContentName(name));
-                                       try (InputStream in = JcrUtils.getFileAsStream(node)) {
-                                               file.write(InputStream.class).complete(in);
-                                       }
-                               } else if (node.isNodeType(NodeType.NT_FOLDER)) {
-                                       Content subCol = collection.add(name, DName.collection.qName());
-                                       copyFiles(node, subCol, additionalCollectionTypes);
-                               } else {
-                                       List<QName> contentClasses = typesAsContentClasses(node, jcrNamespaceContext);
-                                       for (String collectionType : additionalCollectionTypes) {
-                                               if (node.isNodeType(collectionType)) {
-                                                       contentClasses.add(DName.collection.qName());
-                                                       Content subCol = collection.add(name,
-                                                                       contentClasses.toArray(new QName[contentClasses.size()]));
-                                                       setAttributes(node, subCol, jcrNamespaceContext);
-//                                                     setContentClasses(node, subCol, jcrNamespaceContext);
-                                                       copyFiles(node, subCol, additionalCollectionTypes);
-                                                       continue nodes;
-                                               }
-                                       }
-
-                                       QName qName = NamespaceUtils.parsePrefixedName(name);
-//                                     if (NamespaceUtils.hasNamespace(qName)) {
-                                       if (node.getIndex() > 1) {
-                                               log.warn("Same name siblings not supported, skipping " + node);
-                                               continue nodes;
-                                       }
-                                       Content content = collection.add(qName, contentClasses.toArray(new QName[contentClasses.size()]));
-                                       Source source = toSource(node);
-                                       ((ProvidedContent) content).getSession().edit((s) -> {
-                                               ((ProvidedSession) s).notifyModification((ProvidedContent) content);
-                                               content.write(Source.class).complete(source);
-//                                             try {
-//                                                     //setContentClasses(node, content, jcrNamespaceContext);
-//                                             } catch (RepositoryException e) {
-//                                                     // TODO Auto-generated catch block
-//                                                     e.printStackTrace();
-//                                             }
-                                       }).toCompletableFuture().join();
-                                       setAttributes(node, content, jcrNamespaceContext);
-
-//                                     } else {
-//                                             // ignore
-//                                             log.debug(() -> "Ignored " + node);
-//                                             continue nodes;
-//                                     }
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot copy files from " + folder + " to " + collection, e);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot copy files from " + folder + " to " + collection, e);
-               }
-       }
-
-       private static Source toSource(Node node) throws RepositoryException {
-
-//             try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
-//                     node.getSession().exportDocumentView(node.getPath(), out, true, false);
-//                     System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8));
-////                   DocumentBuilder documentBuilder = DocumentBuilderFactory.newNSInstance().newDocumentBuilder();
-////                   Document document;
-////                   try (ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray())) {
-////                           document = documentBuilder.parse(in);
-////                   }
-////                   cleanJcrDom(document);
-////                   return new DOMSource(document);
-//             } catch (IOException e) {
-//                     throw new RuntimeException(e);
-//             }
-
-               try (PipedInputStream in = new PipedInputStream();) {
-
-                       CompletableFuture<Document> toDo = CompletableFuture.supplyAsync(() -> {
-                               try {
-                                       DocumentBuilder documentBuilder = DocumentBuilderFactory.newNSInstance().newDocumentBuilder();
-                                       return documentBuilder.parse(in);
-                               } catch (ParserConfigurationException | SAXException | IOException e) {
-                                       throw new RuntimeException("Cannot parse", e);
-                               }
-                       });
-
-                       // TODO optimise
-                       try (PipedOutputStream out = new PipedOutputStream(in)) {
-                               node.getSession().exportDocumentView(node.getPath(), out, true, false);
-                       } catch (IOException | RepositoryException e) {
-                               throw new RuntimeException("Cannot export " + node + " in workspace " + Jcr.getWorkspaceName(node), e);
-                       }
-                       Document document = toDo.get();
-                       cleanJcrDom(document);
-                       return new DOMSource(document);
-               } catch (IOException | InterruptedException | ExecutionException e1) {
-                       throw new RuntimeException("Cannot parse", e1);
-               }
-
-       }
-
-       public static void setAttributes(Node source, Content target, NamespaceContext jcrNamespaceContext)
-                       throws RepositoryException {
-               properties: for (PropertyIterator pit = source.getProperties(); pit.hasNext();) {
-                       Property p = pit.nextProperty();
-                       // TODO migrate JCR title, last modified, etc. ?
-                       if (p.getName().startsWith("jcr:"))
-                               continue properties;
-                       if (p.isMultiple()) {
-                               List<String> attr = new ArrayList<>();
-                               for (Value value : p.getValues()) {
-                                       attr.add(value.getString());
-                               }
-                               target.put(NamespaceUtils.parsePrefixedName(jcrNamespaceContext, p.getName()), attr);
-                       } else {
-                               target.put(NamespaceUtils.parsePrefixedName(jcrNamespaceContext, p.getName()), p.getString());
-                       }
-               }
-       }
-
-       public static List<QName> typesAsContentClasses(Node source, NamespaceContext jcrNamespaceContext)
-                       throws RepositoryException {
-               // TODO super types?
-               List<QName> contentClasses = new ArrayList<>();
-               contentClasses
-                               .add(NamespaceUtils.parsePrefixedName(jcrNamespaceContext, source.getPrimaryNodeType().getName()));
-               for (NodeType nodeType : source.getMixinNodeTypes()) {
-                       contentClasses.add(NamespaceUtils.parsePrefixedName(jcrNamespaceContext, nodeType.getName()));
-               }
-               // filter out JCR types
-               for (Iterator<QName> it = contentClasses.iterator(); it.hasNext();) {
-                       QName type = it.next();
-                       if (type.getNamespaceURI().equals(JCR_NT_NAMESPACE_URI)
-                                       || type.getNamespaceURI().equals(JCR_MIX_NAMESPACE_URI)) {
-                               it.remove();
-                       }
-               }
-               // target.addContentClasses(contentClasses.toArray(new
-               // QName[contentClasses.size()]));
-               return contentClasses;
-       }
-
-       static final String JCR_NAMESPACE_URI = "http://www.jcp.org/jcr/1.0";
-       static final String JCR_NT_NAMESPACE_URI = "http://www.jcp.org/jcr/nt/1.0";
-       static final String JCR_MIX_NAMESPACE_URI = "http://www.jcp.org/jcr/mix/1.0";
-
-       public static void cleanJcrDom(Document document) {
-               Element documentElement = document.getDocumentElement();
-               Set<String> namespaceUris = new HashSet<>();
-               cleanJcrDom(documentElement, namespaceUris);
-
-               // remove unused namespaces
-               NamedNodeMap attrs = documentElement.getAttributes();
-               Set<Attr> toRemove = new HashSet<>();
-               for (int i = 0; i < attrs.getLength(); i++) {
-                       Attr attr = (Attr) attrs.item(i);
-//                     log.debug("Check "+i+" " + attr);
-                       String prefix = attr.getPrefix();
-                       if (prefix != null && prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
-                               String namespaceUri = attr.getValue();
-                               if (!namespaceUris.contains(namespaceUri)) {
-                                       toRemove.add(attr);
-                                       // log.debug("Removing "+i+" " + namespaceUri);
-                               }
-                       }
-               }
-               for (Attr attr : toRemove)
-                       documentElement.removeAttributeNode(attr);
-
-       }
-
-       private static void cleanJcrDom(Element element, Set<String> namespaceUris) {
-               NodeList children = element.getElementsByTagName("*");
-               for (int i = 0; i < children.getLength(); i++) {
-                       Element child = (Element) children.item(i);
-                       if (!namespaceUris.contains(child.getNamespaceURI()))
-                               namespaceUris.add(child.getNamespaceURI());
-                       cleanJcrDom(child, namespaceUris);
-               }
-
-               NamedNodeMap attrs = element.getAttributes();
-               attributes: for (int i = 0; i < attrs.getLength(); i++) {
-                       Attr attr = (Attr) attrs.item(i);
-                       String namespaceUri = attr.getNamespaceURI();
-                       if (namespaceUri == null)
-                               continue attributes;
-                       if (JCR_NAMESPACE_URI.equals(namespaceUri)) {
-                               // FIXME probably wrong to change attributes length
-                               element.removeAttributeNode(attr);
-                               continue attributes;
-                       }
-                       if (!namespaceUris.contains(namespaceUri))
-                               namespaceUris.add(attr.getNamespaceURI());
-
-               }
-
-       }
-
-       /** singleton */
-       private JcrContentUtils() {
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionAdapter.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionAdapter.java
deleted file mode 100644 (file)
index ae8ae80..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.argeo.cms.jcr.acr;
-
-import java.security.PrivilegedAction;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-
-import org.apache.jackrabbit.core.SessionImpl;
-import org.argeo.api.acr.spi.ProvidedSession;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-
-/** Manages JCR {@link Session} in an ACR context. */
-class JcrSessionAdapter {
-       private Repository repository;
-       private Subject subject;
-
-       private ProvidedSession contentSession;
-
-       private Map<Thread, Map<String, Session>> threadSessions = Collections.synchronizedMap(new HashMap<>());
-
-       private boolean closed = false;
-
-       private Thread lastRetrievingThread = null;
-
-       public JcrSessionAdapter(Repository repository, ProvidedSession contentSession, Subject subject) {
-               this.repository = repository;
-               this.contentSession = contentSession;
-               this.subject = subject;
-       }
-
-       public synchronized void close() {
-               for (Map<String, Session> sessions : threadSessions.values()) {
-                       for (Session session : sessions.values()) {
-                               JcrUtils.logoutQuietly(session);
-                       }
-                       sessions.clear();
-               }
-               threadSessions.clear();
-               closed = true;
-       }
-
-       public synchronized Session getSession(String workspace) {
-               if (closed)
-                       throw new IllegalStateException("JCR session adapter is closed.");
-
-               Thread currentThread = Thread.currentThread();
-               if (lastRetrievingThread == null)
-                       lastRetrievingThread = currentThread;
-
-               Map<String, Session> threadSession = threadSessions.get(currentThread);
-               if (threadSession == null) {
-                       threadSession = new HashMap<>();
-                       threadSessions.put(currentThread, threadSession);
-               }
-
-               Session session = threadSession.get(workspace);
-               if (session == null) {
-                       session = Subject.doAs(subject, (PrivilegedAction<Session>) () -> {
-                               try {
-//                                     String username = CurrentUser.getUsername(subject);
-//                                     SimpleCredentials credentials = new SimpleCredentials(username, new char[0]);
-//                                     credentials.setAttribute(ProvidedSession.class.getName(), contentSession);
-                                       Session sess = repository.login(workspace);
-                                       // Jackrabbit specific:
-                                       ((SessionImpl)sess).setAttribute(ProvidedSession.class.getName(), contentSession);
-                                       return sess;
-                               } catch (RepositoryException e) {
-                                       throw new IllegalStateException("Cannot log in to " + workspace, e);
-                               }
-                       });
-                       threadSession.put(workspace, session);
-               }
-
-               if (lastRetrievingThread != currentThread) {
-                       try {
-                               session.refresh(true);
-                       } catch (RepositoryException e) {
-                               throw new JcrException("Cannot refresh JCR session " + session, e);
-                       }
-               }
-               lastRetrievingThread = currentThread;
-               return session;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionNamespaceContext.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionNamespaceContext.java
deleted file mode 100644 (file)
index a55f4a3..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.argeo.cms.jcr.acr;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.xml.namespace.NamespaceContext;
-
-import org.argeo.jcr.JcrException;
-
-/** A {@link NamespaceContext} based on a JCR {@link Session}. */
-public class JcrSessionNamespaceContext implements NamespaceContext {
-       private final Session session;
-
-       public JcrSessionNamespaceContext(Session session) {
-               this.session = session;
-       }
-
-       @Override
-       public String getNamespaceURI(String prefix) {
-               try {
-                       return session.getNamespaceURI(prefix);
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-       @Override
-       public String getPrefix(String namespaceURI) {
-               try {
-                       return session.getNamespacePrefix(namespaceURI);
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-
-       @Override
-       public Iterator<String> getPrefixes(String namespaceURI) {
-               try {
-                       return Arrays.asList(session.getNamespacePrefix(namespaceURI)).iterator();
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/argeo.cnd b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/argeo.cnd
deleted file mode 100644 (file)
index c9e6ee7..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<argeo = 'http://www.argeo.org/ns/argeo'>
-
-// GENERIC TYPES
-[argeo:remoteRepository] > nt:unstructured
-- argeo:uri (STRING)
-- argeo:userID (STRING)
-+ argeo:password (argeo:encrypted)
-
-// TABULAR CONTENT
-[argeo:table] > nt:file
-+ * (argeo:column) *
-
-[argeo:column] > mix:title
-- jcr:requiredType (STRING) = 'STRING'
-
-[argeo:csv] > nt:resource
-
-// CRYPTO
-[argeo:encrypted]
-mixin
-// initialization vector used by some algorithms
-- argeo:iv (BINARY)
-
-[argeo:pbeKeySpec]
-mixin
-- argeo:secretKeyFactory (STRING)
-- argeo:salt (BINARY)
-- argeo:iterationCount (LONG)
-- argeo:keyLength (LONG)
-- argeo:secretKeyEncryption (STRING)
-
-[argeo:pbeSpec] > argeo:pbeKeySpec
-mixin
-- argeo:cipher (STRING)
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/dn.cnd b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/dn.cnd
deleted file mode 100644 (file)
index 80849be..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// DN (see https://tools.ietf.org/html/rfc4514)
-<cn = 'http://www.argeo.org/ns/rfc4514/cn'>
-<l = 'http://www.argeo.org/ns/rfc4514/l'>
-<st = 'http://www.argeo.org/ns/rfc4514/st'>
-<o = 'http://www.argeo.org/ns/rfc4514/o'>
-<ou = 'http://www.argeo.org/ns/rfc4514/ou'>
-<c = 'http://www.argeo.org/ns/rfc4514/c'>
-<street = 'http://www.argeo.org/ns/rfc4514/street'>
-<dc = 'http://www.argeo.org/ns/rfc4514/dc'>
-<uid = 'http://www.argeo.org/ns/rfc4514/uid'>
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java
deleted file mode 100644 (file)
index 35800f8..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import static org.argeo.cms.osgi.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
-import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.servlet.Servlet;
-
-import org.apache.jackrabbit.commons.cnd.CndImporter;
-import org.apache.jackrabbit.core.RepositoryContext;
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.ArgeoNames;
-import org.argeo.cms.jcr.CmsJcrUtils;
-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.jcr.Jcr;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
-import org.osgi.util.tracker.ServiceTracker;
-
-/** Implementation of a CMS deployment. */
-public class CmsJcrDeployment {
-       private final CmsLog log = CmsLog.getLog(getClass());
-       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-       private DataModels dataModels;
-       private String webDavConfig = JcrHttpUtils.WEBDAV_CONFIG;
-
-       private boolean argeoDataModelExtensionsAvailable = false;
-
-       // Readiness
-       private boolean nodeAvailable = false;
-
-//     CmsDeployment cmsDeployment;
-       public void start() {
-               dataModels = new DataModels(bc);
-
-               ServiceTracker<?, ?> repoContextSt = new RepositoryContextStc();
-               repoContextSt.open();
-               // KernelUtils.asyncOpen(repoContextSt);
-
-//             nodeDeployment = CmsJcrActivator.getService(NodeDeployment.class);
-
-               //JcrInitUtils.addToDeployment(cmsDeployment);
-
-//             contentRepository.registerTypes(NamespaceRegistry.PREFIX_JCR, NamespaceRegistry.NAMESPACE_JCR, null);
-//             contentRepository.registerTypes(NamespaceRegistry.PREFIX_MIX, NamespaceRegistry.NAMESPACE_MIX, null);
-//             contentRepository.registerTypes(NamespaceRegistry.PREFIX_NT, NamespaceRegistry.NAMESPACE_NT, null);
-//             // Jackrabbit
-//             // see
-//             // https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html
-//             contentRepository.registerTypes("rep", "internal", null);
-
-       }
-
-       public void stop() {
-//             if (nodeHttp != null)
-//                     nodeHttp.destroy();
-
-
-               try {
-                       for (ServiceReference<JackrabbitLocalRepository> sr : bc
-                                       .getServiceReferences(JackrabbitLocalRepository.class, null)) {
-                               bc.getService(sr).destroy();
-                       }
-               } catch (InvalidSyntaxException e1) {
-                       log.error("Cannot clean repositories", e1);
-               }
-
-       }
-
-//     public void setCmsDeployment(CmsDeployment cmsDeployment) {
-//             this.cmsDeployment = cmsDeployment;
-//     }
-
-       /**
-        * 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);
-//             }
-//     }
-
-       private void prepareNodeRepository(Repository deployedNodeRepository, List<String> publishAsLocalRepo) {
-//             if (availableSince != null) {
-//                     throw new IllegalStateException("Deployment is already available");
-//             }
-
-               // home
-               prepareDataModel(CmsConstants.NODE_REPOSITORY, deployedNodeRepository, publishAsLocalRepo);
-
-               // init from backup
-//             if (deployConfig.isFirstInit()) {
-//                     Path restorePath = Paths.get(System.getProperty("user.dir"), "restore");
-//                     if (Files.exists(restorePath)) {
-//                             if (log.isDebugEnabled())
-//                                     log.debug("Found backup " + restorePath + ", restoring it...");
-//                             LogicalRestore logicalRestore = new LogicalRestore(bc, deployedNodeRepository, restorePath);
-//                             KernelUtils.doAsDataAdmin(logicalRestore);
-//                             log.info("Restored backup from " + restorePath);
-//                     }
-//             }
-
-               // init from repository
-//             Collection<ServiceReference<Repository>> initRepositorySr;
-//             try {
-//                     initRepositorySr = bc.getServiceReferences(Repository.class,
-//                                     "(" + CmsConstants.CN + "=" + CmsConstants.NODE_INIT + ")");
-//             } catch (InvalidSyntaxException e1) {
-//                     throw new IllegalArgumentException(e1);
-//             }
-//             Iterator<ServiceReference<Repository>> it = initRepositorySr.iterator();
-//             while (it.hasNext()) {
-//                     ServiceReference<Repository> sr = it.next();
-//                     Object labeledUri = sr.getProperties().get(LdapAttrs.labeledURI.name());
-//                     Repository initRepository = bc.getService(sr);
-//                     if (log.isDebugEnabled())
-//                             log.debug("Found init repository " + labeledUri + ", copying it...");
-//                     initFromRepository(deployedNodeRepository, initRepository);
-//                     log.info("Node repository initialised from " + labeledUri);
-//             }
-       }
-
-       /** Init from a (typically remote) repository. */
-       private void initFromRepository(Repository deployedNodeRepository, Repository initRepository) {
-               Session initSession = null;
-               try {
-                       initSession = initRepository.login();
-                       workspaces: for (String workspaceName : initSession.getWorkspace().getAccessibleWorkspaceNames()) {
-                               if ("security".equals(workspaceName))
-                                       continue workspaces;
-                               if (log.isDebugEnabled())
-                                       log.debug("Copying workspace " + workspaceName + " from init repository...");
-                               long begin = System.currentTimeMillis();
-                               Session targetSession = null;
-                               Session sourceSession = null;
-                               try {
-                                       try {
-                                               targetSession = CmsJcrUtils.openDataAdminSession(deployedNodeRepository, workspaceName);
-                                       } catch (IllegalArgumentException e) {// no such workspace
-                                               Session adminSession = CmsJcrUtils.openDataAdminSession(deployedNodeRepository, null);
-                                               try {
-                                                       adminSession.getWorkspace().createWorkspace(workspaceName);
-                                               } finally {
-                                                       Jcr.logout(adminSession);
-                                               }
-                                               targetSession = CmsJcrUtils.openDataAdminSession(deployedNodeRepository, workspaceName);
-                                       }
-                                       sourceSession = initRepository.login(workspaceName);
-//                                     JcrUtils.copyWorkspaceXml(sourceSession, targetSession);
-                                       // TODO deal with referenceable nodes
-                                       JcrUtils.copy(sourceSession.getRootNode(), targetSession.getRootNode());
-                                       targetSession.save();
-                                       long duration = System.currentTimeMillis() - begin;
-                                       if (log.isDebugEnabled())
-                                               log.debug("Copied workspace " + workspaceName + " from init repository in " + (duration / 1000)
-                                                               + " s");
-                               } catch (Exception e) {
-                                       log.error("Cannot copy workspace " + workspaceName + " from init repository.", e);
-                               } finally {
-                                       Jcr.logout(sourceSession);
-                                       Jcr.logout(targetSession);
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               } finally {
-                       Jcr.logout(initSession);
-               }
-       }
-
-       private void prepareHomeRepository(RepositoryImpl deployedRepository) {
-               Session adminSession = KernelUtils.openAdminSession(deployedRepository);
-               try {
-                       argeoDataModelExtensionsAvailable = Arrays
-                                       .asList(adminSession.getWorkspace().getNamespaceRegistry().getURIs())
-                                       .contains(ArgeoNames.ARGEO_NAMESPACE);
-               } catch (RepositoryException e) {
-                       log.warn("Cannot check whether Argeo namespace is registered assuming it isn't.", e);
-                       argeoDataModelExtensionsAvailable = false;
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-
-               // Publish home with the highest service ranking
-               Hashtable<String, Object> regProps = new Hashtable<>();
-               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(CmsConstants.EGO_REPOSITORY, egoRepository);
-
-               // Keyring only if Argeo extensions are available
-//             if (argeoDataModelExtensionsAvailable) {
-//                     new ServiceTracker<CallbackHandler, CallbackHandler>(bc, CallbackHandler.class, null) {
-//
-//                             @Override
-//                             public CallbackHandler addingService(ServiceReference<CallbackHandler> reference) {
-//                                     NodeKeyRing nodeKeyring = new NodeKeyRing(egoRepository);
-//                                     CallbackHandler callbackHandler = bc.getService(reference);
-//                                     nodeKeyring.setDefaultCallbackHandler(callbackHandler);
-//                                     bc.registerService(LangUtils.names(Keyring.class, CryptoKeyring.class, ManagedService.class),
-//                                                     nodeKeyring, LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_KEYRING_PID));
-//                                     return callbackHandler;
-//                             }
-//
-//                     }.open();
-//             }
-       }
-
-       /** Session is logged out. */
-       private void prepareDataModel(String cn, Repository repository, List<String> publishAsLocalRepo) {
-               Session adminSession = KernelUtils.openAdminSession(repository);
-               try {
-                       Set<String> processed = new HashSet<String>();
-                       bundles: for (Bundle bundle : bc.getBundles()) {
-                               BundleWiring wiring = bundle.adapt(BundleWiring.class);
-                               if (wiring == null)
-                                       continue bundles;
-                               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);
-                                       for (BundleCapability capability : capabilities) {
-                                               String dataModelName = (String) capability.getAttributes().get(DataModelNamespace.NAME);
-                                               if (dataModelName.equals(cn))// process only own data model
-                                                       processWiring(cn, adminSession, wiring, processed, false, publishAsLocalRepo);
-                                       }
-                               }
-                       }
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-       }
-
-       private void processWiring(String cn, Session adminSession, BundleWiring wiring, Set<String> processed,
-                       boolean importListedAbstractModels, List<String> publishAsLocalRepo) {
-               // recursively process requirements first
-               List<BundleWire> requiredWires = wiring.getRequiredWires(CMS_DATA_MODEL_NAMESPACE);
-               for (BundleWire wire : requiredWires) {
-                       processWiring(cn, adminSession, wire.getProviderWiring(), processed, true, publishAsLocalRepo);
-               }
-
-               List<BundleCapability> capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
-               capabilities: for (BundleCapability capability : capabilities) {
-                       if (!importListedAbstractModels
-                                       && KernelUtils.asBoolean((String) capability.getAttributes().get(DataModelNamespace.ABSTRACT))) {
-                               continue capabilities;
-                       }
-                       boolean publish = registerDataModelCapability(cn, adminSession, capability, processed);
-                       if (publish)
-                               publishAsLocalRepo.add((String) capability.getAttributes().get(DataModelNamespace.NAME));
-               }
-       }
-
-       private boolean registerDataModelCapability(String cn, Session adminSession, BundleCapability capability,
-                       Set<String> processed) {
-               Map<String, Object> attrs = capability.getAttributes();
-               String name = (String) attrs.get(DataModelNamespace.NAME);
-               if (processed.contains(name)) {
-                       if (log.isTraceEnabled())
-                               log.trace("Data model " + name + " has already been processed");
-                       return false;
-               }
-
-               // CND
-               String path = (String) attrs.get(DataModelNamespace.CND);
-               if (path != null) {
-                       File dataModel = bc.getBundle().getDataFile("dataModels/" + path);
-                       if (!dataModel.exists()) {
-                               URL url = capability.getRevision().getBundle().getResource(path);
-                               if (url == null)
-                                       throw new IllegalArgumentException("No data model '" + name + "' found under path " + path);
-                               try (Reader reader = new InputStreamReader(url.openStream())) {
-                                       CndImporter.registerNodeTypes(reader, adminSession, true);
-                                       processed.add(name);
-                                       dataModel.getParentFile().mkdirs();
-                                       dataModel.createNewFile();
-                                       if (log.isDebugEnabled())
-                                               log.debug("Registered CND " + url);
-                               } catch (Exception e) {
-                                       log.error("Cannot import CND " + url, e);
-                               }
-                       }
-               }
-
-               if (KernelUtils.asBoolean((String) attrs.get(DataModelNamespace.ABSTRACT)))
-                       return false;
-               // Non abstract
-               boolean isStandalone = isStandalone(name);
-               boolean publishLocalRepo;
-               if (isStandalone && name.equals(cn))// includes the node itself
-                       publishLocalRepo = true;
-               else if (!isStandalone && cn.equals(CmsConstants.NODE_REPOSITORY))
-                       publishLocalRepo = true;
-               else
-                       publishLocalRepo = false;
-
-               return publishLocalRepo;
-       }
-
-       boolean isStandalone(String dataModelName) {
-               return true;
-               //return cmsDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null;
-       }
-
-       private void publishLocalRepo(String dataModelName, Repository repository) {
-               Hashtable<String, Object> properties = new Hashtable<>();
-               properties.put(CmsConstants.CN, dataModelName);
-               LocalRepository localRepository;
-               String[] classes;
-               if (repository instanceof RepositoryImpl) {
-                       localRepository = new JackrabbitLocalRepository((RepositoryImpl) repository, dataModelName);
-                       classes = new String[] { Repository.class.getName(), LocalRepository.class.getName(),
-                                       JackrabbitLocalRepository.class.getName() };
-               } else {
-                       localRepository = new LocalRepository(repository, dataModelName);
-                       classes = new String[] { Repository.class.getName(), LocalRepository.class.getName() };
-               }
-               bc.registerService(classes, localRepository, properties);
-
-               // TODO make it configurable
-               registerRepositoryServlets(dataModelName, localRepository);
-               if (log.isTraceEnabled())
-                       log.trace("Published data model " + dataModelName);
-       }
-
-//     @Override
-//     public synchronized Long getAvailableSince() {
-//             return availableSince;
-//     }
-//
-//     public synchronized boolean isAvailable() {
-//             return availableSince != null;
-//     }
-
-       protected void registerRepositoryServlets(String alias, Repository repository) {
-               registerRemotingServlet(alias, repository);
-               registerWebdavServlet(alias, repository);
-       }
-
-       protected void registerWebdavServlet(String alias, Repository repository) {
-               CmsWebDavServlet webdavServlet = new CmsWebDavServlet(alias, repository);
-               Hashtable<String, String> ip = new Hashtable<>();
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsWebDavServlet.INIT_PARAM_RESOURCE_CONFIG, webDavConfig);
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsWebDavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
-                               "/" + alias);
-
-               ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/" + alias + "/*");
-               ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
-                               "(" + 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(CmsConstants.CN, alias);
-               // Properties ip = new Properties();
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
-                               "/" + alias);
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_AUTHENTICATE_HEADER,
-                               "Negotiate");
-
-               // Looks like a bug in Jackrabbit remoting init
-               Path tmpDir;
-               try {
-                       tmpDir = Files.createTempDirectory("remoting_" + alias);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot create temp directory for remoting servlet", e);
-               }
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_HOME, tmpDir.toString());
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_TMP_DIRECTORY,
-                               "remoting_" + alias);
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_PROTECTED_HANDLERS_CONFIG,
-                               JcrHttpUtils.DEFAULT_PROTECTED_HANDLERS);
-               ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_CREATE_ABSOLUTE_URI, "false");
-
-               ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/" + alias + "/*");
-               ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
-                               "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + CmsConstants.PATH_JCR + ")");
-               bc.registerService(Servlet.class, remotingServlet, ip);
-       }
-
-       private class RepositoryContextStc extends ServiceTracker<RepositoryContext, RepositoryContext> {
-
-               public RepositoryContextStc() {
-                       super(bc, RepositoryContext.class, null);
-               }
-
-               @Override
-               public RepositoryContext addingService(ServiceReference<RepositoryContext> reference) {
-                       RepositoryContext repoContext = bc.getService(reference);
-                       String cn = (String) reference.getProperty(CmsConstants.CN);
-                       if (cn != null) {
-                               List<String> publishAsLocalRepo = new ArrayList<>();
-                               if (cn.equals(CmsConstants.NODE_REPOSITORY)) {
-//                                     JackrabbitDataModelMigration.clearRepositoryCaches(repoContext.getRepositoryConfig());
-                                       prepareNodeRepository(repoContext.getRepository(), publishAsLocalRepo);
-                                       // TODO separate home repository
-                                       prepareHomeRepository(repoContext.getRepository());
-                                       registerRepositoryServlets(cn, repoContext.getRepository());
-                                       nodeAvailable = true;
-//                                     checkReadiness();
-                               } else {
-                                       prepareDataModel(cn, repoContext.getRepository(), publishAsLocalRepo);
-                               }
-                               // Publish all at once, so that bundles with multiple CNDs are consistent
-                               for (String dataModelName : publishAsLocalRepo)
-                                       publishLocalRepo(dataModelName, repoContext.getRepository());
-                       }
-                       return repoContext;
-               }
-
-               @Override
-               public void modifiedService(ServiceReference<RepositoryContext> reference, RepositoryContext service) {
-               }
-
-               @Override
-               public void removedService(ServiceReference<RepositoryContext> reference, RepositoryContext service) {
-               }
-
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrFsProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrFsProvider.java
deleted file mode 100644 (file)
index 0099b3b..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystemAlreadyExistsException;
-import java.nio.file.Path;
-import java.nio.file.spi.FileSystemProvider;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider;
-import org.argeo.jcr.fs.JcrFileSystem;
-import org.argeo.jcr.fs.JcrFileSystemProvider;
-import org.argeo.jcr.fs.JcrFsException;
-
-/** Implementation of an {@link FileSystemProvider} based on Jackrabbit. */
-public class CmsJcrFsProvider extends AbstractJackrabbitFsProvider {
-       private Map<String, CmsFileSystem> fileSystems = new HashMap<>();
-
-       private RepositoryFactory repositoryFactory;
-       private Repository repository;
-
-       @Override
-       public String getScheme() {
-               return CmsConstants.SCHEME_NODE;
-       }
-
-       @Override
-       public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
-//             BundleContext bc = FrameworkUtil.getBundle(CmsJcrFsProvider.class).getBundleContext();
-               String username = CurrentUser.getUsername();
-               if (username == null) {
-                       // TODO deal with anonymous
-                       return null;
-               }
-               if (fileSystems.containsKey(username))
-                       throw new FileSystemAlreadyExistsException("CMS file system already exists for user " + username);
-
-               try {
-                       String host = uri.getHost();
-                       if (host != null && !host.trim().equals("")) {
-                               URI repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), "/jcr/node", null, null);
-//                             RepositoryFactory repositoryFactory = bc.getService(bc.getServiceReference(RepositoryFactory.class));
-                               Repository repository = CmsJcrUtils.getRepositoryByUri(repositoryFactory, repoUri.toString());
-                               CmsFileSystem fileSystem = new CmsFileSystem(this, repository);
-                               fileSystems.put(username, fileSystem);
-                               return fileSystem;
-                       } else {
-//                             Repository repository = bc.getService(
-//                                             bc.getServiceReferences(Repository.class, "(cn=" + CmsConstants.EGO_REPOSITORY + ")")
-//                                                             .iterator().next());
-
-                               // Session session = repository.login();
-                               CmsFileSystem fileSystem = new CmsFileSystem(this, repository);
-                               fileSystems.put(username, fileSystem);
-                               return fileSystem;
-                       }
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException("Cannot open file system " + uri + " for user " + username, e);
-               }
-       }
-
-       @Override
-       public FileSystem getFileSystem(URI uri) {
-               return currentUserFileSystem();
-       }
-
-       @Override
-       public Path getPath(URI uri) {
-               JcrFileSystem fileSystem = currentUserFileSystem();
-               String path = uri.getPath();
-               if (fileSystem == null)
-                       try {
-                               fileSystem = (JcrFileSystem) newFileSystem(uri, new HashMap<String, Object>());
-                       } catch (IOException e) {
-                               throw new JcrFsException("Could not autocreate file system", e);
-                       }
-               return fileSystem.getPath(path);
-       }
-
-       protected JcrFileSystem currentUserFileSystem() {
-               String username = CurrentUser.getUsername();
-               return fileSystems.get(username);
-       }
-
-       public Node getUserHome(Repository repository) {
-               try {
-                       Session session = repository.login(CmsConstants.HOME_WORKSPACE);
-                       return CmsJcrUtils.getUserHome(session);
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Cannot get user home", e);
-               }
-       }
-
-       public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
-               this.repositoryFactory = repositoryFactory;
-       }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       static class CmsFileSystem extends JcrFileSystem {
-               public CmsFileSystem(JcrFileSystemProvider provider, Repository repository) throws IOException {
-                       super(provider, repository);
-               }
-
-               public boolean skipNode(Node node) throws RepositoryException {
-//                     if (node.isNodeType(NodeType.NT_HIERARCHY_NODE) || node.isNodeType(NodeTypes.NODE_USER_HOME)
-//                                     || node.isNodeType(NodeTypes.NODE_GROUP_HOME))
-                       if (node.isNodeType(NodeType.NT_HIERARCHY_NODE))
-                               return false;
-                       // FIXME Better identifies home
-                       if (node.hasProperty(Property.JCR_ID))
-                               return false;
-                       return true;
-               }
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsPaths.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsPaths.java
deleted file mode 100644 (file)
index 090ec67..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.nio.file.Path;
-
-/** Centralises access to the default node deployment directories. */
-@Deprecated
-public class CmsPaths {
-       public static Path getRepoDirPath(String cn) {
-               return KernelUtils.getOsgiInstancePath(KernelConstants.DIR_REPOS + '/' + cn);
-       }
-
-       public static Path getRepoIndexesBase() {
-               return KernelUtils.getOsgiInstancePath(KernelConstants.DIR_INDEXES);
-       }
-
-       /** Singleton. */
-       private CmsPaths() {
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java
deleted file mode 100644 (file)
index 69b98dc..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.util.GregorianCalendar;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventIterator;
-import javax.jcr.observation.EventListener;
-import javax.jcr.version.VersionManager;
-
-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 CmsLog log = CmsLog.getLog(CmsWorkspaceIndexer.class);
-
-//     private final static String MIX_ETAG = "mix:etag";
-       private final static String JCR_ETAG = "jcr:etag";
-//     private final static String JCR_LAST_MODIFIED = "jcr:lastModified";
-//     private final static String JCR_LAST_MODIFIED_BY = "jcr:lastModifiedBy";
-//     private final static String JCR_MIXIN_TYPES = "jcr:mixinTypes";
-       private final static String JCR_DATA = "jcr:data";
-       private final static String JCR_CONTENT = "jcr:data";
-
-       private String cn;
-       private String workspaceName;
-       private RepositoryImpl repositoryImpl;
-       private Session session;
-       private VersionManager versionManager;
-
-       private LinkedBlockingDeque<Event> toProcess = new LinkedBlockingDeque<>();
-       private IndexingThread indexingThread;
-       private AtomicBoolean stopping = new AtomicBoolean(false);
-
-       public CmsWorkspaceIndexer(RepositoryImpl repositoryImpl, String cn, String workspaceName)
-                       throws RepositoryException {
-               this.cn = cn;
-               this.workspaceName = workspaceName;
-               this.repositoryImpl = repositoryImpl;
-       }
-
-       public void init() {
-               session = KernelUtils.openAdminSession(repositoryImpl, workspaceName);
-               try {
-                       String[] nodeTypes = { NodeType.NT_FILE, NodeType.MIX_LAST_MODIFIED };
-                       session.getWorkspace().getObservationManager().addEventListener(this,
-                                       Event.NODE_ADDED | Event.PROPERTY_CHANGED, "/", true, null, nodeTypes, true);
-                       versionManager = session.getWorkspace().getVersionManager();
-
-                       indexingThread = new IndexingThread();
-                       indexingThread.start();
-               } catch (RepositoryException e1) {
-                       throw new IllegalStateException(e1);
-               }
-       }
-
-       public void destroy() {
-               stopping.set(true);
-               indexingThread.interrupt();
-               // TODO make it configurable
-               try {
-                       indexingThread.join(10 * 60 * 1000);
-               } catch (InterruptedException e1) {
-                       log.warn("Indexing thread interrupted. Will log out session.");
-               }
-
-               try {
-                       session.getWorkspace().getObservationManager().removeEventListener(this);
-               } catch (RepositoryException e) {
-                       if (log.isTraceEnabled())
-                               log.warn("Cannot unregistered JCR event listener", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       private synchronized void processEvents(EventIterator events) {
-               long begin = System.currentTimeMillis();
-               long count = 0;
-               while (events.hasNext()) {
-                       Event event = events.nextEvent();
-                       try {
-                               toProcess.put(event);
-                       } catch (InterruptedException e) {
-                               e.printStackTrace();
-                       }
-//                     processEvent(event);
-                       count++;
-               }
-               long duration = System.currentTimeMillis() - begin;
-               if (log.isTraceEnabled())
-                       log.trace("Processed " + count + " events in " + duration + " ms");
-               notifyAll();
-       }
-
-       protected synchronized void processEvent(Event event) {
-               try {
-                       String eventPath = event.getPath();
-                       if (event.getType() == Event.NODE_ADDED) {
-                               if (!versionManager.isCheckedOut(eventPath))
-                                       return;// ignore checked-in nodes
-                               if (log.isTraceEnabled())
-                                       log.trace("NODE_ADDED " + eventPath);
-//                             session.refresh(true);
-                               session.refresh(false);
-                               Node node = session.getNode(eventPath);
-                               Node parentNode = node.getParent();
-                               if (parentNode.isNodeType(NodeType.NT_FILE)) {
-                                       if (node.isNodeType(NodeType.NT_UNSTRUCTURED)) {
-                                               if (!node.isNodeType(NodeType.MIX_LAST_MODIFIED))
-                                                       node.addMixin(NodeType.MIX_LAST_MODIFIED);
-                                               Property property = node.getProperty(Property.JCR_DATA);
-                                               String etag = toEtag(property.getValue());
-                                               session.save();
-                                               node.setProperty(JCR_ETAG, etag);
-                                               if (log.isTraceEnabled())
-                                                       log.trace("ETag and last modified added to new " + node);
-                                       } else if (node.isNodeType(NodeType.NT_RESOURCE)) {
-//                                             if (!node.isNodeType(MIX_ETAG))
-//                                                     node.addMixin(MIX_ETAG);
-//                                             session.save();
-//                                             Property property = node.getProperty(Property.JCR_DATA);
-//                                             String etag = toEtag(property.getValue());
-//                                             node.setProperty(JCR_ETAG, etag);
-//                                             session.save();
-                                       }
-//                                     setLastModifiedRecursive(parentNode, event);
-//                                     session.save();
-//                                     if (log.isTraceEnabled())
-//                                             log.trace("ETag and last modified added to new " + node);
-                               }
-
-//                             if (node.isNodeType(NodeType.NT_FOLDER)) {
-//                                     setLastModifiedRecursive(node, event);
-//                                     session.save();
-//                                     if (log.isTraceEnabled())
-//                                             log.trace("Last modified added to new " + node);
-//                             }
-                       } else if (event.getType() == Event.PROPERTY_CHANGED) {
-                               String propertyName = extractItemName(eventPath);
-                               // skip if last modified properties are explicitly set
-                               if (!propertyName.equals(JCR_DATA))
-                                       return;
-//                             if (propertyName.equals(JCR_LAST_MODIFIED))
-//                                     return;
-//                             if (propertyName.equals(JCR_LAST_MODIFIED_BY))
-//                                     return;
-//                             if (propertyName.equals(JCR_MIXIN_TYPES))
-//                                     return;
-//                             if (propertyName.equals(JCR_ETAG))
-//                                     return;
-
-                               if (log.isTraceEnabled())
-                                       log.trace("PROPERTY_CHANGED " + eventPath);
-
-                               if (!session.propertyExists(eventPath))
-                                       return;
-                               session.refresh(false);
-                               Property property = session.getProperty(eventPath);
-                               Node node = property.getParent();
-                               if (property.getType() == PropertyType.BINARY && propertyName.equals(JCR_DATA)
-                                               && node.isNodeType(NodeType.NT_UNSTRUCTURED)) {
-                                       String etag = toEtag(property.getValue());
-                                       node.setProperty(JCR_ETAG, etag);
-                                       Node parentNode = node.getParent();
-                                       if (parentNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
-                                               setLastModified(parentNode, event);
-                                       }
-                                       if (log.isTraceEnabled())
-                                               log.trace("ETag and last modified updated for " + node);
-                               }
-//                             setLastModified(node, event);
-//                             session.save();
-//                             if (log.isTraceEnabled())
-//                                     log.trace("ETag and last modified updated for " + node);
-                       } else if (event.getType() == Event.NODE_REMOVED) {
-                               String removeNodePath = eventPath;
-                               String nodeName = extractItemName(eventPath);
-                               if (JCR_CONTENT.equals(nodeName)) // parent is a file, deleted anyhow
-                                       return;
-                               if (log.isTraceEnabled())
-                                       log.trace("NODE_REMOVED " + eventPath);
-//                             String parentPath = JcrUtils.parentPath(removeNodePath);
-//                             session.refresh(true);
-//                             setLastModified(parentPath, event);
-//                             session.save();
-                               if (log.isTraceEnabled())
-                                       log.trace("Last modified updated for parents of removed " + removeNodePath);
-                       }
-               } catch (Exception e) {
-                       if (log.isTraceEnabled())
-                               log.warn("Cannot process event " + event, e);
-               } finally {
-//                     try {
-//                             session.refresh(true);
-//                             if (session.hasPendingChanges())
-//                                     session.save();
-////                           session.refresh(false);
-//                     } catch (RepositoryException e) {
-//                             if (log.isTraceEnabled())
-//                                     log.warn("Cannot refresh JCR session", e);
-//                     }
-               }
-
-       }
-
-       private String extractItemName(String path) {
-               if (path == null || path.length() <= 1)
-                       return null;
-               int lastIndex = path.lastIndexOf('/');
-               if (lastIndex >= 0) {
-                       return path.substring(lastIndex + 1);
-               } else {
-                       return path;
-               }
-       }
-
-       @Override
-       public void onEvent(EventIterator events) {
-               processEvents(events);
-//             Runnable toRun = new Runnable() {
-//
-//                     @Override
-//                     public void run() {
-//                             processEvents(events);
-//                     }
-//             };
-//             Future<?> future = Activator.getInternalExecutorService().submit(toRun);
-//             try {
-//                     // make the call synchronous
-//                     future.get(60, TimeUnit.SECONDS);
-//             } catch (TimeoutException | ExecutionException | InterruptedException e) {
-//                     // silent
-//             }
-       }
-
-       static String toEtag(Value v) {
-               if (v instanceof JackrabbitValue) {
-                       JackrabbitValue value = (JackrabbitValue) v;
-                       return '\"' + value.getContentIdentity() + '\"';
-               } else {
-                       return null;
-               }
-
-       }
-
-       protected synchronized void setLastModified(Node node, Event event) throws RepositoryException {
-               GregorianCalendar calendar = new GregorianCalendar();
-               calendar.setTimeInMillis(event.getDate());
-               node.setProperty(Property.JCR_LAST_MODIFIED, calendar);
-               node.setProperty(Property.JCR_LAST_MODIFIED_BY, event.getUserID());
-               if (log.isTraceEnabled())
-                       log.trace("Last modified set on " + node);
-       }
-
-       /** Recursively set the last updated time on parents. */
-       protected synchronized void setLastModifiedRecursive(Node node, Event event) throws RepositoryException {
-               if (versionManager.isCheckedOut(node.getPath())) {
-                       if (node.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
-                               setLastModified(node, event);
-                       }
-                       if (node.isNodeType(NodeType.NT_FOLDER) && !node.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
-                               node.addMixin(NodeType.MIX_LAST_MODIFIED);
-                               if (log.isTraceEnabled())
-                                       log.trace("Last modified mix-in added to " + node);
-                       }
-
-               }
-
-               // end condition
-               if (node.getDepth() == 0) {
-//                     try {
-//                             node.getSession().save();
-//                     } catch (RepositoryException e) {
-//                             log.warn("Cannot index workspace", e);
-//                     }
-                       return;
-               } else {
-                       Node parent = node.getParent();
-                       setLastModifiedRecursive(parent, event);
-               }
-       }
-
-       /**
-        * Recursively set the last updated time on parents. Useful to use paths when
-        * dealing with deletions.
-        */
-       protected synchronized void setLastModifiedRecursive(String path, Event event) throws RepositoryException {
-               // root node will always exist, so end condition is delegated to the other
-               // recursive setLastModified method
-               if (session.nodeExists(path)) {
-                       setLastModifiedRecursive(session.getNode(path), event);
-               } else {
-                       setLastModifiedRecursive(JcrUtils.parentPath(path), event);
-               }
-       }
-
-       @Override
-       public String toString() {
-               return "Indexer for workspace " + workspaceName + " of repository " + cn;
-       }
-
-       class IndexingThread extends Thread {
-
-               public IndexingThread() {
-                       super(CmsWorkspaceIndexer.this.toString());
-                       // TODO Auto-generated constructor stub
-               }
-
-               @Override
-               public void run() {
-                       life: while (session != null && session.isLive()) {
-                               try {
-                                       Event nextEvent = toProcess.take();
-                                       processEvent(nextEvent);
-                               } catch (InterruptedException e) {
-                                       // silent
-                                       interrupted();
-                               }
-
-                               if (stopping.get() && toProcess.isEmpty()) {
-                                       break life;
-                               }
-                       }
-                       if (log.isDebugEnabled())
-                               log.debug(CmsWorkspaceIndexer.this.toString() + " has shut down.");
-               }
-
-       }
-
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java
deleted file mode 100644 (file)
index f2196bd..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import static org.argeo.cms.osgi.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.osgi.DataModelNamespace;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-class DataModels implements BundleListener {
-       private final static CmsLog log = CmsLog.getLog(DataModels.class);
-
-       private Map<String, DataModel> dataModels = new TreeMap<>();
-
-       public DataModels(BundleContext bc) {
-               for (Bundle bundle : bc.getBundles())
-                       processBundle(bundle, null);
-               bc.addBundleListener(this);
-       }
-
-       public List<DataModel> getNonAbstractDataModels() {
-               List<DataModel> res = new ArrayList<>();
-               for (String name : dataModels.keySet()) {
-                       DataModel dataModel = dataModels.get(name);
-                       if (!dataModel.isAbstract())
-                               res.add(dataModel);
-               }
-               // TODO reorder?
-               return res;
-       }
-
-       @Override
-       public void bundleChanged(BundleEvent event) {
-               if (event.getType() == Bundle.RESOLVED) {
-                       processBundle(event.getBundle(), null);
-               } else if (event.getType() == Bundle.UNINSTALLED) {
-                       BundleWiring wiring = event.getBundle().adapt(BundleWiring.class);
-                       List<BundleCapability> providedDataModels = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
-                       if (providedDataModels.size() == 0)
-                               return;
-                       for (BundleCapability bundleCapability : providedDataModels) {
-                               dataModels.remove(bundleCapability.getAttributes().get(DataModelNamespace.NAME));
-                       }
-               }
-
-       }
-
-       protected void processBundle(Bundle bundle, List<Bundle> scannedBundles) {
-               if (scannedBundles != null && scannedBundles.contains(bundle))
-                       throw new IllegalStateException("Cycle in CMS data model requirements for " + bundle);
-               BundleWiring wiring = bundle.adapt(BundleWiring.class);
-               if (wiring == null) {
-                       int bundleState = bundle.getState();
-                       if (bundleState != Bundle.INSTALLED && bundleState != Bundle.UNINSTALLED) {// ignore unresolved bundles
-                               log.warn("Bundle " + bundle.getSymbolicName() + " #" + bundle.getBundleId() + " ("
-                                               + bundle.getLocation() + ") cannot be adapted to a wiring");
-                       } else {
-                               if (log.isTraceEnabled())
-                                       log.warn("Bundle " + bundle.getSymbolicName() + " is not resolved.");
-                       }
-                       return;
-               }
-               List<BundleCapability> providedDataModels = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
-               if (providedDataModels.size() == 0)
-                       return;
-               List<BundleWire> requiredDataModels = wiring.getRequiredWires(CMS_DATA_MODEL_NAMESPACE);
-               // process requirements first
-               for (BundleWire bundleWire : requiredDataModels) {
-                       List<Bundle> nextScannedBundles = new ArrayList<>();
-                       if (scannedBundles != null)
-                               nextScannedBundles.addAll(scannedBundles);
-                       nextScannedBundles.add(bundle);
-                       Bundle providerBundle = bundleWire.getProvider().getBundle();
-                       processBundle(providerBundle, nextScannedBundles);
-               }
-               for (BundleCapability bundleCapability : providedDataModels) {
-                       String name = (String) bundleCapability.getAttributes().get(DataModelNamespace.NAME);
-                       assert name != null;
-                       if (!dataModels.containsKey(name)) {
-                               DataModel dataModel = new DataModel(name, bundleCapability, requiredDataModels);
-                               dataModels.put(dataModel.getName(), dataModel);
-                       }
-               }
-       }
-
-       /** Return a negative depth if dataModel is required by ref, 0 otherwise. */
-       static int required(DataModel ref, DataModel dataModel, int depth) {
-               for (DataModel dm : ref.getRequired()) {
-                       if (dm.equals(dataModel))// found here
-                               return depth - 1;
-                       int d = required(dm, dataModel, depth - 1);
-                       if (d != 0)// found deeper
-                               return d;
-               }
-               return 0;// not found
-       }
-
-       class DataModel {
-               private final String name;
-               private final boolean abstrct;
-               // private final boolean standalone;
-               private final String cnd;
-               private final List<DataModel> required;
-
-               private DataModel(String name, BundleCapability bundleCapability, List<BundleWire> requiredDataModels) {
-                       assert CMS_DATA_MODEL_NAMESPACE.equals(bundleCapability.getNamespace());
-                       this.name = name;
-                       Map<String, Object> attrs = bundleCapability.getAttributes();
-                       abstrct = KernelUtils.asBoolean((String) attrs.get(DataModelNamespace.ABSTRACT));
-                       // standalone = KernelUtils.asBoolean((String)
-                       // attrs.get(DataModelNamespace.CAPABILITY_STANDALONE_ATTRIBUTE));
-                       cnd = (String) attrs.get(DataModelNamespace.CND);
-                       List<DataModel> req = new ArrayList<>();
-                       for (BundleWire wire : requiredDataModels) {
-                               String requiredDataModelName = (String) wire.getCapability().getAttributes()
-                                               .get(DataModelNamespace.NAME);
-                               assert requiredDataModelName != null;
-                               DataModel requiredDataModel = dataModels.get(requiredDataModelName);
-                               if (requiredDataModel == null)
-                                       throw new IllegalStateException("No required data model " + requiredDataModelName);
-                               req.add(requiredDataModel);
-                       }
-                       required = Collections.unmodifiableList(req);
-               }
-
-               public String getName() {
-                       return name;
-               }
-
-               public boolean isAbstract() {
-                       return abstrct;
-               }
-
-               // public boolean isStandalone() {
-               // return !isAbstract();
-               // }
-
-               public String getCnd() {
-                       return cnd;
-               }
-
-               public List<DataModel> getRequired() {
-                       return required;
-               }
-
-               // @Override
-               // public int compareTo(DataModel o) {
-               // if (equals(o))
-               // return 0;
-               // int res = required(this, o, 0);
-               // if (res != 0)
-               // return res;
-               // // the other way round
-               // res = required(o, this, 0);
-               // if (res != 0)
-               // return -res;
-               // return 0;
-               // }
-
-               @Override
-               public int hashCode() {
-                       return name.hashCode();
-               }
-
-               @Override
-               public boolean equals(Object obj) {
-                       if (obj instanceof DataModel)
-                               return ((DataModel) obj).name.equals(name);
-                       return false;
-               }
-
-               @Override
-               public String toString() {
-                       return "Data model " + name;
-               }
-
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java
deleted file mode 100644 (file)
index ef785f9..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.security.PrivilegedAction;
-import java.text.SimpleDateFormat;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.security.Privilege;
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-
-import org.argeo.api.cms.CmsAuth;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrRepositoryWrapper;
-import org.argeo.jcr.JcrUtils;
-
-/**
- * Make sure each user has a home directory available.
- */
-class EgoRepository extends JcrRepositoryWrapper {
-
-       /** The home base path. */
-//     private String homeBasePath = KernelConstants.DEFAULT_HOME_BASE_PATH;
-//     private String usersBasePath = KernelConstants.DEFAULT_USERS_BASE_PATH;
-//     private String groupsBasePath = KernelConstants.DEFAULT_GROUPS_BASE_PATH;
-
-       private Set<String> checkedUsers = new HashSet<String>();
-
-       private SimpleDateFormat usersDatePath = new SimpleDateFormat("YYYY/MM");
-
-       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(CmsConstants.CN, CmsConstants.EGO_REPOSITORY);
-               if (!remote) {
-                       LoginContext lc;
-                       try {
-                               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);
-                       }
-                       Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
-
-                               @Override
-                               public Void run() {
-                                       loginOrCreateWorkspace(defaultHomeWorkspace);
-                                       loginOrCreateWorkspace(defaultGroupsWorkspace);
-                                       return null;
-                               }
-
-                       });
-               }
-       }
-
-       private void loginOrCreateWorkspace(String workspace) {
-               Session adminSession = null;
-               try {
-                       adminSession = JcrUtils.loginOrCreateWorkspace(getRepository(workspace), workspace);
-//                     JcrUtils.addPrivilege(adminSession, "/", NodeConstants.ROLE_USER, Privilege.JCR_READ);
-
-//                     initJcr(adminSession);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot init JCR home", e);
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-       }
-
-//     @Override
-//     public Session login(Credentials credentials, String workspaceName)
-//                     throws LoginException, NoSuchWorkspaceException, RepositoryException {
-//             if (workspaceName == null) {
-//                     return super.login(credentials, getUserHomeWorkspace());
-//             } else {
-//                     return super.login(credentials, workspaceName);
-//             }
-//     }
-
-       protected String getUserHomeWorkspace() {
-               // TODO base on JAAS Subject metadata
-               return defaultHomeWorkspace;
-       }
-
-       protected String getGroupsWorkspace() {
-               // TODO base on JAAS Subject metadata
-               return defaultGroupsWorkspace;
-       }
-
-//     protected String getGuestsWorkspace() {
-//             // TODO base on JAAS Subject metadata
-//             return defaultGuestsWorkspace;
-//     }
-
-       @Override
-       protected void processNewSession(Session session, String workspaceName) {
-               String username = session.getUserID();
-               if (username == null || username.toString().equals(""))
-                       return;
-               if (session.getUserID().equals(CmsConstants.ROLE_ANONYMOUS))
-                       return;
-
-               String userHomeWorkspace = getUserHomeWorkspace();
-               if (workspaceName == null || !workspaceName.equals(userHomeWorkspace))
-                       return;
-
-               if (checkedUsers.contains(username))
-                       return;
-               Session adminSession = KernelUtils.openAdminSession(getRepository(workspaceName), workspaceName);
-               try {
-                       syncJcr(adminSession, username);
-                       checkedUsers.add(username);
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-       }
-
-       /*
-        * JCR
-        */
-       /** Session is logged out. */
-       private void initJcr(Session adminSession) {
-               try {
-//                     JcrUtils.mkdirs(adminSession, homeBasePath);
-//                     JcrUtils.mkdirs(adminSession, groupsBasePath);
-                       adminSession.save();
-
-//                     JcrUtils.addPrivilege(adminSession, homeBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
-//                     JcrUtils.addPrivilege(adminSession, groupsBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
-                       adminSession.save();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot initialize home repository", e);
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-       }
-
-       protected synchronized void syncJcr(Session adminSession, String username) {
-               // only in the default workspace
-//             if (workspaceName != null)
-//                     return;
-               // skip system users
-               if (username.endsWith(CmsConstants.SYSTEM_ROLES_BASEDN))
-                       return;
-
-               try {
-                       Node userHome = CmsJcrUtils.getUserHome(adminSession, username);
-                       if (userHome == null) {
-//                             String homePath = generateUserPath(username);
-                               String userId = extractUserId(username);
-//                             if (adminSession.itemExists(homePath))// duplicate user id
-//                                     userHome = adminSession.getNode(homePath).getParent().addNode(JcrUtils.lastPathElement(homePath));
-//                             else
-//                                     userHome = JcrUtils.mkdirs(adminSession, homePath);
-                               userHome = adminSession.getRootNode().addNode(userId);
-//                             userHome.addMixin(NodeTypes.NODE_USER_HOME);
-                               userHome.addMixin(NodeType.MIX_CREATED);
-                               userHome.addMixin(NodeType.MIX_TITLE);
-                               userHome.setProperty(Property.JCR_ID, username);
-                               // TODO use display name
-                               userHome.setProperty(Property.JCR_TITLE, userId);
-//                             userHome.setProperty(NodeNames.LDAP_UID, username);
-                               adminSession.save();
-
-                               JcrUtils.clearAccessControList(adminSession, userHome.getPath(), username);
-                               JcrUtils.addPrivilege(adminSession, userHome.getPath(), username, Privilege.JCR_ALL);
-//                             JackrabbitSecurityUtils.denyPrivilege(adminSession, userHome.getPath(), NodeConstants.ROLE_USER,
-//                                             Privilege.JCR_READ);
-                       }
-                       if (adminSession.hasPendingChanges())
-                               adminSession.save();
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(adminSession);
-                       throw new JcrException("Cannot sync node security model for " + username, e);
-               }
-       }
-
-       /** Generate path for a new user home */
-       private String generateUserPath(String username) {
-               LdapName dn;
-               try {
-                       dn = new LdapName(username);
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Invalid name " + username, e);
-               }
-               String userId = dn.getRdn(dn.size() - 1).getValue().toString();
-               return '/' + userId;
-//             int atIndex = userId.indexOf('@');
-//             if (atIndex < 0) {
-//                     return homeBasePath+'/' + userId;
-//             } else {
-//                     return usersBasePath + '/' + usersDatePath.format(new Date()) + '/' + userId;
-//             }
-       }
-
-       private String extractUserId(String username) {
-               LdapName dn;
-               try {
-                       dn = new LdapName(username);
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Invalid name " + username, e);
-               }
-               String userId = dn.getRdn(dn.size() - 1).getValue().toString();
-               return userId;
-//             int atIndex = userId.indexOf('@');
-//             if (atIndex < 0) {
-//                     return homeBasePath+'/' + userId;
-//             } else {
-//                     return usersBasePath + '/' + usersDatePath.format(new Date()) + '/' + userId;
-//             }
-       }
-
-       public void createWorkgroup(LdapName dn) {
-               String groupsWorkspace = getGroupsWorkspace();
-               Session adminSession = KernelUtils.openAdminSession(getRepository(groupsWorkspace), groupsWorkspace);
-               String cn = dn.getRdn(dn.size() - 1).getValue().toString();
-               Node newWorkgroup = CmsJcrUtils.getGroupHome(adminSession, cn);
-               if (newWorkgroup != null) {
-                       JcrUtils.logoutQuietly(adminSession);
-                       throw new IllegalStateException("Workgroup " + newWorkgroup + " already exists for " + dn);
-               }
-               try {
-                       // TODO enhance transformation of cn to a valid node name
-                       // String relPath = cn.replaceAll("[^a-zA-Z0-9]", "_");
-                       String relPath = JcrUtils.replaceInvalidChars(cn);
-                       newWorkgroup = adminSession.getRootNode().addNode(relPath, NodeType.NT_UNSTRUCTURED);
-//                     newWorkgroup = JcrUtils.mkdirs(adminSession.getNode(groupsBasePath), relPath, NodeType.NT_UNSTRUCTURED);
-//                     newWorkgroup.addMixin(NodeTypes.NODE_GROUP_HOME);
-                       newWorkgroup.addMixin(NodeType.MIX_CREATED);
-                       newWorkgroup.addMixin(NodeType.MIX_TITLE);
-                       newWorkgroup.setProperty(Property.JCR_ID, dn.toString());
-                       newWorkgroup.setProperty(Property.JCR_TITLE, cn);
-//                     newWorkgroup.setProperty(NodeNames.LDAP_CN, cn);
-                       adminSession.save();
-                       JcrUtils.addPrivilege(adminSession, newWorkgroup.getPath(), dn.toString(), Privilege.JCR_ALL);
-                       adminSession.save();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot create workgroup", e);
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-
-       }
-
-       public boolean isRemote() {
-               return remote;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java
deleted file mode 100644 (file)
index bad9fdf..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-
-class JackrabbitLocalRepository extends LocalRepository {
-       private final static CmsLog log = CmsLog.getLog(JackrabbitLocalRepository.class);
-       final String SECURITY_WORKSPACE = "security";
-
-       private Map<String, CmsWorkspaceIndexer> workspaceMonitors = new TreeMap<>();
-
-       public JackrabbitLocalRepository(RepositoryImpl repository, String cn) {
-               super(repository, cn);
-//             Session session = KernelUtils.openAdminSession(repository);
-//             try {
-//                     if (NodeConstants.NODE.equals(cn))
-//                             for (String workspaceName : session.getWorkspace().getAccessibleWorkspaceNames()) {
-//                                     addMonitor(workspaceName);
-//                             }
-//             } catch (RepositoryException e) {
-//                     throw new IllegalStateException(e);
-//             } finally {
-//                     JcrUtils.logoutQuietly(session);
-//             }
-       }
-
-       protected RepositoryImpl getJackrabbitrepository(String workspaceName) {
-               return (RepositoryImpl) getRepository(workspaceName);
-       }
-
-       @Override
-       protected synchronized void processNewSession(Session session, String workspaceName) {
-//             String realWorkspaceName = session.getWorkspace().getName();
-//             addMonitor(realWorkspaceName);
-       }
-
-       private void addMonitor(String realWorkspaceName) {
-               if (realWorkspaceName.equals(SECURITY_WORKSPACE))
-                       return;
-               if (!CmsConstants.NODE_REPOSITORY.equals(getCn()))
-                       return;
-
-               if (!workspaceMonitors.containsKey(realWorkspaceName)) {
-                       try {
-                               CmsWorkspaceIndexer workspaceMonitor = new CmsWorkspaceIndexer(
-                                               getJackrabbitrepository(realWorkspaceName), getCn(), realWorkspaceName);
-                               workspaceMonitors.put(realWorkspaceName, workspaceMonitor);
-                               workspaceMonitor.init();
-                               if (log.isDebugEnabled())
-                                       log.debug("Registered " + workspaceMonitor);
-                       } catch (RepositoryException e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
-                       }
-               }
-       }
-
-       public void destroy() {
-               for (String workspaceName : workspaceMonitors.keySet()) {
-                       workspaceMonitors.get(workspaceName).destroy();
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java
deleted file mode 100644 (file)
index 17625f5..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.io.ByteArrayInputStream;
-import java.io.CharArrayReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.SecureRandom;
-
-import javax.crypto.Cipher;
-import javax.crypto.CipherInputStream;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-
-import org.apache.commons.io.IOUtils;
-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 CmsLog log = CmsLog.getLog(JcrKeyring.class);
-       /**
-        * Stronger with 256, but causes problem with Oracle JVM, force 128 in this case
-        */
-       public final static Long DEFAULT_SECRETE_KEY_LENGTH = 256l;
-       public final static String DEFAULT_SECRETE_KEY_FACTORY = "PBKDF2WithHmacSHA1";
-       public final static String DEFAULT_SECRETE_KEY_ENCRYPTION = "AES";
-       public final static String DEFAULT_CIPHER_NAME = "AES/CBC/PKCS5Padding";
-
-       private Integer iterationCountFactor = 200;
-       private Long secretKeyLength = DEFAULT_SECRETE_KEY_LENGTH;
-       private String secretKeyFactoryName = DEFAULT_SECRETE_KEY_FACTORY;
-       private String secretKeyEncryption = DEFAULT_SECRETE_KEY_ENCRYPTION;
-       private String cipherName = DEFAULT_CIPHER_NAME;
-
-       private final Repository repository;
-       // TODO remove thread local session ; open a session each time
-       private ThreadLocal<Session> sessionThreadLocal = new ThreadLocal<Session>() {
-
-               @Override
-               protected Session initialValue() {
-                       return login();
-               }
-
-       };
-
-       // FIXME is it really still needed?
-       /**
-        * When setup is called the session has not yet been saved and we don't want to
-        * save it since there maybe other data which would be inconsistent. So we keep
-        * a reference to this node which will then be used (an reset to null) when
-        * handling the PBE callback. We keep one per thread in case multiple users are
-        * accessing the same instance of a keyring.
-        */
-       // private ThreadLocal<Node> notYetSavedKeyring = new ThreadLocal<Node>() {
-       //
-       // @Override
-       // protected Node initialValue() {
-       // return null;
-       // }
-       // };
-
-       public JcrKeyring(Repository repository) {
-               this.repository = repository;
-       }
-
-       private Session session() {
-               Session session = this.sessionThreadLocal.get();
-               if (!session.isLive()) {
-                       session = login();
-                       sessionThreadLocal.set(session);
-               }
-               return session;
-       }
-
-       private Session login() {
-               try {
-                       return repository.login(CmsConstants.HOME_WORKSPACE);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot login key ring session", e);
-               }
-       }
-
-       @Override
-       protected synchronized Boolean isSetup() {
-               Session session = null;
-               try {
-                       // if (notYetSavedKeyring.get() != null)
-                       // return true;
-                       session = session();
-                       session.refresh(true);
-                       Node userHome = CmsJcrUtils.getUserHome(session);
-                       return userHome.hasNode(ARGEO_KEYRING);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check whether keyring is setup", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       @Override
-       protected synchronized void setup(char[] password) {
-               Binary binary = null;
-               // InputStream in = null;
-               try {
-                       session().refresh(true);
-                       Node userHome = CmsJcrUtils.getUserHome(session());
-                       Node keyring;
-                       if (userHome.hasNode(ARGEO_KEYRING)) {
-                               throw new IllegalArgumentException("Keyring already set up");
-                       } else {
-                               keyring = userHome.addNode(ARGEO_KEYRING);
-                       }
-                       keyring.addMixin(ArgeoTypes.ARGEO_PBE_SPEC);
-
-                       // deterministic salt and iteration count based on username
-                       String username = session().getUserID();
-                       byte[] salt = new byte[8];
-                       byte[] usernameBytes = username.getBytes(StandardCharsets.UTF_8);
-                       for (int i = 0; i < salt.length; i++) {
-                               if (i < usernameBytes.length)
-                                       salt[i] = usernameBytes[i];
-                               else
-                                       salt[i] = 0;
-                       }
-                       try (InputStream in = new ByteArrayInputStream(salt);) {
-                               binary = session().getValueFactory().createBinary(in);
-                               keyring.setProperty(ARGEO_SALT, binary);
-                       } catch (IOException e) {
-                               throw new RuntimeException("Cannot set keyring salt", e);
-                       }
-
-                       Integer iterationCount = username.length() * iterationCountFactor;
-                       keyring.setProperty(ARGEO_ITERATION_COUNT, iterationCount);
-
-                       // default algo
-                       // TODO check if algo and key length are available, use DES if not
-                       keyring.setProperty(ARGEO_SECRET_KEY_FACTORY, secretKeyFactoryName);
-                       keyring.setProperty(ARGEO_KEY_LENGTH, secretKeyLength);
-                       keyring.setProperty(ARGEO_SECRET_KEY_ENCRYPTION, secretKeyEncryption);
-                       keyring.setProperty(ARGEO_CIPHER, cipherName);
-
-                       keyring.getSession().save();
-
-                       // encrypted password hash
-                       // IOUtils.closeQuietly(in);
-                       // JcrUtils.closeQuietly(binary);
-                       // byte[] btPass = hash(password, salt, iterationCount);
-                       // in = new ByteArrayInputStream(btPass);
-                       // binary = session().getValueFactory().createBinary(in);
-                       // keyring.setProperty(ARGEO_PASSWORD, binary);
-
-                       // notYetSavedKeyring.set(keyring);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot setup keyring", e);
-               } finally {
-                       JcrUtils.closeQuietly(binary);
-                       // IOUtils.closeQuietly(in);
-                       // JcrUtils.discardQuietly(session());
-               }
-       }
-
-       @Override
-       protected synchronized void handleKeySpecCallback(PBEKeySpecCallback pbeCallback) {
-               Session session = null;
-               try {
-                       session = session();
-                       session.refresh(true);
-                       Node userHome = CmsJcrUtils.getUserHome(session);
-                       Node keyring;
-                       if (userHome.hasNode(ARGEO_KEYRING))
-                               keyring = userHome.getNode(ARGEO_KEYRING);
-                       // else if (notYetSavedKeyring.get() != null)
-                       // keyring = notYetSavedKeyring.get();
-                       else
-                               throw new IllegalStateException("Keyring not setup");
-
-                       pbeCallback.set(keyring.getProperty(ARGEO_SECRET_KEY_FACTORY).getString(),
-                                       JcrUtils.getBinaryAsBytes(keyring.getProperty(ARGEO_SALT)),
-                                       (int) keyring.getProperty(ARGEO_ITERATION_COUNT).getLong(),
-                                       (int) keyring.getProperty(ARGEO_KEY_LENGTH).getLong(),
-                                       keyring.getProperty(ARGEO_SECRET_KEY_ENCRYPTION).getString());
-
-                       // if (notYetSavedKeyring.get() != null)
-                       // notYetSavedKeyring.remove();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot handle key spec callback", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       /** The parent node must already exist at this path. */
-       @Override
-       protected synchronized void encrypt(String path, InputStream unencrypted) {
-               // should be called first for lazy initialization
-               SecretKey secretKey = getSecretKey(null);
-               Cipher cipher = createCipher();
-
-               // Binary binary = null;
-               // InputStream in = null;
-               try {
-                       session().refresh(true);
-                       Node node;
-                       if (!session().nodeExists(path)) {
-                               String parentPath = JcrUtils.parentPath(path);
-                               if (!session().nodeExists(parentPath))
-                                       throw new IllegalStateException("No parent node of " + path);
-                               Node parentNode = session().getNode(parentPath);
-                               node = parentNode.addNode(JcrUtils.nodeNameFromPath(path));
-                       } else {
-                               node = session().getNode(path);
-                       }
-                       encrypt(secretKey, cipher, node, unencrypted);
-                       // node.addMixin(ArgeoTypes.ARGEO_ENCRYPTED);
-                       // SecureRandom random = new SecureRandom();
-                       // byte[] iv = new byte[16];
-                       // random.nextBytes(iv);
-                       // cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
-                       // JcrUtils.setBinaryAsBytes(node, ARGEO_IV, iv);
-                       //
-                       // try (InputStream in = new CipherInputStream(unencrypted, cipher);) {
-                       // binary = session().getValueFactory().createBinary(in);
-                       // node.setProperty(Property.JCR_DATA, binary);
-                       // session().save();
-                       // }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot encrypt", e);
-               } finally {
-                       try {
-                               unencrypted.close();
-                       } catch (IOException e) {
-                               // silent
-                       }
-                       // IOUtils.closeQuietly(unencrypted);
-                       // IOUtils.closeQuietly(in);
-                       // JcrUtils.closeQuietly(binary);
-                       JcrUtils.logoutQuietly(session());
-               }
-       }
-
-       protected synchronized void encrypt(SecretKey secretKey, Cipher cipher, Node node, InputStream unencrypted) {
-               try {
-                       node.addMixin(ArgeoTypes.ARGEO_ENCRYPTED);
-                       SecureRandom random = new SecureRandom();
-                       byte[] iv = new byte[16];
-                       random.nextBytes(iv);
-                       cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
-                       JcrUtils.setBinaryAsBytes(node, ARGEO_IV, iv);
-
-                       Binary binary = null;
-                       try (InputStream in = new CipherInputStream(unencrypted, cipher);) {
-                               binary = session().getValueFactory().createBinary(in);
-                               node.setProperty(Property.JCR_DATA, binary);
-                               session().save();
-                       } finally {
-                               JcrUtils.closeQuietly(binary);
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot encrypt", e);
-               } catch (GeneralSecurityException | IOException e) {
-                       throw new RuntimeException("Cannot encrypt", e);
-               }
-       }
-
-       @Override
-       protected synchronized InputStream decrypt(String path) {
-               Binary binary = null;
-               try {
-                       session().refresh(true);
-                       if (!session().nodeExists(path)) {
-                               char[] password = ask();
-                               Reader reader = new CharArrayReader(password);
-                               return new ByteArrayInputStream(IOUtils.toByteArray(reader, StandardCharsets.UTF_8));
-                       } else {
-                               // should be called first for lazy initialisation
-                               SecretKey secretKey = getSecretKey(null);
-                               Cipher cipher = createCipher();
-                               Node node = session().getNode(path);
-                               return decrypt(secretKey, cipher, node);
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot decrypt", e);
-               } catch (GeneralSecurityException | IOException e) {
-                       throw new RuntimeException("Cannot decrypt", e);
-               } finally {
-                       JcrUtils.closeQuietly(binary);
-                       JcrUtils.logoutQuietly(session());
-               }
-       }
-
-       protected synchronized InputStream decrypt(SecretKey secretKey, Cipher cipher, Node node)
-                       throws RepositoryException, GeneralSecurityException {
-               if (node.hasProperty(ARGEO_IV)) {
-                       byte[] iv = JcrUtils.getBinaryAsBytes(node.getProperty(ARGEO_IV));
-                       cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
-               } else {
-                       cipher.init(Cipher.DECRYPT_MODE, secretKey);
-               }
-
-               Binary binary = node.getProperty(Property.JCR_DATA).getBinary();
-               InputStream encrypted = binary.getStream();
-               return new CipherInputStream(encrypted, cipher);
-       }
-
-       protected Cipher createCipher() {
-               try {
-                       Node userHome = CmsJcrUtils.getUserHome(session());
-                       if (!userHome.hasNode(ARGEO_KEYRING))
-                               throw new IllegalArgumentException("Keyring not setup");
-                       Node keyring = userHome.getNode(ARGEO_KEYRING);
-                       String cipherName = keyring.getProperty(ARGEO_CIPHER).getString();
-                       Provider securityProvider = getSecurityProvider();
-                       Cipher cipher;
-                       if (securityProvider == null)// TODO use BC?
-                               cipher = Cipher.getInstance(cipherName);
-                       else
-                               cipher = Cipher.getInstance(cipherName, securityProvider);
-                       return cipher;
-               } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
-                       throw new IllegalArgumentException("Cannot get cipher", e);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get cipher", e);
-               } finally {
-
-               }
-       }
-
-       public synchronized void changePassword(char[] oldPassword, char[] newPassword) {
-               // TODO make it XA compatible
-               SecretKey oldSecretKey = getSecretKey(oldPassword);
-               SecretKey newSecretKey = getSecretKey(newPassword);
-               Session session = session();
-               try {
-                       NodeIterator encryptedNodes = session.getWorkspace().getQueryManager()
-                                       .createQuery("select * from [argeo:encrypted]", Query.JCR_SQL2).execute().getNodes();
-                       while (encryptedNodes.hasNext()) {
-                               Node node = encryptedNodes.nextNode();
-                               InputStream in = decrypt(oldSecretKey, createCipher(), node);
-                               encrypt(newSecretKey, createCipher(), node, in);
-                               if (log.isDebugEnabled())
-                                       log.debug("Converted keyring encrypted value of " + node.getPath());
-                       }
-               } catch (GeneralSecurityException e) {
-                       throw new RuntimeException("Cannot change JCR keyring password", e);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot change JCR keyring password", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       // public synchronized void setSession(Session session) {
-       // this.session = session;
-       // }
-
-       public void setIterationCountFactor(Integer iterationCountFactor) {
-               this.iterationCountFactor = iterationCountFactor;
-       }
-
-       public void setSecretKeyLength(Long keyLength) {
-               this.secretKeyLength = keyLength;
-       }
-
-       public void setSecretKeyFactoryName(String secreteKeyFactoryName) {
-               this.secretKeyFactoryName = secreteKeyFactoryName;
-       }
-
-       public void setSecretKeyEncryption(String secreteKeyEncryption) {
-               this.secretKeyEncryption = secreteKeyEncryption;
-       }
-
-       public void setCipherName(String cipherName) {
-               this.cipherName = cipherName;
-       }
-
-}
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrRepositoryFactory.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrRepositoryFactory.java
deleted file mode 100644 (file)
index 342c1ad..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-
-import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
-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;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-/**
- * OSGi-aware Jackrabbit repository factory which can retrieve/publish
- * {@link Repository} as OSGi services.
- */
-public class JcrRepositoryFactory implements RepositoryFactory {
-       private final CmsLog log = CmsLog.getLog(getClass());
-//     private final BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-       // private Resource fileRepositoryConfiguration = new ClassPathResource(
-       // "/org/argeo/cms/internal/kernel/repository-localfs.xml");
-
-       protected Repository getRepositoryByAlias(String alias) {
-               BundleContext bundleContext = CmsJcrActivator.getBundleContext();
-               if (bundleContext != null) {
-                       try {
-                               Collection<ServiceReference<Repository>> srs = bundleContext.getServiceReferences(Repository.class,
-                                               "(" + CmsConstants.CN + "=" + alias + ")");
-                               if (srs.size() == 0)
-                                       throw new IllegalArgumentException("No repository with alias " + alias + " found in OSGi registry");
-                               else if (srs.size() > 1)
-                                       throw new IllegalArgumentException(
-                                                       srs.size() + " repositories with alias " + alias + " found in OSGi registry");
-                               return bundleContext.getService(srs.iterator().next());
-                       } catch (InvalidSyntaxException e) {
-                               throw new IllegalArgumentException("Cannot find repository with alias " + alias, e);
-                       }
-               } else {
-                       // TODO ability to filter static services
-                       return null;
-               }
-       }
-
-       // private void publish(String alias, Repository repository, Properties
-       // properties) {
-       // if (bundleContext != null) {
-       // // do not modify reference
-       // Hashtable<String, String> props = new Hashtable<String, String>();
-       // props.putAll(props);
-       // props.put(JCR_REPOSITORY_ALIAS, alias);
-       // bundleContext.registerService(Repository.class.getName(), repository,
-       // props);
-       // }
-       // }
-
-       @SuppressWarnings({ "rawtypes" })
-       public Repository getRepository(Map parameters) throws RepositoryException {
-               // // check if can be found by alias
-               // Repository repository = super.getRepository(parameters);
-               // if (repository != null)
-               // return repository;
-
-               // check if remote
-               Repository repository;
-               String uri = null;
-               if (parameters.containsKey(RepoConf.labeledUri.name()))
-                       uri = parameters.get(CmsConstants.LABELED_URI).toString();
-               else if (parameters.containsKey(KernelConstants.JACKRABBIT_REPOSITORY_URI))
-                       uri = parameters.get(KernelConstants.JACKRABBIT_REPOSITORY_URI).toString();
-
-               if (uri != null) {
-                       if (uri.startsWith("http")) {// http, https
-                               Object defaultWorkspace = parameters.get(RepoConf.defaultWorkspace.name());
-                               repository = createRemoteRepository(uri, defaultWorkspace != null ? defaultWorkspace.toString() : null);
-                       } else if (uri.startsWith("file"))// http, https
-                               repository = createFileRepository(uri, parameters);
-                       else if (uri.startsWith("vm")) {
-                               // log.warn("URI " + uri + " should have been managed by generic
-                               // JCR repository factory");
-                               repository = getRepositoryByAlias(getAliasFromURI(uri));
-                       } else
-                               throw new IllegalArgumentException("Unrecognized URI format " + uri);
-
-               }
-
-               else if (parameters.containsKey(CmsConstants.CN)) {
-                       // Properties properties = new Properties();
-                       // properties.putAll(parameters);
-                       String alias = parameters.get(CmsConstants.CN).toString();
-                       // publish(alias, repository, properties);
-                       // log.info("Registered JCR repository under alias '" + alias + "'
-                       // with properties " + properties);
-                       repository = getRepositoryByAlias(alias);
-               } else
-                       throw new IllegalArgumentException("Not enough information in " + parameters);
-
-               if (repository == null)
-                       throw new IllegalArgumentException("Repository not found " + parameters);
-
-               return repository;
-       }
-
-       protected Repository createRemoteRepository(String uri, String defaultWorkspace) throws RepositoryException {
-               Map<String, String> params = new HashMap<String, String>();
-               params.put(KernelConstants.JACKRABBIT_REPOSITORY_URI, uri);
-               if (defaultWorkspace != null)
-                       params.put(KernelConstants.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, defaultWorkspace);
-               Repository repository = new Jcr2davRepositoryFactory().getRepository(params);
-               if (repository == null)
-                       throw new IllegalArgumentException("Remote Davex repository " + uri + " not found");
-               log.info("Initialized remote Jackrabbit repository from uri " + uri);
-               return repository;
-       }
-
-       @SuppressWarnings({ "rawtypes" })
-       protected Repository createFileRepository(final String uri, Map parameters) throws RepositoryException {
-               throw new UnsupportedOperationException();
-               // InputStream configurationIn = null;
-               // try {
-               // Properties vars = new Properties();
-               // vars.putAll(parameters);
-               // String dirPath = uri.substring("file:".length());
-               // File homeDir = new File(dirPath);
-               // if (homeDir.exists() && !homeDir.isDirectory())
-               // throw new ArgeoJcrException("Repository home " + dirPath + " is not a
-               // directory");
-               // if (!homeDir.exists())
-               // homeDir.mkdirs();
-               // configurationIn = fileRepositoryConfiguration.getInputStream();
-               // vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
-               // homeDir.getCanonicalPath());
-               // RepositoryConfig repositoryConfig = RepositoryConfig.create(new
-               // InputSource(configurationIn), vars);
-               //
-               // // TransientRepository repository = new
-               // // TransientRepository(repositoryConfig);
-               // final RepositoryImpl repository =
-               // RepositoryImpl.create(repositoryConfig);
-               // Session session = repository.login();
-               // // FIXME make it generic
-               // org.argeo.jcr.JcrUtils.addPrivilege(session, "/", "ROLE_ADMIN",
-               // "jcr:all");
-               // org.argeo.jcr.JcrUtils.logoutQuietly(session);
-               // Runtime.getRuntime().addShutdownHook(new Thread("Clean JCR repository
-               // " + uri) {
-               // public void run() {
-               // repository.shutdown();
-               // log.info("Destroyed repository " + uri);
-               // }
-               // });
-               // log.info("Initialized file Jackrabbit repository from uri " + uri);
-               // return repository;
-               // } catch (Exception e) {
-               // throw new ArgeoJcrException("Cannot create repository " + uri, e);
-               // } finally {
-               // IOUtils.closeQuietly(configurationIn);
-               // }
-       }
-
-       protected String getAliasFromURI(String uri) {
-               try {
-                       URI uriObj = new URI(uri);
-                       String alias = uriObj.getPath();
-                       if (alias.charAt(0) == '/')
-                               alias = alias.substring(1);
-                       if (alias.charAt(alias.length() - 1) == '/')
-                               alias = alias.substring(0, alias.length() - 1);
-                       return alias;
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException("Cannot interpret URI " + uri, e);
-               }
-       }
-
-       /**
-        * Called after the repository has been initialised. Does nothing by default.
-        */
-       @SuppressWarnings("rawtypes")
-       protected void postInitialization(Repository repository, Map parameters) {
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java
deleted file mode 100644 (file)
index 93f29fb..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import org.argeo.api.cms.CmsConstants;
-
-/** Internal CMS constants. */
-@Deprecated
-public interface KernelConstants {
-       // Directories
-       String DIR_NODE = "node";
-       String DIR_REPOS = "repos";
-       String DIR_INDEXES = "indexes";
-       String DIR_TRANSACTIONS = "transactions";
-
-       // Files
-       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
-       String JAAS_CONFIG = "/org/argeo/cms/internal/kernel/jaas.cfg";
-       String JAAS_CONFIG_IPA = "/org/argeo/cms/internal/kernel/jaas-ipa.cfg";
-
-       // Java
-       String JAAS_CONFIG_PROP = "java.security.auth.login.config";
-
-       // DEFAULTS JCR PATH
-       String DEFAULT_HOME_BASE_PATH = "/home";
-       String DEFAULT_USERS_BASE_PATH = "/users";
-       String DEFAULT_GROUPS_BASE_PATH = "/groups";
-       
-       // KERBEROS
-       String DEFAULT_KERBEROS_SERVICE = "HTTP";
-
-       // HTTP client
-       String COOKIE_POLICY_BROWSER_COMPATIBILITY = "compatibility";
-
-       // RWT / RAP
-       // String PATH_WORKBENCH = "/ui";
-       // String PATH_WORKBENCH_PUBLIC = PATH_WORKBENCH + "/public";
-
-       String JETTY_FACTORY_PID = "org.eclipse.equinox.http.jetty.config";
-       String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern";
-       // default Jetty server configured via JettyConfigurator
-       String DEFAULT_JETTY_SERVER = "default";
-       String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
-
-       // avoid dependencies
-       String CONTEXT_NAME_PROP = "contextName";
-       String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
-       String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java
deleted file mode 100644 (file)
index edfe87a..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.security.PrivilegedAction;
-import java.security.URIParameter;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Properties;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-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;
-import org.osgi.util.tracker.ServiceTracker;
-
-/** Package utilities */
-class KernelUtils implements KernelConstants {
-       final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
-       final static String OSGI_CONFIGURATION_AREA = "osgi.configuration.area";
-
-       static void setJaasConfiguration(URL jaasConfigurationUrl) {
-               try {
-                       URIParameter uriParameter = new URIParameter(jaasConfigurationUrl.toURI());
-                       javax.security.auth.login.Configuration jaasConfiguration = javax.security.auth.login.Configuration
-                                       .getInstance("JavaLoginConfig", uriParameter);
-                       javax.security.auth.login.Configuration.setConfiguration(jaasConfiguration);
-               } catch (Exception e) {
-                       throw new IllegalArgumentException("Cannot set configuration " + jaasConfigurationUrl, e);
-               }
-       }
-
-       static Dictionary<String, ?> asDictionary(Properties props) {
-               Hashtable<String, Object> hashtable = new Hashtable<String, Object>();
-               for (Object key : props.keySet()) {
-                       hashtable.put(key.toString(), props.get(key));
-               }
-               return hashtable;
-       }
-
-       static Dictionary<String, ?> asDictionary(ClassLoader cl, String resource) {
-               Properties props = new Properties();
-               try {
-                       props.load(cl.getResourceAsStream(resource));
-               } catch (IOException e) {
-                       throw new IllegalArgumentException("Cannot load " + resource + " from classpath", e);
-               }
-               return asDictionary(props);
-       }
-
-       static File getExecutionDir(String relativePath) {
-               File executionDir = new File(getFrameworkProp("user.dir"));
-               if (relativePath == null)
-                       return executionDir;
-               try {
-                       return new File(executionDir, relativePath).getCanonicalFile();
-               } catch (IOException e) {
-                       throw new IllegalArgumentException("Cannot get canonical file", e);
-               }
-       }
-
-       static File getOsgiInstanceDir() {
-               return new File(getBundleContext().getProperty(OSGI_INSTANCE_AREA).substring("file:".length()))
-                               .getAbsoluteFile();
-       }
-
-       static Path getOsgiInstancePath(String relativePath) {
-               return Paths.get(getOsgiInstanceUri(relativePath));
-       }
-
-       static URI getOsgiInstanceUri(String relativePath) {
-               String osgiInstanceBaseUri = getFrameworkProp(OSGI_INSTANCE_AREA);
-               if (osgiInstanceBaseUri != null)
-                       return safeUri(osgiInstanceBaseUri + (relativePath != null ? relativePath : ""));
-               else
-                       return Paths.get(System.getProperty("user.dir")).toUri();
-       }
-
-       static File getOsgiConfigurationFile(String relativePath) {
-               try {
-                       return new File(new URI(getBundleContext().getProperty(OSGI_CONFIGURATION_AREA) + relativePath))
-                                       .getCanonicalFile();
-               } catch (Exception e) {
-                       throw new IllegalArgumentException("Cannot get configuration file for " + relativePath, e);
-               }
-       }
-
-       static String getFrameworkProp(String key, String def) {
-               BundleContext bundleContext = CmsJcrActivator.getBundleContext();
-               String value;
-               if (bundleContext != null)
-                       value = bundleContext.getProperty(key);
-               else
-                       value = System.getProperty(key);
-               if (value == null)
-                       return def;
-               return value;
-       }
-
-       static String getFrameworkProp(String key) {
-               return getFrameworkProp(key, null);
-       }
-
-       // Security
-       // static Subject anonymousLogin() {
-       // Subject subject = new Subject();
-       // LoginContext lc;
-       // try {
-       // lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject);
-       // lc.login();
-       // return subject;
-       // } catch (LoginException e) {
-       // throw new CmsException("Cannot login as anonymous", e);
-       // }
-       // }
-
-       static void logFrameworkProperties(CmsLog log) {
-               BundleContext bc = getBundleContext();
-               for (Object sysProp : new TreeSet<Object>(System.getProperties().keySet())) {
-                       log.debug(sysProp + "=" + bc.getProperty(sysProp.toString()));
-               }
-               // String[] keys = { Constants.FRAMEWORK_STORAGE,
-               // Constants.FRAMEWORK_OS_NAME, Constants.FRAMEWORK_OS_VERSION,
-               // Constants.FRAMEWORK_PROCESSOR, Constants.FRAMEWORK_SECURITY,
-               // Constants.FRAMEWORK_TRUST_REPOSITORIES,
-               // Constants.FRAMEWORK_WINDOWSYSTEM, Constants.FRAMEWORK_VENDOR,
-               // Constants.FRAMEWORK_VERSION, Constants.FRAMEWORK_STORAGE_CLEAN,
-               // Constants.FRAMEWORK_LANGUAGE, Constants.FRAMEWORK_UUID };
-               // for (String key : keys)
-               // log.debug(key + "=" + bc.getProperty(key));
-       }
-
-       static void printSystemProperties(PrintStream out) {
-               TreeMap<String, String> display = new TreeMap<>();
-               for (Object key : System.getProperties().keySet())
-                       display.put(key.toString(), System.getProperty(key.toString()));
-               for (String key : display.keySet())
-                       out.println(key + "=" + display.get(key));
-       }
-
-       static Session openAdminSession(Repository repository) {
-               return openAdminSession(repository, null);
-       }
-
-       static Session openAdminSession(final Repository repository, final String workspaceName) {
-               LoginContext loginContext = loginAsDataAdmin();
-               return Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Session>() {
-
-                       @Override
-                       public Session run() {
-                               try {
-                                       return repository.login(workspaceName);
-                               } catch (RepositoryException e) {
-                                       throw new IllegalStateException("Cannot open admin session", e);
-                               } finally {
-                                       try {
-                                               loginContext.logout();
-                                       } catch (LoginException e) {
-                                               throw new IllegalStateException(e);
-                                       }
-                               }
-                       }
-
-               });
-       }
-
-       static LoginContext loginAsDataAdmin() {
-               ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
-               Thread.currentThread().setContextClassLoader(KernelUtils.class.getClassLoader());
-               LoginContext loginContext;
-               try {
-                       loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_DATA_ADMIN);
-                       loginContext.login();
-               } catch (LoginException e1) {
-                       throw new IllegalStateException("Could not login as data admin", e1);
-               } finally {
-                       Thread.currentThread().setContextClassLoader(currentCl);
-               }
-               return loginContext;
-       }
-
-       static void doAsDataAdmin(Runnable action) {
-               LoginContext loginContext = loginAsDataAdmin();
-               Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Void>() {
-
-                       @Override
-                       public Void run() {
-                               try {
-                                       action.run();
-                                       return null;
-                               } finally {
-                                       try {
-                                               loginContext.logout();
-                                       } catch (LoginException e) {
-                                               throw new IllegalStateException(e);
-                                       }
-                               }
-                       }
-
-               });
-       }
-
-       static void asyncOpen(ServiceTracker<?, ?> st) {
-               Runnable run = new Runnable() {
-
-                       @Override
-                       public void run() {
-                               st.open();
-                       }
-               };
-//             Activator.getInternalExecutorService().execute(run);
-               new Thread(run, "Open service tracker " + st).start();
-       }
-
-       static BundleContext getBundleContext() {
-               return CmsJcrActivator.getBundleContext();
-       }
-
-       static boolean asBoolean(String value) {
-               if (value == null)
-                       return false;
-               switch (value) {
-               case "true":
-                       return true;
-               case "false":
-                       return false;
-               default:
-                       throw new IllegalArgumentException(
-                                       "Unsupported value for attribute " + DataModelNamespace.ABSTRACT + ": " + value);
-               }
-       }
-
-       private static URI safeUri(String uri) {
-               if (uri == null)
-                       throw new IllegalArgumentException("URI cannot be null");
-               try {
-                       return new URI(uri);
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException("Badly formatted URI " + uri, e);
-               }
-       }
-
-       private KernelUtils() {
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java
deleted file mode 100644 (file)
index 0bac94c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import javax.jcr.Repository;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.jcr.JcrRepositoryWrapper;
-
-class LocalRepository extends JcrRepositoryWrapper {
-       private final String cn;
-
-       public LocalRepository(Repository repository, String cn) {
-               super(repository);
-               this.cn = cn;
-               // Map<String, Object> attrs = dataModelCapability.getAttributes();
-               // cn = (String) attrs.get(DataModelNamespace.NAME);
-               putDescriptor(CmsConstants.CN, cn);
-       }
-
-       String getCn() {
-               return cn;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeKeyRing.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeKeyRing.java
deleted file mode 100644 (file)
index 9cd1f72..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.util.Dictionary;
-
-import javax.jcr.Repository;
-
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
-
-class NodeKeyRing extends JcrKeyring implements ManagedService{
-       
-       public NodeKeyRing(Repository repository) {
-               super(repository);
-       }
-
-       @Override
-       public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java
deleted file mode 100644 (file)
index f3a099b..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-
-import org.apache.jackrabbit.core.RepositoryContext;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.CmsState;
-import org.argeo.cms.CmsDeployProperty;
-import org.argeo.cms.internal.jcr.RepoConf;
-import org.argeo.cms.internal.jcr.RepositoryBuilder;
-import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
-import org.argeo.util.LangUtils;
-import org.osgi.service.cm.ManagedServiceFactory;
-
-/** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */
-public class RepositoryContextsFactory {
-       private final static CmsLog log = CmsLog.getLog(RepositoryContextsFactory.class);
-       private final static String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
-//     private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext();
-
-//     private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
-//     private Map<String, Object> pidToCn = new HashMap<String, Object>();
-
-       private RepositoryContext repositoryContext;
-
-       private CmsState cmsState;
-
-       public void init() {
-               Dictionary<String, Object> config = getNodeRepositoryConfig();
-               deployRepository(config);
-       }
-
-       public void destroy() {
-               if (this.repositoryContext != null) {
-                       this.repositoryContext.getRepository().shutdown();
-               }
-//             for (String pid : repositories.keySet()) {
-//                     try {
-//                             RepositoryContext repositoryContext = repositories.get(pid);
-//                             // Must start in another thread otherwise shutdown is interrupted
-//                             // TODO use an executor?
-//                             new Thread(() -> {
-//                                     repositoryContext.getRepository().shutdown();
-//                                     if (log.isDebugEnabled())
-//                                             log.debug("Shut down repository " + pid
-//                                                             + (pidToCn.containsKey(pid) ? " (" + pidToCn.get(pid) + ")" : ""));
-//                             }, "Shutdown JCR repository " + pid).start();
-//                     } catch (Exception e) {
-//                             log.error("Error when shutting down Jackrabbit repository " + pid, e);
-//                     }
-//             }
-       }
-
-//     @Override
-//     public String getName() {
-//             return "Jackrabbit repository service factory";
-//     }
-
-       /** Override the provided config with the framework properties */
-       private Dictionary<String, Object> getNodeRepositoryConfig() {
-               Dictionary<String, Object> props = new Hashtable<String, Object>();
-               addDeployProperty(CmsDeployProperty.DB_URL, RepoConf.dburl, props);
-               addDeployProperty(CmsDeployProperty.DB_USER, RepoConf.dbuser, props);
-               addDeployProperty(CmsDeployProperty.DB_PASSWORD, RepoConf.dbpassword, props);
-               for (RepoConf repoConf : RepoConf.values()) {
-                       Object value = getFrameworkProp(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(CmsConstants.CN, CmsConstants.NODE_REPOSITORY);
-               return props;
-       }
-
-       private void addDeployProperty(CmsDeployProperty deployProperty, RepoConf repoConf,
-                       Dictionary<String, Object> props) {
-               String value = getFrameworkProp(deployProperty.getProperty());
-               if (value != null) {
-                       props.put(repoConf.name(), value);
-               }
-
-       }
-
-//     @Override
-//     public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
-       protected void deployRepository(Dictionary<String, Object> properties) {
-//             if (repositories.containsKey(pid))
-//                     throw new IllegalArgumentException("Already a repository registered for " + pid);
-
-               if (properties == null)
-                       return;
-
-               Object cn = properties.get(CmsConstants.CN);
-//             if (cn != null)
-//                     for (String otherPid : pidToCn.keySet()) {
-//                             Object o = pidToCn.get(otherPid);
-//                             if (cn.equals(o)) {
-//                                     RepositoryContext repositoryContext = repositories.remove(otherPid);
-//                                     repositories.put(pid, repositoryContext);
-//                                     if (log.isDebugEnabled())
-//                                             log.debug("Ignoring update of Jackrabbit repository " + cn);
-//                                     // FIXME perform a proper update (also of the OSGi service)
-//                                     return;
-//                             }
-//                     }
-
-               try {
-                       Object labeledUri = properties.get(RepoConf.labeledUri.name());
-                       if (labeledUri == null) {
-                               RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
-                               RepositoryContext repositoryContext = repositoryBuilder.createRepositoryContext(properties);
-//                             repositories.put(pid, repositoryContext);
-//                             Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
-                               Dictionary<String, Object> props = new Hashtable<>();
-                               // props.put(ArgeoJcrConstants.JCR_REPOSITORY_URI,
-                               // properties.get(RepoConf.labeledUri.name()));
-                               if (cn != null) {
-                                       props.put(CmsConstants.CN, cn);
-                                       // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
-//                                     pidToCn.put(pid, cn);
-                               }
-                               CmsJcrActivator.registerService(RepositoryContext.class, repositoryContext, props);
-                               this.repositoryContext = repositoryContext;
-                       } else {
-                               Object defaultWorkspace = properties.get(RepoConf.defaultWorkspace.name());
-                               if (defaultWorkspace == null)
-                                       defaultWorkspace = RepoConf.defaultWorkspace.getDefault();
-                               URI uri = new URI(labeledUri.toString());
-//                                     RepositoryFactory repositoryFactory = bc
-//                                                     .getService(bc.getServiceReference(RepositoryFactory.class));
-                               RepositoryFactory repositoryFactory = CmsJcrActivator.getService(RepositoryFactory.class);
-                               Map<String, String> parameters = new HashMap<String, String>();
-                               parameters.put(RepoConf.labeledUri.name(), uri.toString());
-                               parameters.put(RepoConf.defaultWorkspace.name(), defaultWorkspace.toString());
-                               Repository repository = repositoryFactory.getRepository(parameters);
-                               // Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory,
-                               // uri.toString());
-//                             Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
-                               Dictionary<String, Object> props = new Hashtable<>();
-                               props.put(RepoConf.labeledUri.name(),
-                                               new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null)
-                                                               .toString());
-                               if (cn != null) {
-                                       props.put(CmsConstants.CN, cn);
-//                                     pidToCn.put(pid, cn);
-                               }
-                               CmsJcrActivator.registerService(Repository.class, repository, props);
-
-                               // home
-                               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);
-                               }
-                       }
-               } catch (RepositoryException | URISyntaxException | IOException e) {
-                       throw new IllegalStateException("Cannot create Jackrabbit repository " + properties, e);
-               }
-
-       }
-
-//     @Override
-//     public void deleted(String pid) {
-//             RepositoryContext repositoryContext = repositories.remove(pid);
-//             repositoryContext.getRepository().shutdown();
-//             if (log.isDebugEnabled())
-//                     log.debug("Deleted repository " + pid);
-//     }
-
-       private String getFrameworkProp(String key) {
-               return cmsState.getDeployProperty(key);
-       }
-
-       public void setCmsState(CmsState cmsState) {
-               this.cmsState = cmsState;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java
deleted file mode 100644 (file)
index 5a2cd5b..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.argeo.cms.jcr.internal;
-
-import java.io.File;
-import java.lang.management.ManagementFactory;
-
-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 CmsLog log = CmsLog.getLog(StatisticsThread.class);
-
-       private RepositoryStatisticsImpl repoStats;
-
-       /** The smallest period of operation, in ms */
-       private final long PERIOD = 60 * 1000l;
-       /** One ms in ns */
-       private final static long m = 1000l * 1000l;
-       private final static long M = 1024l * 1024l;
-
-       private boolean running = true;
-
-       private CmsLog kernelStatsLog = CmsLog.getLog("argeo.stats.kernel");
-       private CmsLog nodeStatsLog = CmsLog.getLog("argeo.stats.node");
-
-       @SuppressWarnings("unused")
-       private long cycle = 0l;
-
-       public StatisticsThread(String name) {
-               super(name);
-       }
-
-       private void doSmallestPeriod() {
-               // Clean expired sessions
-               // FIXME re-enable it in CMS
-               //CmsSessionImpl.closeInvalidSessions();
-
-               if (kernelStatsLog.isDebugEnabled()) {
-                       StringBuilder line = new StringBuilder(64);
-                       line.append("§\t");
-                       long freeMem = Runtime.getRuntime().freeMemory() / M;
-                       long totalMem = Runtime.getRuntime().totalMemory() / M;
-                       long maxMem = Runtime.getRuntime().maxMemory() / M;
-                       double loadAvg = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage();
-                       // in min
-                       boolean min = true;
-                       long uptime = ManagementFactory.getRuntimeMXBean().getUptime() / (1000 * 60);
-                       if (uptime > 24 * 60) {
-                               min = false;
-                               uptime = uptime / 60;
-                       }
-                       line.append(uptime).append(min ? " min" : " h").append('\t');
-                       line.append(loadAvg).append('\t').append(maxMem).append('\t').append(totalMem).append('\t').append(freeMem)
-                                       .append('\t');
-                       kernelStatsLog.debug(line);
-               }
-
-               if (nodeStatsLog.isDebugEnabled()) {
-                       File dataDir = KernelUtils.getOsgiInstanceDir();
-                       long freeSpace = dataDir.getUsableSpace() / M;
-                       // File currentRoot = null;
-                       // for (File root : File.listRoots()) {
-                       // String rootPath = root.getAbsolutePath();
-                       // if (dataDir.getAbsolutePath().startsWith(rootPath)) {
-                       // if (currentRoot == null
-                       // || (rootPath.length() > currentRoot.getPath()
-                       // .length())) {
-                       // currentRoot = root;
-                       // }
-                       // }
-                       // }
-                       // long totalSpace = currentRoot.getTotalSpace();
-                       StringBuilder line = new StringBuilder(128);
-                       line.append("§\t").append(freeSpace).append(" MB left in " + dataDir);
-                       line.append('\n');
-                       if (repoStats != null)
-                               for (RepositoryStatistics.Type type : RepositoryStatistics.Type.values()) {
-                                       long[] vals = repoStats.getTimeSeries(type).getValuePerMinute();
-                                       long val = vals[vals.length - 1];
-                                       line.append(type.name()).append('\t').append(val).append('\n');
-                               }
-                       nodeStatsLog.debug(line);
-               }
-       }
-
-       @Override
-       public void run() {
-               if (log.isTraceEnabled())
-                       log.trace("Kernel thread started.");
-               final long periodNs = PERIOD * m;
-               while (running) {
-                       long beginNs = System.nanoTime();
-                       doSmallestPeriod();
-
-                       long waitNs = periodNs - (System.nanoTime() - beginNs);
-                       if (waitNs < 0)
-                               continue;
-                       // wait
-                       try {
-                               sleep(waitNs / m, (int) (waitNs % m));
-                       } catch (InterruptedException e) {
-                               // silent
-                       }
-                       cycle++;
-               }
-       }
-
-       public synchronized void destroyAndJoin() {
-               running = false;
-               notifyAll();
-//             interrupt();
-//             try {
-//                     join(PERIOD * 2);
-//             } catch (InterruptedException e) {
-//                     // throw new CmsException("Kernel thread destruction was interrupted");
-//                     log.error("Kernel thread destruction was interrupted", e);
-//             }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java
deleted file mode 100644 (file)
index 57860d8..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.argeo.cms.jcr.internal.osgi;
-
-import java.util.Dictionary;
-
-import org.argeo.cms.jcr.internal.StatisticsThread;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class CmsJcrActivator implements BundleActivator {
-       private static BundleContext bundleContext;
-
-//     private List<Runnable> stopHooks = new ArrayList<>();
-       private StatisticsThread kernelThread;
-
-//     private JackrabbitRepositoryContextsFactory repositoryServiceFactory;
-//     private CmsJcrDeployment jcrDeployment;
-
-       @Override
-       public void start(BundleContext context) throws Exception {
-               bundleContext = context;
-               
-               // kernel thread
-               kernelThread = new StatisticsThread("Kernel Thread");
-               kernelThread.setContextClassLoader(getClass().getClassLoader());
-               kernelThread.start();
-
-               // JCR
-//             repositoryServiceFactory = new JackrabbitRepositoryContextsFactory();
-////           stopHooks.add(() -> repositoryServiceFactory.shutdown());
-//             registerService(ManagedServiceFactory.class, repositoryServiceFactory,
-//                             LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_REPOS_FACTORY_PID));
-
-//             JcrRepositoryFactory repositoryFactory = new JcrRepositoryFactory();
-//             registerService(RepositoryFactory.class, repositoryFactory, null);
-
-               // File System
-//             CmsJcrFsProvider cmsFsProvider = new CmsJcrFsProvider();
-//             ServiceLoader<FileSystemProvider> fspSl = ServiceLoader.load(FileSystemProvider.class);
-//             for (FileSystemProvider fsp : fspSl) {
-//                     log.debug("FileSystemProvider " + fsp);
-//                     if (fsp instanceof CmsFsProvider) {
-//                             cmsFsProvider = (CmsFsProvider) fsp;
-//                     }
-//             }
-//             for (FileSystemProvider fsp : FileSystemProvider.installedProviders()) {
-//                     log.debug("Installed FileSystemProvider " + fsp);
-//             }
-//             registerService(FileSystemProvider.class, cmsFsProvider,
-//                             LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_FS_PROVIDER_PID));
-
-//             jcrDeployment = new CmsJcrDeployment();
-//             jcrDeployment.init();
-       }
-
-       @Override
-       public void stop(BundleContext context) throws Exception {
-//             if (jcrDeployment != null)
-//                     jcrDeployment.destroy();
-
-//             if (repositoryServiceFactory != null)
-//                     repositoryServiceFactory.shutdown();
-
-               if (kernelThread != null)
-                       kernelThread.destroyAndJoin();
-
-               bundleContext = null;
-       }
-
-       @Deprecated
-       public static <T> void registerService(Class<T> clss, T service, Dictionary<String, ?> properties) {
-               if (bundleContext != null) {
-                       bundleContext.registerService(clss, service, properties);
-               }
-
-       }
-
-       @Deprecated
-       public static BundleContext getBundleContext() {
-               return bundleContext;
-       }
-
-       @Deprecated
-       public static <T> T getService(Class<T> clss) {
-               if (bundleContext != null) {
-                       return bundleContext.getService(bundleContext.getServiceReference(clss));
-               } else {
-                       return null;
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java
deleted file mode 100644 (file)
index fa3f87f..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import java.util.Map;
-
-import javax.jcr.Repository;
-
-import org.apache.jackrabbit.server.SessionProvider;
-import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet;
-import org.argeo.api.cms.CmsConstants;
-
-/** A {@link JcrRemotingServlet} based on {@link CmsSessionProvider}. */
-public class CmsRemotingServlet extends JcrRemotingServlet {
-       private static final long serialVersionUID = 6459455509684213633L;
-       private Repository repository;
-       private SessionProvider sessionProvider;
-
-       public CmsRemotingServlet() {
-       }
-
-       public CmsRemotingServlet(String alias, Repository repository) {
-               this.repository = repository;
-               this.sessionProvider = new CmsSessionProvider(alias);
-       }
-
-       @Override
-       public Repository getRepository() {
-               return repository;
-       }
-
-       public void setRepository(Repository repository, Map<String, String> properties) {
-               this.repository = repository;
-               String alias = properties.get(CmsConstants.CN);
-               if (alias != null)
-                       sessionProvider = new CmsSessionProvider(alias);
-               else
-                       throw new IllegalArgumentException("Only aliased repositories are supported");
-       }
-
-       @Override
-       protected SessionProvider getSessionProvider() {
-               return sessionProvider;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java
deleted file mode 100644 (file)
index 4e067ee..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import java.io.Serializable;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.CmsSession;
-import org.argeo.cms.auth.RemoteAuthUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-import org.argeo.jcr.JcrUtils;
-
-/**
- * Implements an open session in view patter: a new JCR session is created for
- * each request
- */
-public class CmsSessionProvider implements SessionProvider, Serializable {
-       private static final long serialVersionUID = -1358136599534938466L;
-
-       private final static CmsLog log = CmsLog.getLog(CmsSessionProvider.class);
-
-       private final String alias;
-
-       private LinkedHashMap<Session, CmsDataSession> cmsSessions = new LinkedHashMap<>();
-
-       public CmsSessionProvider(String alias) {
-               this.alias = alias;
-       }
-
-       public Session getSession(HttpServletRequest request, Repository rep, String workspace)
-                       throws javax.jcr.LoginException, ServletException, RepositoryException {
-
-               // a client is scanning parent URLs.
-//             if (workspace == null)
-//                     return null;
-
-               CmsSession cmsSession = RemoteAuthUtils.getCmsSession(new ServletHttpRequest(request));
-               // CmsSessionImpl cmsSession = WebCmsSessionImpl.getCmsSession(request);
-               if (log.isTraceEnabled()) {
-                       log.trace("Get JCR session from " + cmsSession);
-               }
-               if (cmsSession == null)
-                       throw new IllegalStateException("Cannot find a session for request " + request.getRequestURI());
-               CmsDataSession cmsDataSession = new CmsDataSession(cmsSession);
-               Session session = cmsDataSession.getDataSession(alias, workspace, rep);
-               cmsSessions.put(session, cmsDataSession);
-               return session;
-       }
-
-       public void releaseSession(Session session) {
-//             JcrUtils.logoutQuietly(session);
-               if (cmsSessions.containsKey(session)) {
-                       CmsDataSession cmsDataSession = cmsSessions.get(session);
-                       cmsDataSession.releaseDataSession(alias, session);
-               } else {
-                       log.warn("JCR session " + session + " not found in CMS session list. Logging it out...");
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       static class CmsDataSession {
-               private CmsSession cmsSession;
-
-               private Map<String, Session> dataSessions = new HashMap<>();
-               private Set<String> dataSessionsInUse = new HashSet<>();
-               private Set<Session> additionalDataSessions = new HashSet<>();
-
-               private CmsDataSession(CmsSession cmsSession) {
-                       this.cmsSession = cmsSession;
-                       cmsSession.addOnCloseCallback((sess) -> close());
-               }
-
-               public Session newDataSession(String cn, String workspace, Repository repository) {
-                       checkValid();
-                       return login(repository, workspace);
-               }
-
-               public synchronized Session getDataSession(String cn, String workspace, Repository repository) {
-                       checkValid();
-                       // FIXME make it more robust
-                       if (workspace == null)
-                               workspace = CmsConstants.SYS_WORKSPACE;
-                       String path = cn + '/' + workspace;
-                       if (dataSessionsInUse.contains(path)) {
-                               try {
-                                       wait(1000);
-                                       if (dataSessionsInUse.contains(path)) {
-                                               Session session = login(repository, workspace);
-                                               additionalDataSessions.add(session);
-                                               if (log.isTraceEnabled())
-                                                       log.trace("Additional data session " + path + " for " + cmsSession.getUserDn());
-                                               return session;
-                                       }
-                               } catch (InterruptedException e) {
-                                       // silent
-                               }
-                       }
-
-                       Session session = null;
-                       if (dataSessions.containsKey(path)) {
-                               session = dataSessions.get(path);
-                       } else {
-                               session = login(repository, workspace);
-                               dataSessions.put(path, session);
-                               if (log.isTraceEnabled())
-                                       log.trace("New data session " + path + " for " + cmsSession.getUserDn());
-                       }
-                       dataSessionsInUse.add(path);
-                       return session;
-               }
-
-               private Session login(Repository repository, String workspace) {
-                       try {
-                               return Subject.doAs(cmsSession.getSubject(), new PrivilegedExceptionAction<Session>() {
-                                       @Override
-                                       public Session run() throws Exception {
-                                               return repository.login(workspace);
-                                       }
-                               });
-                       } catch (PrivilegedActionException e) {
-                               throw new IllegalStateException("Cannot log in " + cmsSession.getUserDn() + " to JCR", e);
-                       }
-               }
-
-               public synchronized void releaseDataSession(String cn, Session session) {
-                       if (additionalDataSessions.contains(session)) {
-                               JcrUtils.logoutQuietly(session);
-                               additionalDataSessions.remove(session);
-                               if (log.isTraceEnabled())
-                                       log.trace("Remove additional data session " + session);
-                               return;
-                       }
-                       String path = cn + '/' + session.getWorkspace().getName();
-                       if (!dataSessionsInUse.contains(path))
-                               log.warn("Data session " + path + " was not in use for " + cmsSession.getUserDn());
-                       dataSessionsInUse.remove(path);
-                       Session registeredSession = dataSessions.get(path);
-                       if (session != registeredSession)
-                               log.warn("Data session " + path + " not consistent for " + cmsSession.getUserDn());
-                       if (log.isTraceEnabled())
-                               log.trace("Released data session " + session + " for " + path);
-                       notifyAll();
-               }
-
-               private void checkValid() {
-                       if (!cmsSession.isValid())
-                               throw new IllegalStateException(
-                                               "CMS session " + cmsSession.getUuid() + " is not valid since " + cmsSession.getEnd());
-               }
-
-               protected void close() {
-                       synchronized (this) {
-                               // TODO check data session in use ?
-                               for (String path : dataSessions.keySet())
-                                       JcrUtils.logoutQuietly(dataSessions.get(path));
-                               for (Session session : additionalDataSessions)
-                                       JcrUtils.logoutQuietly(session);
-                       }
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java
deleted file mode 100644 (file)
index 0f0858f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import java.util.Map;
-
-import javax.jcr.Repository;
-
-import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet;
-import org.argeo.api.cms.CmsConstants;
-
-/** A {@link SimpleWebdavServlet} based on {@link CmsSessionProvider}. */
-public class CmsWebDavServlet extends SimpleWebdavServlet {
-       private static final long serialVersionUID = 7485800288686328063L;
-       private Repository repository;
-
-       public CmsWebDavServlet() {
-       }
-
-       public CmsWebDavServlet(String alias, Repository repository) {
-               this.repository = repository;
-               setSessionProvider(new CmsSessionProvider(alias));
-       }
-
-       @Override
-       public Repository getRepository() {
-               return repository;
-       }
-
-       public void setRepository(Repository repository, Map<String, String> properties) {
-               this.repository = repository;
-               String alias = properties.get(CmsConstants.CN);
-               if (alias != null)
-                       setSessionProvider(new CmsSessionProvider(alias));
-               else
-                       throw new IllegalArgumentException("Only aliased repositories are supported");
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/DataServletContext.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/DataServletContext.java
deleted file mode 100644 (file)
index 2f60e97..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import org.argeo.cms.servlet.CmsServletContext;
-
-/** Internal subclass, so that config resources can be loaded from our bundle. */
-public class DataServletContext extends CmsServletContext {
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java
deleted file mode 100644 (file)
index 11e903d..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import java.util.Enumeration;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.api.cms.CmsLog;
-
-public class JcrHttpUtils {
-       public final static String HEADER_AUTHORIZATION = "Authorization";
-       public final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
-
-       public final static String DEFAULT_PROTECTED_HANDLERS = "/org/argeo/cms/jcr/internal/servlet/protectedHandlers.xml";
-       public final static String WEBDAV_CONFIG = "/org/argeo/cms/jcr/internal/servlet/webdav-config.xml";
-
-       static boolean isBrowser(String userAgent) {
-               return userAgent.contains("webkit") || userAgent.contains("gecko") || userAgent.contains("firefox")
-                               || userAgent.contains("msie") || userAgent.contains("chrome") || userAgent.contains("chromium")
-                               || userAgent.contains("opera") || userAgent.contains("browser");
-       }
-
-       public static void logResponseHeaders(CmsLog log, HttpServletResponse response) {
-               if (!log.isDebugEnabled())
-                       return;
-               for (String headerName : response.getHeaderNames()) {
-                       Object headerValue = response.getHeader(headerName);
-                       log.debug(headerName + ": " + headerValue);
-               }
-       }
-
-       public static void logRequestHeaders(CmsLog log, HttpServletRequest request) {
-               if (!log.isDebugEnabled())
-                       return;
-               for (Enumeration<String> headerNames = request.getHeaderNames(); headerNames.hasMoreElements();) {
-                       String headerName = headerNames.nextElement();
-                       Object headerValue = request.getHeader(headerName);
-                       log.debug(headerName + ": " + headerValue);
-               }
-               log.debug(request.getRequestURI() + "\n");
-       }
-
-       public static void logRequest(CmsLog log, HttpServletRequest request) {
-               log.debug("contextPath=" + request.getContextPath());
-               log.debug("servletPath=" + request.getServletPath());
-               log.debug("requestURI=" + request.getRequestURI());
-               log.debug("queryString=" + request.getQueryString());
-               StringBuilder buf = new StringBuilder();
-               // headers
-               Enumeration<String> en = request.getHeaderNames();
-               while (en.hasMoreElements()) {
-                       String header = en.nextElement();
-                       Enumeration<String> values = request.getHeaders(header);
-                       while (values.hasMoreElements())
-                               buf.append("  " + header + ": " + values.nextElement());
-                       buf.append('\n');
-               }
-
-               // attributed
-               Enumeration<String> an = request.getAttributeNames();
-               while (an.hasMoreElements()) {
-                       String attr = an.nextElement();
-                       Object value = request.getAttribute(attr);
-                       buf.append("  " + attr + ": " + value);
-                       buf.append('\n');
-               }
-               log.debug("\n" + buf);
-       }
-
-       private JcrHttpUtils() {
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrReadServlet.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrReadServlet.java
deleted file mode 100644 (file)
index b0cd789..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.security.AccessControlContext;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeType;
-import javax.security.auth.Subject;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.api.JackrabbitNode;
-import org.apache.jackrabbit.api.JackrabbitValue;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.integration.CmsExceptionsChain;
-import org.argeo.jcr.JcrUtils;
-import org.osgi.service.http.context.ServletContextHelper;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/** Access a JCR repository via web services. */
-public class JcrReadServlet extends HttpServlet {
-       private static final long serialVersionUID = 6536175260540484539L;
-       private final static CmsLog log = CmsLog.getLog(JcrReadServlet.class);
-
-       protected final static String ACCEPT_HTTP_HEADER = "Accept";
-       protected final static String CONTENT_DISPOSITION_HTTP_HEADER = "Content-Disposition";
-
-       protected final static String OCTET_STREAM_CONTENT_TYPE = "application/octet-stream";
-       protected final static String XML_CONTENT_TYPE = "application/xml";
-       protected final static String JSON_CONTENT_TYPE = "application/json";
-
-       private final static String PARAM_VERBOSE = "verbose";
-       private final static String PARAM_DEPTH = "depth";
-
-       protected final static String JCR_NODES = "jcr:nodes";
-       // cf. javax.jcr.Property
-       protected final static String JCR_PATH = "path";
-       protected final static String JCR_NAME = "name";
-
-       protected final static String _JCR = "_jcr";
-       protected final static String JCR_PREFIX = "jcr:";
-       protected final static String REP_PREFIX = "rep:";
-
-       private Repository repository;
-       private Integer maxDepth = 8;
-
-       private ObjectMapper objectMapper = new ObjectMapper();
-
-       @Override
-       protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-               if (log.isTraceEnabled())
-                       log.trace("Data service: " + req.getPathInfo());
-
-               String dataWorkspace = getWorkspace(req);
-               String jcrPath = getJcrPath(req);
-
-               boolean verbose = req.getParameter(PARAM_VERBOSE) != null && !req.getParameter(PARAM_VERBOSE).equals("false");
-               int depth = 1;
-               if (req.getParameter(PARAM_DEPTH) != null) {
-                       depth = Integer.parseInt(req.getParameter(PARAM_DEPTH));
-                       if (depth > maxDepth)
-                               throw new RuntimeException("Depth " + depth + " is higher than maximum " + maxDepth);
-               }
-
-               Session session = null;
-               try {
-                       // authentication
-                       session = openJcrSession(req, resp, getRepository(), dataWorkspace);
-                       if (!session.itemExists(jcrPath))
-                               throw new RuntimeException("JCR node " + jcrPath + " does not exist");
-                       Node node = session.getNode(jcrPath);
-
-                       List<String> acceptHeader = readAcceptHeader(req);
-                       if (!acceptHeader.isEmpty() && node.isNodeType(NodeType.NT_FILE)) {
-                               resp.setContentType(OCTET_STREAM_CONTENT_TYPE);
-                               resp.addHeader(CONTENT_DISPOSITION_HTTP_HEADER, "attachment; filename='" + node.getName() + "'");
-                               IOUtils.copy(JcrUtils.getFileAsStream(node), resp.getOutputStream());
-                               resp.flushBuffer();
-                       } else {
-                               if (!acceptHeader.isEmpty() && acceptHeader.get(0).equals(XML_CONTENT_TYPE)) {
-                                       // TODO Use req.startAsync(); ?
-                                       resp.setContentType(XML_CONTENT_TYPE);
-                                       session.exportSystemView(node.getPath(), resp.getOutputStream(), false, depth <= 1);
-                                       return;
-                               }
-                               if (!acceptHeader.isEmpty() && !acceptHeader.contains(JSON_CONTENT_TYPE)) {
-                                       if (log.isTraceEnabled())
-                                               log.warn("Content type " + acceptHeader + " in Accept header is not supported. Supported: "
-                                                               + JSON_CONTENT_TYPE + " (default), " + XML_CONTENT_TYPE);
-                               }
-                               resp.setContentType(JSON_CONTENT_TYPE);
-                               JsonGenerator jsonGenerator = getObjectMapper().getFactory().createGenerator(resp.getWriter());
-                               jsonGenerator.writeStartObject();
-                               writeNodeChildren(node, jsonGenerator, depth, verbose);
-                               writeNodeProperties(node, jsonGenerator, verbose);
-                               jsonGenerator.writeEndObject();
-                               jsonGenerator.flush();
-                       }
-               } catch (Exception e) {
-                       new CmsExceptionsChain(e).writeAsJson(getObjectMapper(), resp);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       protected Session openJcrSession(HttpServletRequest req, HttpServletResponse resp, Repository repository,
-                       String workspace) throws RepositoryException {
-               AccessControlContext acc = (AccessControlContext) req.getAttribute(ServletContextHelper.REMOTE_USER);
-               Subject subject = Subject.getSubject(acc);
-               try {
-                       return Subject.doAs(subject, new PrivilegedExceptionAction<Session>() {
-
-                               @Override
-                               public Session run() throws RepositoryException {
-                                       return repository.login(workspace);
-                               }
-
-                       });
-               } catch (PrivilegedActionException e) {
-                       if (e.getException() instanceof RepositoryException)
-                               throw (RepositoryException) e.getException();
-                       else
-                               throw new RuntimeException(e.getException());
-               }
-//             return workspace != null ? repository.login(workspace) : repository.login();
-       }
-
-       protected String getWorkspace(HttpServletRequest req) {
-               String path = req.getPathInfo();
-               try {
-                       path = URLDecoder.decode(path, StandardCharsets.UTF_8.name());
-               } catch (UnsupportedEncodingException e) {
-                       throw new IllegalArgumentException(e);
-               }
-               String[] pathTokens = path.split("/");
-               return pathTokens[1];
-       }
-
-       protected String getJcrPath(HttpServletRequest req) {
-               String path = req.getPathInfo();
-               try {
-                       path = URLDecoder.decode(path, StandardCharsets.UTF_8.name());
-               } catch (UnsupportedEncodingException e) {
-                       throw new IllegalArgumentException(e);
-               }
-               String[] pathTokens = path.split("/");
-               String domain = pathTokens[1];
-               String jcrPath = path.substring(domain.length() + 1);
-               return jcrPath;
-       }
-
-       protected List<String> readAcceptHeader(HttpServletRequest req) {
-               List<String> lst = new ArrayList<>();
-               String acceptHeader = req.getHeader(ACCEPT_HTTP_HEADER);
-               if (acceptHeader == null)
-                       return lst;
-//             Enumeration<String> acceptHeader = req.getHeaders(ACCEPT_HTTP_HEADER);
-//             while (acceptHeader.hasMoreElements()) {
-               String[] arr = acceptHeader.split("\\.");
-               for (int i = 0; i < arr.length; i++) {
-                       String str = arr[i].trim();
-                       if (!"".equals(str))
-                               lst.add(str);
-               }
-//             }
-               return lst;
-       }
-
-       protected void writeNodeProperties(Node node, JsonGenerator jsonGenerator, boolean verbose)
-                       throws RepositoryException, IOException {
-               String jcrPath = node.getPath();
-               Map<String, Map<String, Property>> namespaces = new TreeMap<>();
-
-               PropertyIterator pit = node.getProperties();
-               properties: while (pit.hasNext()) {
-                       Property property = pit.nextProperty();
-
-                       final String propertyName = property.getName();
-                       int columnIndex = propertyName.indexOf(':');
-                       if (columnIndex > 0) {
-                               // mark prefix with a '_' before the name of the object, according to JSON
-                               // conventions to indicate a special value
-                               String prefix = "_" + propertyName.substring(0, columnIndex);
-                               String unqualifiedName = propertyName.substring(columnIndex + 1);
-                               if (!namespaces.containsKey(prefix))
-                                       namespaces.put(prefix, new LinkedHashMap<String, Property>());
-                               Map<String, Property> map = namespaces.get(prefix);
-                               assert !map.containsKey(unqualifiedName);
-                               map.put(unqualifiedName, property);
-                               continue properties;
-                       }
-
-                       if (property.getType() == PropertyType.BINARY) {
-                               if (!(node instanceof JackrabbitNode)) {
-                                       continue properties;// skip
-                               }
-                       }
-
-                       writeProperty(propertyName, property, jsonGenerator);
-               }
-
-               for (String prefix : namespaces.keySet()) {
-                       Map<String, Property> map = namespaces.get(prefix);
-                       jsonGenerator.writeFieldName(prefix);
-                       jsonGenerator.writeStartObject();
-                       if (_JCR.equals(prefix)) {
-                               jsonGenerator.writeStringField(JCR_NAME, node.getName());
-                               jsonGenerator.writeStringField(JCR_PATH, jcrPath);
-                       }
-                       properties: for (String unqualifiedName : map.keySet()) {
-                               Property property = map.get(unqualifiedName);
-                               if (property.getType() == PropertyType.BINARY) {
-                                       if (!(node instanceof JackrabbitNode)) {
-                                               continue properties;// skip
-                                       }
-                               }
-                               writeProperty(unqualifiedName, property, jsonGenerator);
-                       }
-                       jsonGenerator.writeEndObject();
-               }
-       }
-
-       protected void writeProperty(String fieldName, Property property, JsonGenerator jsonGenerator)
-                       throws RepositoryException, IOException {
-               if (!property.isMultiple()) {
-                       jsonGenerator.writeFieldName(fieldName);
-                       writePropertyValue(property.getType(), property.getValue(), jsonGenerator);
-               } else {
-                       jsonGenerator.writeFieldName(fieldName);
-                       jsonGenerator.writeStartArray();
-                       Value[] values = property.getValues();
-                       for (Value value : values) {
-                               writePropertyValue(property.getType(), value, jsonGenerator);
-                       }
-                       jsonGenerator.writeEndArray();
-               }
-       }
-
-       protected void writePropertyValue(int type, Value value, JsonGenerator jsonGenerator)
-                       throws RepositoryException, IOException {
-               if (type == PropertyType.DOUBLE)
-                       jsonGenerator.writeNumber(value.getDouble());
-               else if (type == PropertyType.LONG)
-                       jsonGenerator.writeNumber(value.getLong());
-               else if (type == PropertyType.BINARY) {
-                       if (value instanceof JackrabbitValue) {
-                               String contentIdentity = ((JackrabbitValue) value).getContentIdentity();
-                               jsonGenerator.writeString("SHA256:" + contentIdentity);
-                       } else {
-                               // TODO write Base64 ?
-                               jsonGenerator.writeNull();
-                       }
-               } else
-                       jsonGenerator.writeString(value.getString());
-       }
-
-       protected void writeNodeChildren(Node node, JsonGenerator jsonGenerator, int depth, boolean verbose)
-                       throws RepositoryException, IOException {
-               if (!node.hasNodes())
-                       return;
-               if (depth <= 0)
-                       return;
-               NodeIterator nit;
-
-               nit = node.getNodes();
-               children: while (nit.hasNext()) {
-                       Node child = nit.nextNode();
-                       if (!verbose && child.getName().startsWith(REP_PREFIX)) {
-                               continue children;// skip Jackrabbit auth metadata
-                       }
-
-                       jsonGenerator.writeFieldName(child.getName());
-                       jsonGenerator.writeStartObject();
-                       writeNodeChildren(child, jsonGenerator, depth - 1, verbose);
-                       writeNodeProperties(child, jsonGenerator, verbose);
-                       jsonGenerator.writeEndObject();
-               }
-       }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setMaxDepth(Integer maxDepth) {
-               this.maxDepth = maxDepth;
-       }
-
-       protected Repository getRepository() {
-               return repository;
-       }
-
-       protected ObjectMapper getObjectMapper() {
-               return objectMapper;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrServletContext.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrServletContext.java
deleted file mode 100644 (file)
index 21046f3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import org.argeo.cms.servlet.PrivateWwwAuthServletContext;
-
-/** Internal subclass, so that config resources can be loaded from our bundle. */
-public class JcrServletContext extends PrivateWwwAuthServletContext {
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrWriteServlet.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrWriteServlet.java
deleted file mode 100644 (file)
index 459a1e4..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import java.io.IOException;
-
-import javax.jcr.ImportUUIDBehavior;
-import javax.jcr.Node;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.integration.CmsExceptionsChain;
-import org.argeo.jcr.JcrUtils;
-
-/** Access a JCR repository via web services. */
-public class JcrWriteServlet extends JcrReadServlet {
-       private static final long serialVersionUID = 17272653843085492L;
-       private final static CmsLog log = CmsLog.getLog(JcrWriteServlet.class);
-
-       @Override
-       protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-               if (log.isDebugEnabled())
-                       log.debug("Data service POST: " + req.getPathInfo());
-
-               String dataWorkspace = getWorkspace(req);
-               String jcrPath = getJcrPath(req);
-
-               Session session = null;
-               try {
-                       // authentication
-                       session = openJcrSession(req, resp, getRepository(), dataWorkspace);
-
-                       if (req.getContentType() != null && req.getContentType().equals(XML_CONTENT_TYPE)) {
-//                             resp.setContentType(XML_CONTENT_TYPE);
-                               session.getWorkspace().importXML(jcrPath, req.getInputStream(),
-                                               ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
-                               return;
-                       }
-
-                       if (!session.itemExists(jcrPath)) {
-                               String parentPath = FilenameUtils.getFullPathNoEndSeparator(jcrPath);
-                               String fileName = FilenameUtils.getName(jcrPath);
-                               Node folderNode = JcrUtils.mkfolders(session, parentPath);
-                               byte[] bytes = IOUtils.toByteArray(req.getInputStream());
-                               JcrUtils.copyBytesAsFile(folderNode, fileName, bytes);
-                       } else {
-                               Node node = session.getNode(jcrPath);
-                               if (!node.isNodeType(NodeType.NT_FILE))
-                                       throw new IllegalArgumentException("Node " + jcrPath + " exists but is not a file");
-                               byte[] bytes = IOUtils.toByteArray(req.getInputStream());
-                               JcrUtils.copyBytesAsFile(node.getParent(), node.getName(), bytes);
-                       }
-                       session.save();
-               } catch (Exception e) {
-                       new CmsExceptionsChain(e).writeAsJson(getObjectMapper(), resp);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       @Override
-       protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-               if (log.isDebugEnabled())
-                       log.debug("Data service DELETE: " + req.getPathInfo());
-
-               String dataWorkspace = getWorkspace(req);
-               String jcrPath = getJcrPath(req);
-
-               Session session = null;
-               try {
-                       // authentication
-                       session = openJcrSession(req, resp, getRepository(), dataWorkspace);
-                       if (!session.itemExists(jcrPath)) {
-                               // ignore
-                               return;
-                       } else {
-                               Node node = session.getNode(jcrPath);
-                               node.remove();
-                       }
-                       session.save();
-               } catch (Exception e) {
-                       new CmsExceptionsChain(e).writeAsJson(getObjectMapper(), resp);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java
deleted file mode 100644 (file)
index be5684a..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-package org.argeo.cms.jcr.internal.servlet;
-
-import static javax.jcr.Property.JCR_DESCRIPTION;
-import static javax.jcr.Property.JCR_LAST_MODIFIED;
-import static javax.jcr.Property.JCR_TITLE;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.PrivilegedExceptionAction;
-import java.util.Calendar;
-import java.util.Collection;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.api.cms.CmsAuth;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.jcr.JcrUtils;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-
-public class LinkServlet extends HttpServlet {
-       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-       private static final long serialVersionUID = 3749990143146845708L;
-
-       @Override
-       protected void service(HttpServletRequest request, HttpServletResponse response)
-                       throws ServletException, IOException {
-               String path = request.getPathInfo();
-               String userAgent = request.getHeader("User-Agent").toLowerCase();
-               boolean isBot = false;
-               // boolean isCompatibleBrowser = false;
-               if (userAgent.contains("bot") || userAgent.contains("facebook") || userAgent.contains("twitter")) {
-                       isBot = true;
-               }
-               // else if (userAgent.contains("webkit") ||
-               // userAgent.contains("gecko") || userAgent.contains("firefox")
-               // || userAgent.contains("msie") || userAgent.contains("chrome") ||
-               // userAgent.contains("chromium")
-               // || userAgent.contains("opera") || userAgent.contains("browser"))
-               // {
-               // isCompatibleBrowser = true;
-               // }
-
-               if (isBot) {
-                       // log.warn("# BOT " + request.getHeader("User-Agent"));
-                       canonicalAnswer(request, response, path);
-                       return;
-               }
-
-               // if (isCompatibleBrowser && log.isTraceEnabled())
-               // log.trace("# BWS " + request.getHeader("User-Agent"));
-               redirectTo(response, "/#" + path);
-       }
-
-       private void redirectTo(HttpServletResponse response, String location) {
-               response.setHeader("Location", location);
-               response.setStatus(HttpServletResponse.SC_FOUND);
-       }
-
-       // private boolean canonicalAnswerNeededBy(HttpServletRequest request) {
-       // String userAgent = request.getHeader("User-Agent").toLowerCase();
-       // return userAgent.startsWith("facebookexternalhit/");
-       // }
-
-       /** For bots which don't understand RWT. */
-       private void canonicalAnswer(HttpServletRequest request, HttpServletResponse response, String path) {
-               Session session = null;
-               try {
-                       PrintWriter writer = response.getWriter();
-                       session = Subject.doAs(anonymousLogin(), new PrivilegedExceptionAction<Session>() {
-
-                               @Override
-                               public Session run() throws Exception {
-                                       Collection<ServiceReference<Repository>> srs = bc.getServiceReferences(Repository.class,
-                                                       "(" + CmsConstants.CN + "=" + CmsConstants.EGO_REPOSITORY + ")");
-                                       Repository repository = bc.getService(srs.iterator().next());
-                                       return repository.login();
-                               }
-
-                       });
-                       Node node = session.getNode(path);
-                       String title = node.hasProperty(JCR_TITLE) ? node.getProperty(JCR_TITLE).getString() : node.getName();
-                       String desc = node.hasProperty(JCR_DESCRIPTION) ? node.getProperty(JCR_DESCRIPTION).getString() : null;
-                       Calendar lastUpdate = node.hasProperty(JCR_LAST_MODIFIED) ? node.getProperty(JCR_LAST_MODIFIED).getDate()
-                                       : null;
-                       String url = getCanonicalUrl(node, request);
-                       String imgUrl = null;
-                       // TODO support images
-//                     loop: for (NodeIterator it = node.getNodes(); it.hasNext();) {
-//                             // Takes the first found cms:image
-//                             Node child = it.nextNode();
-//                             if (child.isNodeType(CMS_IMAGE)) {
-//                                     imgUrl = getDataUrl(child, request);
-//                                     break loop;
-//                             }
-//                     }
-                       StringBuilder buf = new StringBuilder();
-                       buf.append("<html>");
-                       buf.append("<head>");
-                       writeMeta(buf, "og:title", escapeHTML(title));
-                       writeMeta(buf, "og:type", "website");
-                       buf.append("<meta name='twitter:card' content='summary' />");
-                       buf.append("<meta name='twitter:site' content='@argeo_org' />");
-                       writeMeta(buf, "og:url", url);
-                       if (desc != null)
-                               writeMeta(buf, "og:description", escapeHTML(desc));
-                       if (imgUrl != null)
-                               writeMeta(buf, "og:image", imgUrl);
-                       if (lastUpdate != null)
-                               writeMeta(buf, "og:updated_time", Long.toString(lastUpdate.getTime().getTime()));
-                       buf.append("</head>");
-                       buf.append("<body>");
-                       buf.append("<p><b>!! This page is meant for indexing robots, not for real people," + " visit <a href='/#")
-                                       .append(path).append("'>").append(escapeHTML(title)).append("</a> instead.</b></p>");
-                       writeCanonical(buf, node);
-                       buf.append("</body>");
-                       buf.append("</html>");
-                       writer.print(buf.toString());
-
-                       response.setHeader("Content-Type", "text/html");
-                       writer.flush();
-               } catch (Exception e) {
-                       throw new IllegalStateException("Cannot write canonical answer", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       /**
-        * From http://stackoverflow.com/questions/1265282/recommended-method-for-
-        * escaping-html-in-java (+ escaping '). TODO Use
-        * org.apache.commons.lang.StringEscapeUtils
-        */
-       private String escapeHTML(String s) {
-               StringBuilder out = new StringBuilder(Math.max(16, s.length()));
-               for (int i = 0; i < s.length(); i++) {
-                       char c = s.charAt(i);
-                       if (c > 127 || c == '\'' || c == '"' || c == '<' || c == '>' || c == '&') {
-                               out.append("&#");
-                               out.append((int) c);
-                               out.append(';');
-                       } else {
-                               out.append(c);
-                       }
-               }
-               return out.toString();
-       }
-
-       private void writeMeta(StringBuilder buf, String tag, String value) {
-               buf.append("<meta property='").append(tag).append("' content='").append(value).append("'/>");
-       }
-
-       private void writeCanonical(StringBuilder buf, Node node) throws RepositoryException {
-               buf.append("<div>");
-               if (node.hasProperty(JCR_TITLE))
-                       buf.append("<p>").append(node.getProperty(JCR_TITLE).getString()).append("</p>");
-               if (node.hasProperty(JCR_DESCRIPTION))
-                       buf.append("<p>").append(node.getProperty(JCR_DESCRIPTION).getString()).append("</p>");
-               NodeIterator children = node.getNodes();
-               while (children.hasNext()) {
-                       writeCanonical(buf, children.nextNode());
-               }
-               buf.append("</div>");
-       }
-
-       // DATA
-       private StringBuilder getServerBaseUrl(HttpServletRequest request) {
-               try {
-                       URL url = new URL(request.getRequestURL().toString());
-                       StringBuilder buf = new StringBuilder();
-                       buf.append(url.getProtocol()).append("://").append(url.getHost());
-                       if (url.getPort() != -1)
-                               buf.append(':').append(url.getPort());
-                       return buf;
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot extract server base URL from " + request.getRequestURL(), e);
-               }
-       }
-
-       private String getDataUrl(Node node, HttpServletRequest request) throws RepositoryException {
-               try {
-                       StringBuilder buf = getServerBaseUrl(request);
-                       buf.append(CmsJcrUtils.getDataPath(CmsConstants.EGO_REPOSITORY, node));
-                       return new URL(buf.toString()).toString();
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot build data URL for " + node, e);
-               }
-       }
-
-       // public static String getDataPath(Node node) throws
-       // RepositoryException {
-       // assert node != null;
-       // String userId = node.getSession().getUserID();
-       //// if (log.isTraceEnabled())
-       //// log.trace(userId + " : " + node.getPath());
-       // StringBuilder buf = new StringBuilder();
-       // boolean isAnonymous =
-       // userId.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS);
-       // if (isAnonymous)
-       // buf.append(WEBDAV_PUBLIC);
-       // else
-       // buf.append(WEBDAV_PRIVATE);
-       // Session session = node.getSession();
-       // Repository repository = session.getRepository();
-       // String cn;
-       // if (repository.isSingleValueDescriptor(NodeConstants.CN)) {
-       // cn = repository.getDescriptor(NodeConstants.CN);
-       // } else {
-       //// log.warn("No cn defined in repository, using " +
-       // NodeConstants.NODE);
-       // cn = NodeConstants.NODE;
-       // }
-       // return
-       // buf.append('/').append(cn).append('/').append(session.getWorkspace().getName()).append(node.getPath())
-       // .toString();
-       // }
-
-       private String getCanonicalUrl(Node node, HttpServletRequest request) throws RepositoryException {
-               try {
-                       StringBuilder buf = getServerBaseUrl(request);
-                       buf.append('/').append('!').append(node.getPath());
-                       return new URL(buf.toString()).toString();
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot build data URL for " + node, e);
-               }
-               // return request.getRequestURL().append('!').append(node.getPath())
-               // .toString();
-       }
-
-       private Subject anonymousLogin() {
-               Subject subject = new Subject();
-               LoginContext lc;
-               try {
-                       lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS, subject);
-                       lc.login();
-                       return subject;
-               } catch (LoginException e) {
-                       throw new IllegalStateException("Cannot login as anonymous", e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/protectedHandlers.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/protectedHandlers.xml
deleted file mode 100644 (file)
index 59f22cd..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<config>
-       <protecteditemremovehandler>
-               <class name="org.apache.jackrabbit.server.remoting.davex.AclRemoveHandler" />
-       </protecteditemremovehandler>
-</config>
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/webdav-config.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/webdav-config.xml
deleted file mode 100644 (file)
index 4363898..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-  -->
-<!--
-<!DOCTYPE config [
-        <!ELEMENT config (iomanager , propertymanager, (collection | noncollection)? , filter?, mimetypeproperties?) >
-
-        <!ELEMENT iomanager (class, iohandler*) >
-        <!ELEMENT iohandler (class) >
-
-        <!ELEMENT propertymanager (class, propertyhandler*) >
-        <!ELEMENT propertyhandler (class) >
-
-        <!ELEMENT collection (nodetypes) >
-        <!ELEMENT noncollection (nodetypes) >
-
-        <!ELEMENT filter (class, namespaces?, nodetypes?) >
-
-        <!ELEMENT class >
-        <!ATTLIST class
-            name  CDATA #REQUIRED
-        >
-        <!ELEMENT namespaces (prefix | uri)* >
-        <!ELEMENT prefix (CDATA) >
-        <!ELEMENT uri (CDATA) >
-
-        <!ELEMENT nodetypes (nodetype)* >
-        <!ELEMENT nodetype (CDATA) >
-
-        <!ELEMENT mimetypeproperties (mimemapping*, defaultmimetype) >
-
-        <!ELEMENT mimemapping >
-        <!ATTLIST mimemapping
-            extension  CDATA #REQUIRED
-            mimetype  CDATA #REQUIRED
-        >
-
-        <!ELEMENT defaultmimetype (CDATA) >
-]>
--->
-
-<config>
-    <!--
-     Defines the IOManager implementation that is responsible for passing
-     import/export request to the individual IO-handlers.
-    -->
-    <iomanager>
-        <!-- class element defines the manager to be used. The specified class
-             must implement the IOManager interface.
-             Note, that the handlers are being added and called in the order
-             they appear in the configuration.
-        -->
-        <class name="org.apache.jackrabbit.server.io.IOManagerImpl" />
-        <iohandler>
-            <class name="org.apache.jackrabbit.server.io.VersionHandler" />
-        </iohandler>
-        <iohandler>
-            <class name="org.apache.jackrabbit.server.io.VersionHistoryHandler" />
-        </iohandler>
-<!--         <iohandler> -->
-<!--             <class name="org.apache.jackrabbit.server.io.ZipHandler" /> -->
-<!--         </iohandler> -->
-<!--         <iohandler> -->
-<!--             <class name="org.apache.jackrabbit.server.io.XmlHandler" /> -->
-<!--         </iohandler> -->
-        <iohandler>
-            <class name="org.apache.jackrabbit.server.io.DirListingExportHandler" />
-        </iohandler>
-        <iohandler>
-            <class name="org.apache.jackrabbit.server.io.DefaultHandler" />
-        </iohandler>
-    </iomanager>
-    <!--
-     Example config for iomanager that populates its list of handlers with
-     default values. Therefore the 'iohandler' elements are omited.
-    -->
-    <!--
-    <iomanager>
-        <class name="org.apache.jackrabbit.server.io.DefaultIOManager" />
-    </iomanager>
-    -->
-    <!--
-     Defines the PropertyManager implementation that is responsible for export
-     and import of resource properties.
-    -->
-    <propertymanager>
-        <!-- class element defines the manager to be used. The specified class
-             must implement the PropertyManager interface.
-             Note, that the handlers are being added and called in the order
-             they appear in the configuration.
-        -->
-        <class name="org.apache.jackrabbit.server.io.PropertyManagerImpl" />
-        <propertyhandler>
-            <class name="org.apache.jackrabbit.server.io.VersionHandler" />
-        </propertyhandler>
-        <propertyhandler>
-            <class name="org.apache.jackrabbit.server.io.VersionHistoryHandler" />
-        </propertyhandler>
-<!--         <propertyhandler> -->
-<!--             <class name="org.apache.jackrabbit.server.io.ZipHandler" /> -->
-<!--         </propertyhandler> -->
-<!--         <propertyhandler> -->
-<!--             <class name="org.apache.jackrabbit.server.io.XmlHandler" /> -->
-<!--         </propertyhandler> -->
-        <propertyhandler>
-            <class name="org.apache.jackrabbit.server.io.DefaultHandler" />
-        </propertyhandler>
-    </propertymanager>
-    <!--
-     Define nodetypes, that should never by displayed as 'collection'
-    -->
-    <noncollection>
-        <nodetypes>
-            <nodetype>nt:file</nodetype>
-            <nodetype>nt:resource</nodetype>
-        </nodetypes>
-    </noncollection>
-    <!--
-     Example: Defines nodetypes, that should always be displayed as 'collection'.
-    -->
-    <!--
-    <collection>
-        <nodetypes>
-            <nodetype>nt:folder</nodetype>
-            <nodetype>rep:root</nodetype>
-        </nodetypes>
-    </collection>
-    -->
-    <!--
-     Filter that allows to prevent certain items from being displayed.
-     Please note, that this has an effect on PROPFIND calls only and does not
-     provide limited access to those items matching any of the filters.
-
-     However specifying a filter may cause problems with PUT or MKCOL if the
-     resource to be created is being filtered out, thus resulting in inconsistent
-     responses (e.g. PUT followed by PROPFIND on parent).
-     -->
-    <filter>
-        <!-- class element defines the resource filter to be used. The specified class
-             must implement the ItemFilter interface -->
-        <class name="org.apache.jackrabbit.webdav.simple.DefaultItemFilter" />
-        <!--
-         Nodetype names to be used to filter child nodes.
-         A child node can be filtered if the declaring nodetype of its definition
-         is one of the nodetype names specified in the nodetypes Element.
-         E.g. defining 'rep:root' as filtered nodetype whould result in jcr:system
-         being hidden but no other child node of the root node, since those
-         are defined by the nodetype nt:unstructered.
-        -->
-        <!--
-        <nodetypes>
-            <nodetype>rep:root</nodetype>
-        </nodetypes>
-        -->
-        <!--
-         Namespace prefixes or uris. Items having a name that matches any of the
-         entries will be filtered.
-        -->
-        <namespaces>
-            <prefix>rep</prefix>
-            <prefix>jcr</prefix>
-            <!-- Argeo namespaces -->
-            <prefix>node</prefix>
-            <prefix>argeo</prefix>
-            <prefix>cms</prefix>
-            <prefix>slc</prefix>
-            <prefix>connect</prefix>
-            <prefix>activities</prefix>
-            <prefix>people</prefix>
-            <prefix>documents</prefix>
-            <prefix>tracker</prefix>
-            <!--
-            <uri>internal</uri>
-            <uri>http://www.jcp.org/jcr/1.0</uri>
-            -->
-        </namespaces>
-    </filter>
-    
-    <!--
-     Optional 'mimetypeproperties' element.
-     It defines additional or replaces existing mappings for the MimeResolver
-     instance created by the ResourceConfig.
-     The default mappings are defined in org.apache.jackrabbit.server.io.mimetypes.properties.
-     If the default mime type defined by MimeResolver is 'application/octet-stream'.
-    -->
-    <!--
-    <mimetypeproperties>
-        <mimemapping extension="rtf" mimetype="application/rtf" />
-        <mimemapping extension="ott" mimetype="application/vnd.oasis.opendocument.text-template" />
-        <defaultmimetype>text/html</defaultmimetype>
-    </mimetypeproperties>
-    -->
-</config>
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/ldap.cnd b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/ldap.cnd
deleted file mode 100644 (file)
index a2306c6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<ldap = 'http://www.argeo.org/ns/ldap'>
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/node.cnd b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/node.cnd
deleted file mode 100644 (file)
index d8a26b6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<node = 'http://www.argeo.org/ns/node'>
-
-[node:userHome]
-mixin
-- ldap:uid (STRING) m
-
-[node:groupHome]
-mixin
-- ldap:cn (STRING) m
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java
deleted file mode 100644 (file)
index ccd543f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java
deleted file mode 100644 (file)
index d1d9b58..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-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/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java
deleted file mode 100644 (file)
index cc3e0d7..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-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/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java
deleted file mode 100644 (file)
index 506a6ac..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** 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/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitAdminLoginModule.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitAdminLoginModule.java
deleted file mode 100644 (file)
index 7396c87..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.argeo.jackrabbit;
-
-import java.util.Map;
-
-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.apache.jackrabbit.core.security.SecurityConstants;
-import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
-
-@Deprecated
-public class JackrabbitAdminLoginModule 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 {
-               // TODO check permission?
-               return true;
-       }
-
-       @Override
-       public boolean commit() throws LoginException {
-               subject.getPrincipals().add(
-                               new AdminPrincipal(SecurityConstants.ADMIN_ID));
-               return true;
-       }
-
-       @Override
-       public boolean abort() throws LoginException {
-               return true;
-       }
-
-       @Override
-       public boolean logout() throws LoginException {
-               subject.getPrincipals().removeAll(
-                               subject.getPrincipals(AdminPrincipal.class));
-               return true;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java
deleted file mode 100644 (file)
index 8c267e3..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-package org.argeo.jackrabbit;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.io.IOUtils;
-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;
-
-/** Migrate the data in a Jackrabbit repository. */
-@Deprecated
-public class JackrabbitDataModelMigration implements Comparable<JackrabbitDataModelMigration> {
-       private final static CmsLog log = CmsLog.getLog(JackrabbitDataModelMigration.class);
-
-       private String dataModelNodePath;
-       private String targetVersion;
-       private URL migrationCnd;
-       private JcrCallback dataModification;
-
-       /**
-        * Expects an already started repository with the old data model to migrate.
-        * Expects to be run with admin rights (Repository.login() will be used).
-        * 
-        * @return true if a migration was performed and the repository needs to be
-        *         restarted and its caches cleared.
-        */
-       public Boolean migrate(Session session) {
-               long begin = System.currentTimeMillis();
-               Reader reader = null;
-               try {
-                       // check if already migrated
-                       if (!session.itemExists(dataModelNodePath)) {
-//                             log.warn("Node " + dataModelNodePath + " does not exist: nothing to migrate.");
-                               return false;
-                       }
-//                     Node dataModelNode = session.getNode(dataModelNodePath);
-//                     if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
-//                             String currentVersion = dataModelNode.getProperty(
-//                                             ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
-//                             if (compareVersions(currentVersion, targetVersion) >= 0) {
-//                                     log.info("Data model at version " + currentVersion
-//                                                     + ", no need to migrate.");
-//                                     return false;
-//                             }
-//                     }
-
-                       // apply transitional CND
-                       if (migrationCnd != null) {
-                               reader = new InputStreamReader(migrationCnd.openStream());
-                               CndImporter.registerNodeTypes(reader, session, true);
-                               session.save();
-//                             log.info("Registered migration node types from " + migrationCnd);
-                       }
-
-                       // modify data
-                       dataModification.execute(session);
-
-                       // apply changes
-                       session.save();
-
-                       long duration = System.currentTimeMillis() - begin;
-//                     log.info("Migration of data model " + dataModelNodePath + " to " + targetVersion + " performed in "
-//                                     + duration + "ms");
-                       return true;
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new JcrException("Migration of data model " + dataModelNodePath + " to " + targetVersion + " failed.",
-                                       e);
-               } catch (ParseException | IOException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new RuntimeException(
-                                       "Migration of data model " + dataModelNodePath + " to " + targetVersion + " failed.", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-                       IOUtils.closeQuietly(reader);
-               }
-       }
-
-       protected static int compareVersions(String version1, String version2) {
-               // TODO do a proper version analysis and comparison
-               return version1.compareTo(version2);
-       }
-
-       /** To be called on a stopped repository. */
-       public static void clearRepositoryCaches(RepositoryConfig repositoryConfig) {
-               try {
-                       String customeNodeTypesPath = "/nodetypes/custom_nodetypes.xml";
-                       // FIXME causes weird error in Eclipse
-                       repositoryConfig.getFileSystem().deleteFile(customeNodeTypesPath);
-                       if (log.isDebugEnabled())
-                               log.debug("Cleared " + customeNodeTypesPath);
-               } catch (RuntimeException e) {
-                       throw e;
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               } catch (FileSystemException e) {
-                       throw new RuntimeException("Cannot clear node types cache.",e);
-               }
-
-               // File customNodeTypes = new File(home.getPath()
-               // + "/repository/nodetypes/custom_nodetypes.xml");
-               // if (customNodeTypes.exists()) {
-               // customNodeTypes.delete();
-               // if (log.isDebugEnabled())
-               // log.debug("Cleared " + customNodeTypes);
-               // } else {
-               // log.warn("File " + customNodeTypes + " not found.");
-               // }
-       }
-
-       /*
-        * FOR USE IN (SORTED) SETS
-        */
-
-       public int compareTo(JackrabbitDataModelMigration dataModelMigration) {
-               // TODO make ordering smarter
-               if (dataModelNodePath.equals(dataModelMigration.dataModelNodePath))
-                       return compareVersions(targetVersion, dataModelMigration.targetVersion);
-               else
-                       return dataModelNodePath.compareTo(dataModelMigration.dataModelNodePath);
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (!(obj instanceof JackrabbitDataModelMigration))
-                       return false;
-               JackrabbitDataModelMigration dataModelMigration = (JackrabbitDataModelMigration) obj;
-               return dataModelNodePath.equals(dataModelMigration.dataModelNodePath)
-                               && targetVersion.equals(dataModelMigration.targetVersion);
-       }
-
-       @Override
-       public int hashCode() {
-               return targetVersion.hashCode();
-       }
-
-       public void setDataModelNodePath(String dataModelNodePath) {
-               this.dataModelNodePath = dataModelNodePath;
-       }
-
-       public void setTargetVersion(String targetVersion) {
-               this.targetVersion = targetVersion;
-       }
-
-       public void setMigrationCnd(URL migrationCnd) {
-               this.migrationCnd = migrationCnd;
-       }
-
-       public void setDataModification(JcrCallback dataModification) {
-               this.dataModification = dataModification;
-       }
-
-       public String getDataModelNodePath() {
-               return dataModelNodePath;
-       }
-
-       public String getTargetVersion() {
-               return targetVersion;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryFactory.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryFactory.java
deleted file mode 100644 (file)
index 77ad527..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.argeo.jackrabbit.client;
-
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-
-import org.apache.jackrabbit.jcr2spi.Jcr2spiRepositoryFactory;
-import org.apache.jackrabbit.jcr2spi.RepositoryImpl;
-import org.apache.jackrabbit.spi.RepositoryServiceFactory;
-
-/** A customised {@link RepositoryFactory} access a remote DAVEX service. */
-public class ClientDavexRepositoryFactory implements RepositoryFactory {
-       public final static String JACKRABBIT_DAVEX_URI = ClientDavexRepositoryServiceFactory.PARAM_REPOSITORY_URI;
-       public final static String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = ClientDavexRepositoryServiceFactory.PARAM_WORKSPACE_NAME_DEFAULT;
-
-       @SuppressWarnings("rawtypes")
-       @Override
-       public Repository getRepository(Map parameters) throws RepositoryException {
-               RepositoryServiceFactory repositoryServiceFactory = new ClientDavexRepositoryServiceFactory();
-               return RepositoryImpl
-                               .create(new Jcr2spiRepositoryFactory.RepositoryConfigImpl(repositoryServiceFactory, parameters));
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryService.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryService.java
deleted file mode 100644 (file)
index 7d86af2..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.argeo.jackrabbit.client;
-
-import javax.jcr.RepositoryException;
-
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.protocol.HttpContext;
-import org.apache.jackrabbit.spi.SessionInfo;
-import org.apache.jackrabbit.spi2davex.BatchReadConfig;
-import org.apache.jackrabbit.spi2davex.RepositoryServiceImpl;
-
-/**
- * Wrapper for {@link RepositoryServiceImpl} in order to access the underlying
- * {@link HttpClientContext}.
- */
-public class ClientDavexRepositoryService extends RepositoryServiceImpl {
-
-       public ClientDavexRepositoryService(String jcrServerURI, BatchReadConfig batchReadConfig)
-                       throws RepositoryException {
-               super(jcrServerURI, batchReadConfig);
-       }
-       
-       
-
-//     public ClientDavexRepositoryService(String jcrServerURI, String defaultWorkspaceName,
-//                     BatchReadConfig batchReadConfig, int itemInfoCacheSize, ConnectionOptions connectionOptions)
-//                     throws RepositoryException {
-//             super(jcrServerURI, defaultWorkspaceName, batchReadConfig, itemInfoCacheSize, connectionOptions);
-//             // TODO Auto-generated constructor stub
-//     }
-
-
-
-//     public ClientDavexRepositoryService(String jcrServerURI, String defaultWorkspaceName,
-//                     BatchReadConfig batchReadConfig, int itemInfoCacheSize, int maximumHttpConnections)
-//                     throws RepositoryException {
-//             super(jcrServerURI, defaultWorkspaceName, batchReadConfig, itemInfoCacheSize, maximumHttpConnections);
-//     }
-//
-//     public ClientDavexRepositoryService(String jcrServerURI, String defaultWorkspaceName,
-//                     BatchReadConfig batchReadConfig, int itemInfoCacheSize) throws RepositoryException {
-//             super(jcrServerURI, defaultWorkspaceName, batchReadConfig, itemInfoCacheSize);
-//     }
-
-       @Override
-       protected HttpContext getContext(SessionInfo sessionInfo) throws RepositoryException {
-               HttpClientContext result = HttpClientContext.create();
-               result.setAuthCache(new NonSerialBasicAuthCache());
-               return result;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryServiceFactory.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/ClientDavexRepositoryServiceFactory.java
deleted file mode 100644 (file)
index 2af0835..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.argeo.jackrabbit.client;
-
-import java.util.Map;
-
-import javax.jcr.RepositoryException;
-
-import org.apache.jackrabbit.spi.RepositoryService;
-import org.apache.jackrabbit.spi.commons.ItemInfoCacheImpl;
-import org.apache.jackrabbit.spi2davex.BatchReadConfig;
-import org.apache.jackrabbit.spi2davex.Spi2davexRepositoryServiceFactory;
-
-/**
- * Wrapper for {@link Spi2davexRepositoryServiceFactory} in order to create a
- * {@link ClientDavexRepositoryService}.
- */
-public class ClientDavexRepositoryServiceFactory extends Spi2davexRepositoryServiceFactory {
-       @Override
-       public RepositoryService createRepositoryService(Map<?, ?> parameters) throws RepositoryException {
-               // retrieve the repository uri
-               String uri;
-               if (parameters == null) {
-                       uri = System.getProperty(PARAM_REPOSITORY_URI);
-               } else {
-                       Object repoUri = parameters.get(PARAM_REPOSITORY_URI);
-                       uri = (repoUri == null) ? null : repoUri.toString();
-               }
-               if (uri == null) {
-                       uri = DEFAULT_REPOSITORY_URI;
-               }
-
-               // load other optional configuration parameters
-               BatchReadConfig brc = null;
-               int itemInfoCacheSize = ItemInfoCacheImpl.DEFAULT_CACHE_SIZE;
-               int maximumHttpConnections = 0;
-
-               // since JCR-4120 the default workspace name is no longer set to 'default'
-               // note: if running with JCR Server < 1.5 a default workspace name must
-               // therefore be configured
-               String workspaceNameDefault = null;
-
-               if (parameters != null) {
-                       // batchRead config
-                       Object param = parameters.get(PARAM_BATCHREAD_CONFIG);
-                       if (param != null && param instanceof BatchReadConfig) {
-                               brc = (BatchReadConfig) param;
-                       }
-
-                       // itemCache size config
-                       param = parameters.get(PARAM_ITEMINFO_CACHE_SIZE);
-                       if (param != null) {
-                               try {
-                                       itemInfoCacheSize = Integer.parseInt(param.toString());
-                               } catch (NumberFormatException e) {
-                                       // ignore, use default
-                               }
-                       }
-
-                       // max connections config
-                       param = parameters.get(PARAM_MAX_CONNECTIONS);
-                       if (param != null) {
-                               try {
-                                       maximumHttpConnections = Integer.parseInt(param.toString());
-                               } catch (NumberFormatException e) {
-                                       // using default
-                               }
-                       }
-
-                       param = parameters.get(PARAM_WORKSPACE_NAME_DEFAULT);
-                       if (param != null) {
-                               workspaceNameDefault = param.toString();
-                       }
-               }
-
-               // FIXME adapt to changes in Jackrabbit
-//             if (maximumHttpConnections > 0) {
-//                     return new ClientDavexRepositoryService(uri, workspaceNameDefault, brc, itemInfoCacheSize,
-//                                     maximumHttpConnections);
-//             } else {
-//                     return new ClientDavexRepositoryService(uri, workspaceNameDefault, brc, itemInfoCacheSize);
-//             }
-               return null;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/JackrabbitClient.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/JackrabbitClient.java
deleted file mode 100644 (file)
index 3a122f1..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.argeo.jackrabbit.client;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.protocol.HttpContext;
-import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
-import org.apache.jackrabbit.jcr2spi.Jcr2spiRepositoryFactory;
-import org.apache.jackrabbit.jcr2spi.RepositoryImpl;
-import org.apache.jackrabbit.spi.RepositoryService;
-import org.apache.jackrabbit.spi.RepositoryServiceFactory;
-import org.apache.jackrabbit.spi.SessionInfo;
-import org.apache.jackrabbit.spi.commons.ItemInfoCacheImpl;
-import org.apache.jackrabbit.spi2davex.BatchReadConfig;
-import org.apache.jackrabbit.spi2davex.RepositoryServiceImpl;
-import org.apache.jackrabbit.spi2davex.Spi2davexRepositoryServiceFactory;
-import org.argeo.jcr.JcrUtils;
-
-/** Minimal client to test JCR DAVEX connectivity. */
-public class JackrabbitClient {
-       final static String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
-       final static String JACKRABBIT_DAVEX_URI = "org.apache.jackrabbit.spi2davex.uri";
-       final static String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
-
-       public static void main(String[] args) {
-               String repoUri = args.length == 0 ? "http://root:demo@localhost:7070/jcr/ego" : args[0];
-               String workspace = args.length < 2 ? "home" : args[1];
-
-               Repository repository = null;
-               Session session = null;
-
-               URI uri;
-               try {
-                       uri = new URI(repoUri);
-               } catch (URISyntaxException e1) {
-                       throw new IllegalArgumentException(e1);
-               }
-
-               if (uri.getScheme().equals("http") || uri.getScheme().equals("https")) {
-
-                       RepositoryFactory repositoryFactory = new Jcr2davRepositoryFactory() {
-                               @SuppressWarnings("rawtypes")
-                               public Repository getRepository(Map parameters) throws RepositoryException {
-                                       RepositoryServiceFactory repositoryServiceFactory = new Spi2davexRepositoryServiceFactory() {
-
-                                               @Override
-                                               public RepositoryService createRepositoryService(Map<?, ?> parameters)
-                                                               throws RepositoryException {
-                                                       Object uri = parameters.get(JACKRABBIT_DAVEX_URI);
-                                                       Object defaultWorkspace = parameters.get(JACKRABBIT_REMOTE_DEFAULT_WORKSPACE);
-                                                       BatchReadConfig brc = null;
-                                                       // FIXME adapt to change in Jackrabbit
-//                                                     return new RepositoryServiceImpl(uri.toString(), defaultWorkspace.toString(), brc,
-//                                                                     ItemInfoCacheImpl.DEFAULT_CACHE_SIZE) {
-//
-//                                                             @Override
-//                                                             protected HttpContext getContext(SessionInfo sessionInfo) throws RepositoryException {
-//                                                                     HttpClientContext result = HttpClientContext.create();
-//                                                                     result.setAuthCache(new NonSerialBasicAuthCache());
-//                                                                     return result;
-//                                                             }
-//
-//                                                     };
-                                                       return null;
-                                               }
-                                       };
-                                       return RepositoryImpl.create(
-                                                       new Jcr2spiRepositoryFactory.RepositoryConfigImpl(repositoryServiceFactory, parameters));
-                               }
-                       };
-                       Map<String, String> params = new HashMap<String, String>();
-                       params.put(JACKRABBIT_DAVEX_URI, repoUri.toString());
-                       // FIXME make it configurable
-                       params.put(JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, "sys");
-
-                       try {
-                               repository = repositoryFactory.getRepository(params);
-                               if (repository != null)
-                                       session = repository.login(workspace);
-                               else
-                                       throw new IllegalArgumentException("Repository " + repoUri + " not found");
-                       } catch (RepositoryException e) {
-                               e.printStackTrace();
-                       }
-
-               } else {
-                       Path path = Paths.get(uri.getPath());
-               }
-
-               try {
-                       Node rootNode = session.getRootNode();
-                       NodeIterator nit = rootNode.getNodes();
-                       while (nit.hasNext()) {
-                               System.out.println(nit.nextNode().getPath());
-                       }
-
-                       Node newNode = JcrUtils.mkdirs(rootNode, "dir/subdir");
-                       System.out.println("Created folder " + newNode.getPath());
-                       Node newFile = JcrUtils.copyBytesAsFile(newNode, "test.txt", "TEST".getBytes());
-                       System.out.println("Created file " + newFile.getPath());
-                       try (BufferedReader reader = new BufferedReader(new InputStreamReader(JcrUtils.getFileAsStream(newFile)))) {
-                               System.out.println("Read " + reader.readLine());
-                       } catch (IOException e) {
-                               e.printStackTrace();
-                       }
-                       newNode.getParent().remove();
-                       System.out.println("Removed new nodes");
-               } catch (RepositoryException e) {
-                       e.printStackTrace();
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/NonSerialBasicAuthCache.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/client/NonSerialBasicAuthCache.java
deleted file mode 100644 (file)
index 3fb0db9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.argeo.jackrabbit.client;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScheme;
-import org.apache.http.client.AuthCache;
-
-/**
- * Implementation of {@link AuthCache} which doesn't use serialization, as it is
- * not supported by GraalVM at this stage.
- */
-public class NonSerialBasicAuthCache implements AuthCache {
-       private final Map<HttpHost, AuthScheme> cache;
-
-       public NonSerialBasicAuthCache() {
-               cache = new ConcurrentHashMap<HttpHost, AuthScheme>();
-       }
-
-       @Override
-       public void put(HttpHost host, AuthScheme authScheme) {
-               cache.put(host, authScheme);
-       }
-
-       @Override
-       public AuthScheme get(HttpHost host) {
-               return cache.get(host);
-       }
-
-       @Override
-       public void remove(HttpHost host) {
-               cache.remove(host);
-       }
-
-       @Override
-       public void clear() {
-               cache.clear();
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/AbstractJackrabbitFsProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/AbstractJackrabbitFsProvider.java
deleted file mode 100644 (file)
index a2eb983..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.argeo.jackrabbit.fs;
-
-import org.argeo.jcr.fs.JcrFileSystemProvider;
-
-public abstract class AbstractJackrabbitFsProvider extends JcrFileSystemProvider {
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/DavexFsProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/DavexFsProvider.java
deleted file mode 100644 (file)
index 1cae6e4..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-package org.argeo.jackrabbit.fs;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystemAlreadyExistsException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-
-import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
-import org.argeo.jcr.fs.JcrFileSystem;
-import org.argeo.jcr.fs.JcrFsException;
-
-/**
- * A file system provider based on a JCR repository remotely accessed via the
- * DAVEX protocol.
- */
-public class DavexFsProvider extends AbstractJackrabbitFsProvider {
-       final static String DEFAULT_JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "sys";
-
-       private Map<String, JcrFileSystem> fileSystems = new HashMap<>();
-
-       @Override
-       public String getScheme() {
-               return "davex";
-       }
-
-       @Override
-       public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
-               if (uri.getHost() == null)
-                       throw new IllegalArgumentException("An host should be provided");
-               try {
-                       URI repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), null, null);
-                       String repoKey = repoUri.toString();
-                       if (fileSystems.containsKey(repoKey))
-                               throw new FileSystemAlreadyExistsException("CMS file system already exists for " + repoKey);
-                       RepositoryFactory repositoryFactory = new ClientDavexRepositoryFactory();
-                       return tryGetRepo(repositoryFactory, repoUri, "home");
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException("Cannot open file system " + uri, e);
-               }
-       }
-
-       private JcrFileSystem tryGetRepo(RepositoryFactory repositoryFactory, URI repoUri, String workspace)
-                       throws IOException {
-               Map<String, String> params = new HashMap<String, String>();
-               params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, repoUri.toString());
-               // TODO better integrate with OSGi or other configuration than system
-               // properties.
-               String remoteDefaultWorkspace = System.getProperty(
-                               ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE,
-                               DEFAULT_JACKRABBIT_REMOTE_DEFAULT_WORKSPACE);
-               params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, remoteDefaultWorkspace);
-               Repository repository = null;
-               Session session = null;
-               try {
-                       repository = repositoryFactory.getRepository(params);
-                       if (repository != null)
-                               session = repository.login(workspace);
-               } catch (Exception e) {
-                       // silent
-               }
-
-               if (session == null) {
-                       if (repoUri.getPath() == null || repoUri.getPath().equals("/"))
-                               return null;
-                       String repoUriStr = repoUri.toString();
-                       if (repoUriStr.endsWith("/"))
-                               repoUriStr = repoUriStr.substring(0, repoUriStr.length() - 1);
-                       String nextRepoUriStr = repoUriStr.substring(0, repoUriStr.lastIndexOf('/'));
-                       String nextWorkspace = repoUriStr.substring(repoUriStr.lastIndexOf('/') + 1);
-                       URI nextUri;
-                       try {
-                               nextUri = new URI(nextRepoUriStr);
-                       } catch (URISyntaxException e) {
-                               throw new IllegalArgumentException("Badly formatted URI", e);
-                       }
-                       return tryGetRepo(repositoryFactory, nextUri, nextWorkspace);
-               } else {
-                       JcrFileSystem fileSystem = new JcrFileSystem(this, repository);
-                       fileSystems.put(repoUri.toString() + "/" + workspace, fileSystem);
-                       return fileSystem;
-               }
-       }
-
-       @Override
-       public FileSystem getFileSystem(URI uri) {
-               return currentUserFileSystem(uri);
-       }
-
-       @Override
-       public Path getPath(URI uri) {
-               JcrFileSystem fileSystem = currentUserFileSystem(uri);
-               if (fileSystem == null)
-                       try {
-                               fileSystem = (JcrFileSystem) newFileSystem(uri, new HashMap<String, Object>());
-                               if (fileSystem == null)
-                                       throw new IllegalArgumentException("No file system found for " + uri);
-                       } catch (IOException e) {
-                               throw new JcrFsException("Could not autocreate file system", e);
-                       }
-               URI repoUri = null;
-               try {
-                       repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), null, null);
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException(e);
-               }
-               String uriStr = repoUri.toString();
-               String localPath = null;
-               for (String key : fileSystems.keySet()) {
-                       if (uriStr.startsWith(key)) {
-                               localPath = uriStr.toString().substring(key.length());
-                       }
-               }
-               if ("".equals(localPath))
-                       localPath = "/";
-               return fileSystem.getPath(localPath);
-       }
-
-       private JcrFileSystem currentUserFileSystem(URI uri) {
-               for (String key : fileSystems.keySet()) {
-                       if (uri.toString().startsWith(key))
-                               return fileSystems.get(key);
-               }
-               return null;
-       }
-
-       public static void main(String args[]) {
-               try {
-                       DavexFsProvider fsProvider = new DavexFsProvider();
-                       Path path = fsProvider.getPath(new URI("davex://root:demo@localhost:7070/jcr/ego/"));
-                       System.out.println(path);
-                       DirectoryStream<Path> ds = Files.newDirectoryStream(path);
-                       for (Path p : ds) {
-                               System.out.println("- " + p);
-                       }
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/JackrabbitMemoryFsProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/JackrabbitMemoryFsProvider.java
deleted file mode 100644 (file)
index e3a70d0..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.argeo.jackrabbit.fs;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.FileSystem;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Credentials;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.argeo.jcr.fs.JcrFileSystem;
-import org.argeo.jcr.fs.JcrFsException;
-
-public class JackrabbitMemoryFsProvider extends AbstractJackrabbitFsProvider {
-       private RepositoryImpl repository;
-       private JcrFileSystem fileSystem;
-
-       private Credentials credentials;
-
-       public JackrabbitMemoryFsProvider() {
-               String username = System.getProperty("user.name");
-               credentials = new SimpleCredentials(username, username.toCharArray());
-       }
-
-       @Override
-       public String getScheme() {
-               return "jcr+memory";
-       }
-
-       @Override
-       public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
-               try {
-                       Path tempDir = Files.createTempDirectory("fs-memory");
-                       URL confUrl = JackrabbitMemoryFsProvider.class.getResource("fs-memory.xml");
-                       RepositoryConfig repositoryConfig = RepositoryConfig.create(confUrl.toURI(), tempDir.toString());
-                       repository = RepositoryImpl.create(repositoryConfig);
-                       postRepositoryCreation(repository);
-                       fileSystem = new JcrFileSystem(this, repository, credentials);
-                       return fileSystem;
-               } catch (RepositoryException | URISyntaxException e) {
-                       throw new IOException("Cannot login to repository", e);
-               }
-       }
-
-       @Override
-       public FileSystem getFileSystem(URI uri) {
-               return fileSystem;
-       }
-
-       @Override
-       public Path getPath(URI uri) {
-               String path = uri.getPath();
-               if (fileSystem == null)
-                       try {
-                               newFileSystem(uri, new HashMap<String, Object>());
-                       } catch (IOException e) {
-                               throw new JcrFsException("Could not autocreate file system", e);
-                       }
-               return fileSystem.getPath(path);
-       }
-
-       public Repository getRepository() {
-               return repository;
-       }
-
-       public Session login() throws RepositoryException {
-               return getRepository().login(credentials);
-       }
-
-       /**
-        * Called after the repository has been created and before the file system is
-        * created.
-        */
-       protected void postRepositoryCreation(RepositoryImpl repositoryImpl) throws RepositoryException {
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/fs-memory.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/fs-memory.xml
deleted file mode 100644 (file)
index f2541fb..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- File system and datastore -->
-       <FileSystem
-               class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="main" configRootPath="/workspaces" />
-       <Workspace name="${wsp.name}">
-               <FileSystem
-                       class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-               </PersistenceManager>
-               <SearchIndex
-                       class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/index" />
-                       <param name="directoryManagerClass"
-                               value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-                       <param name="extractorPoolSize" value="0" />
-                       <FileSystem
-                               class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               </SearchIndex>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem
-                       class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex
-               class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="directoryManagerClass"
-                       value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-               <param name="extractorPoolSize" value="0" />
-               <FileSystem
-                       class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <LoginModule
-                       class="org.apache.jackrabbit.core.security.SimpleLoginModule" />
-               <!-- <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager" -->
-               <!-- workspaceName="security" /> -->
-               <!-- <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" 
-                       /> -->
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/fs/package-info.java
deleted file mode 100644 (file)
index c9ec2c3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Java NIO file system implementation based on Jackrabbit. */
-package org.argeo.jackrabbit.fs;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/package-info.java
deleted file mode 100644 (file)
index 17497d6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Generic Jackrabbit utilities. */
-package org.argeo.jackrabbit;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-h2.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-h2.xml
deleted file mode 100644 (file)
index 0526762..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.h2.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="h2" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="default" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-       <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
-               <param name="path" value="${rep.home}/datastore" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-localfs.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-localfs.xml
deleted file mode 100644 (file)
index 3d24708..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-               <param name="path" value="${rep.home}/repository" />
-       </FileSystem>
-       <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
-               <param name="path" value="${rep.home}/datastore" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-                       <param name="path" value="${wsp.home}" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-                       <param name="path" value="${rep.home}/version" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-memory.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-memory.xml
deleted file mode 100644 (file)
index ecee5bd..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" configRootPath="/workspaces" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="blobFSBlockSize" value="1" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/index" />
-                       <param name="directoryManagerClass"
-                               value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-                       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               </SearchIndex>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
-                       <param name="blobFSBlockSize" value="1" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="directoryManagerClass"
-                       value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-postgresql-ds.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-postgresql-ds.xml
deleted file mode 100644 (file)
index 07a0d04..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.postgresql.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="postgresql" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="postgresql" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-       <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
-               <param name="path" value="${rep.home}/datastore" />
-       </DataStore>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-postgresql.xml b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/repository-postgresql.xml
deleted file mode 100644 (file)
index 9677828..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.postgresql.Driver" />
-                       <param name="url" value="${dburl}" />
-                       <param name="user" value="${dbuser}" />
-                       <param name="password" value="${dbpassword}" />
-                       <param name="databaseType" value="postgresql" />
-                       <param name="maxPoolSize" value="${maxPoolSize}" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="postgresql" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </FileSystem>
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${defaultWorkspace}" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/index" />
-                       <param name="extractorPoolSize" value="${extractorPoolSize}" />
-                       <param name="cacheSize" value="${searchCacheSize}" />
-                       <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-               </SearchIndex>
-               <WorkspaceSecurity>
-                       <AccessControlProvider
-                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
-               </WorkspaceSecurity>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="postgresql" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-                       <param name="bundleCacheSize" value="${bundleCacheMB}" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="extractorPoolSize" value="${extractorPoolSize}" />
-               <param name="cacheSize" value="${searchCacheSize}" />
-               <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security" />
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java
deleted file mode 100644 (file)
index f98cf99..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.argeo.jackrabbit.security;
-
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.security.Privilege;
-
-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 CmsLog log = CmsLog.getLog(JackrabbitSecurityUtils.class);
-
-       /**
-        * Convenience method for denying a single privilege to a principal (user or
-        * role), typically jcr:all
-        */
-       public synchronized static void denyPrivilege(Session session, String path, String principal, String privilege)
-                       throws RepositoryException {
-               List<Privilege> privileges = new ArrayList<Privilege>();
-               privileges.add(session.getAccessControlManager().privilegeFromName(privilege));
-               denyPrivileges(session, path, () -> principal, privileges);
-       }
-
-       /**
-        * Deny privileges on a path to a {@link Principal}. The path must already
-        * exist. Session is saved. Synchronized to prevent concurrent modifications of
-        * the same node.
-        */
-       public synchronized static Boolean denyPrivileges(Session session, String path, Principal principal,
-                       List<Privilege> privs) throws RepositoryException {
-               // make sure the session is in line with the persisted state
-               session.refresh(false);
-               JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session.getAccessControlManager();
-               JackrabbitAccessControlList acl = (JackrabbitAccessControlList) JcrUtils.getAccessControlList(acm, path);
-
-//             accessControlEntries: for (AccessControlEntry ace : acl.getAccessControlEntries()) {
-//                     Principal currentPrincipal = ace.getPrincipal();
-//                     if (currentPrincipal.getName().equals(principal.getName())) {
-//                             Privilege[] currentPrivileges = ace.getPrivileges();
-//                             if (currentPrivileges.length != privs.size())
-//                                     break accessControlEntries;
-//                             for (int i = 0; i < currentPrivileges.length; i++) {
-//                                     Privilege currP = currentPrivileges[i];
-//                                     Privilege p = privs.get(i);
-//                                     if (!currP.getName().equals(p.getName())) {
-//                                             break accessControlEntries;
-//                                     }
-//                             }
-//                             return false;
-//                     }
-//             }
-
-               Privilege[] privileges = privs.toArray(new Privilege[privs.size()]);
-               acl.addEntry(principal, privileges, false);
-               acm.setPolicy(path, acl);
-               if (log.isDebugEnabled()) {
-                       StringBuffer privBuf = new StringBuffer();
-                       for (Privilege priv : privs)
-                               privBuf.append(priv.getName());
-                       log.debug("Denied privileges " + privBuf + " to " + principal.getName() + " on " + path + " in '"
-                                       + session.getWorkspace().getName() + "'");
-               }
-               session.refresh(true);
-               session.save();
-               return true;
-       }
-
-       /** Singleton. */
-       private JackrabbitSecurityUtils() {
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/package-info.java
deleted file mode 100644 (file)
index f3a282c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Generic Jackrabbit security utilities. */
-package org.argeo.jackrabbit.security;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/Bin.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/Bin.java
deleted file mode 100644 (file)
index 0418810..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.argeo.jcr;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.jcr.Binary;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-/**
- * A {@link Binary} wrapper implementing {@link AutoCloseable} for ease of use
- * in try/catch blocks.
- */
-public class Bin implements Binary, AutoCloseable {
-       private final Binary wrappedBinary;
-
-       public Bin(Property property) throws RepositoryException {
-               this(property.getBinary());
-       }
-
-       public Bin(Binary wrappedBinary) {
-               if (wrappedBinary == null)
-                       throw new IllegalArgumentException("Wrapped binary cannot be null");
-               this.wrappedBinary = wrappedBinary;
-       }
-
-       // private static Binary getBinary(Property property) throws IOException {
-       // try {
-       // return property.getBinary();
-       // } catch (RepositoryException e) {
-       // throw new IOException("Cannot get binary from property " + property, e);
-       // }
-       // }
-
-       @Override
-       public void close() {
-               dispose();
-       }
-
-       @Override
-       public InputStream getStream() throws RepositoryException {
-               return wrappedBinary.getStream();
-       }
-
-       @Override
-       public int read(byte[] b, long position) throws IOException, RepositoryException {
-               return wrappedBinary.read(b, position);
-       }
-
-       @Override
-       public long getSize() throws RepositoryException {
-               return wrappedBinary.getSize();
-       }
-
-       @Override
-       public void dispose() {
-               wrappedBinary.dispose();
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/CollectionNodeIterator.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/CollectionNodeIterator.java
deleted file mode 100644 (file)
index b4124ee..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.argeo.jcr;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-
-/** Wraps a collection of nodes in order to read it as a {@link NodeIterator} */
-public class CollectionNodeIterator implements NodeIterator {
-       private final Long collectionSize;
-       private final Iterator<Node> iterator;
-       private Integer position = 0;
-
-       public CollectionNodeIterator(Collection<Node> nodes) {
-               super();
-               this.collectionSize = (long) nodes.size();
-               this.iterator = nodes.iterator();
-       }
-
-       public void skip(long skipNum) {
-               if (skipNum < 0)
-                       throw new IllegalArgumentException(
-                                       "Skip count has to be positive: " + skipNum);
-
-               for (long i = 0; i < skipNum; i++) {
-                       if (!hasNext())
-                               throw new NoSuchElementException("Last element past (position="
-                                               + getPosition() + ")");
-                       nextNode();
-               }
-       }
-
-       public long getSize() {
-               return collectionSize;
-       }
-
-       public long getPosition() {
-               return position;
-       }
-
-       public boolean hasNext() {
-               return iterator.hasNext();
-       }
-
-       public Object next() {
-               return nextNode();
-       }
-
-       public void remove() {
-               iterator.remove();
-       }
-
-       public Node nextNode() {
-               Node node = iterator.next();
-               position++;
-               return node;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java
deleted file mode 100644 (file)
index d873ef6..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.argeo.jcr;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventIterator;
-import javax.jcr.observation.EventListener;
-import javax.jcr.observation.ObservationManager;
-
-import org.argeo.api.cms.CmsLog;
-
-/** To be overridden */
-public class DefaultJcrListener implements EventListener {
-       private final static CmsLog log = CmsLog.getLog(DefaultJcrListener.class);
-       private Session session;
-       private String path = "/";
-       private Boolean deep = true;
-
-       public void start() {
-               try {
-                       addEventListener(session().getWorkspace().getObservationManager());
-                       if (log.isDebugEnabled())
-                               log.debug("Registered JCR event listener on " + path);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot register event listener", e);
-               }
-       }
-
-       public void stop() {
-               try {
-                       session().getWorkspace().getObservationManager()
-                                       .removeEventListener(this);
-                       if (log.isDebugEnabled())
-                               log.debug("Unregistered JCR event listener on " + path);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot unregister event listener", e);
-               }
-       }
-
-       /** Default is listen to all events */
-       protected Integer getEvents() {
-               return Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED
-                               | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED;
-       }
-
-       /** To be overidden */
-       public void onEvent(EventIterator events) {
-               while (events.hasNext()) {
-                       Event event = events.nextEvent();
-                       log.debug(event);
-               }
-       }
-
-       /** To be overidden */
-       protected void addEventListener(ObservationManager observationManager)
-                       throws RepositoryException {
-               observationManager.addEventListener(this, getEvents(), path, deep,
-                               null, null, false);
-       }
-
-       private Session session() {
-               return session;
-       }
-
-       public void setPath(String path) {
-               this.path = path;
-       }
-
-       public void setDeep(Boolean deep) {
-               this.deep = deep;
-       }
-
-       public void setSession(Session session) {
-               this.session = session;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/Jcr.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/Jcr.java
deleted file mode 100644 (file)
index 49b008d..0000000
+++ /dev/null
@@ -1,993 +0,0 @@
-package org.argeo.jcr;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.text.MessageFormat;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jcr.Binary;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.Workspace;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.Row;
-import javax.jcr.security.Privilege;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionIterator;
-import javax.jcr.version.VersionManager;
-
-import org.apache.commons.io.IOUtils;
-
-/**
- * Utility class whose purpose is to make using JCR less verbose by
- * systematically using unchecked exceptions and returning <code>null</code>
- * when something is not found. This is especially useful when writing user
- * interfaces (such as with SWT) where listeners and callbacks expect unchecked
- * exceptions. Loosely inspired by Java's <code>Files</code> singleton.
- */
-public class Jcr {
-       /**
-        * The name of a node which will be serialized as XML text, as per section 7.3.1
-        * of the JCR 2.0 specifications.
-        */
-       public final static String JCR_XMLTEXT = "jcr:xmltext";
-       /**
-        * The name of a property which will be serialized as XML text, as per section
-        * 7.3.1 of the JCR 2.0 specifications.
-        */
-       public final static String JCR_XMLCHARACTERS = "jcr:xmlcharacters";
-       /**
-        * <code>jcr:name</code>, when used in another context than
-        * {@link Property#JCR_NAME}, typically to name a node rather than a property.
-        */
-       public final static String JCR_NAME = "jcr:name";
-       /**
-        * <code>jcr:path</code>, when used in another context than
-        * {@link Property#JCR_PATH}, typically to name a node rather than a property.
-        */
-       public final static String JCR_PATH = "jcr:path";
-       /**
-        * <code>jcr:primaryType</code> with prefix instead of namespace (as in
-        * {@link Property#JCR_PRIMARY_TYPE}.
-        */
-       public final static String JCR_PRIMARY_TYPE = "jcr:primaryType";
-       /**
-        * <code>jcr:mixinTypes</code> with prefix instead of namespace (as in
-        * {@link Property#JCR_MIXIN_TYPES}.
-        */
-       public final static String JCR_MIXIN_TYPES = "jcr:mixinTypes";
-       /**
-        * <code>jcr:uuid</code> with prefix instead of namespace (as in
-        * {@link Property#JCR_UUID}.
-        */
-       public final static String JCR_UUID = "jcr:uuid";
-       /**
-        * <code>jcr:created</code> with prefix instead of namespace (as in
-        * {@link Property#JCR_CREATED}.
-        */
-       public final static String JCR_CREATED = "jcr:created";
-       /**
-        * <code>jcr:createdBy</code> with prefix instead of namespace (as in
-        * {@link Property#JCR_CREATED_BY}.
-        */
-       public final static String JCR_CREATED_BY = "jcr:createdBy";
-       /**
-        * <code>jcr:lastModified</code> with prefix instead of namespace (as in
-        * {@link Property#JCR_LAST_MODIFIED}.
-        */
-       public final static String JCR_LAST_MODIFIED = "jcr:lastModified";
-       /**
-        * <code>jcr:lastModifiedBy</code> with prefix instead of namespace (as in
-        * {@link Property#JCR_LAST_MODIFIED_BY}.
-        */
-       public final static String JCR_LAST_MODIFIED_BY = "jcr:lastModifiedBy";
-
-       /**
-        * @see Node#isNodeType(String)
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static boolean isNodeType(Node node, String nodeTypeName) {
-               try {
-                       return node.isNodeType(nodeTypeName);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get whether " + node + " is of type " + nodeTypeName, e);
-               }
-       }
-
-       /**
-        * @see Node#hasNodes()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static boolean hasNodes(Node node) {
-               try {
-                       return node.hasNodes();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get whether " + node + " has children.", e);
-               }
-       }
-
-       /**
-        * @see Node#getParent()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static Node getParent(Node node) {
-               try {
-                       return isRoot(node) ? null : node.getParent();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get parent of " + node, e);
-               }
-       }
-
-       /**
-        * @see Node#getParent()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static String getParentPath(Node node) {
-               return getPath(getParent(node));
-       }
-
-       /**
-        * Whether this node is the root node.
-        * 
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static boolean isRoot(Node node) {
-               try {
-                       return node.getDepth() == 0;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get depth of " + node, e);
-               }
-       }
-
-       /**
-        * @see Node#getPath()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static String getPath(Node node) {
-               try {
-                       return node.getPath();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get path of " + node, e);
-               }
-       }
-
-       /**
-        * @see Node#getSession()
-        * @see Session#getWorkspace()
-        * @see Workspace#getName()
-        */
-       public static String getWorkspaceName(Node node) {
-               return session(node).getWorkspace().getName();
-       }
-
-       /**
-        * @see Node#getIdentifier()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static String getIdentifier(Node node) {
-               try {
-                       return node.getIdentifier();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get identifier of " + node, e);
-               }
-       }
-
-       /**
-        * @see Node#getName()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static String getName(Node node) {
-               try {
-                       return node.getName();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get name of " + node, e);
-               }
-       }
-
-       /**
-        * Returns the node name with its current index (useful for re-ordering).
-        * 
-        * @see Node#getName()
-        * @see Node#getIndex()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static String getIndexedName(Node node) {
-               try {
-                       return node.getName() + "[" + node.getIndex() + "]";
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get name of " + node, e);
-               }
-       }
-
-       /**
-        * @see Node#getProperty(String)
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static Property getProperty(Node node, String property) {
-               try {
-                       if (node.hasProperty(property))
-                               return node.getProperty(property);
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get property " + property + " of " + node, e);
-               }
-       }
-
-       /**
-        * @see Node#getIndex()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static int getIndex(Node node) {
-               try {
-                       return node.getIndex();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get index of " + node, e);
-               }
-       }
-
-       /**
-        * If node has mixin {@link NodeType#MIX_TITLE}, return
-        * {@link Property#JCR_TITLE}, otherwise return {@link #getName(Node)}.
-        */
-       public static String getTitle(Node node) {
-               if (Jcr.isNodeType(node, NodeType.MIX_TITLE))
-                       return get(node, Property.JCR_TITLE);
-               else
-                       return Jcr.getName(node);
-       }
-
-       /** Accesses a {@link NodeIterator} as an {@link Iterable}. */
-       @SuppressWarnings("unchecked")
-       public static Iterable<Node> iterate(NodeIterator nodeIterator) {
-               return new Iterable<Node>() {
-
-                       @Override
-                       public Iterator<Node> iterator() {
-                               return nodeIterator;
-                       }
-               };
-       }
-
-       /**
-        * @return the children as an {@link Iterable} for use in for-each llops.
-        * @see Node#getNodes()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static Iterable<Node> nodes(Node node) {
-               try {
-                       return iterate(node.getNodes());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get children of " + node, e);
-               }
-       }
-
-       /**
-        * @return the children as a (possibly empty) {@link List}.
-        * @see Node#getNodes()
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static List<Node> getNodes(Node node) {
-               List<Node> nodes = new ArrayList<>();
-               try {
-                       if (node.hasNodes()) {
-                               NodeIterator nit = node.getNodes();
-                               while (nit.hasNext())
-                                       nodes.add(nit.nextNode());
-                               return nodes;
-                       } else
-                               return nodes;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get children of " + node, e);
-               }
-       }
-
-       /**
-        * @return the child or <code>null</node> if not found
-        * @see Node#getNode(String)
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static Node getNode(Node node, String child) {
-               try {
-                       if (node.hasNode(child))
-                               return node.getNode(child);
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get child of " + node, e);
-               }
-       }
-
-       /**
-        * @return the node at this path or <code>null</node> if not found
-        * @see Session#getNode(String)
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static Node getNode(Session session, String path) {
-               try {
-                       if (session.nodeExists(path))
-                               return session.getNode(path);
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get node " + path, e);
-               }
-       }
-
-       /**
-        * Add a node to this parent, setting its primary type and its mixins.
-        * 
-        * @param parent      the parent node
-        * @param name        the name of the node, if <code>null</code>, the primary
-        *                    type will be used (typically for XML structures)
-        * @param primaryType the primary type, if <code>null</code>
-        *                    {@link NodeType#NT_UNSTRUCTURED} will be used.
-        * @param mixins      the mixins
-        * @return the created node
-        * @see Node#addNode(String, String)
-        * @see Node#addMixin(String)
-        */
-       public static Node addNode(Node parent, String name, String primaryType, String... mixins) {
-               if (name == null && primaryType == null)
-                       throw new IllegalArgumentException("Both node name and primary type cannot be null");
-               try {
-                       Node newNode = parent.addNode(name == null ? primaryType : name,
-                                       primaryType == null ? NodeType.NT_UNSTRUCTURED : primaryType);
-                       for (String mixin : mixins) {
-                               newNode.addMixin(mixin);
-                       }
-                       return newNode;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot add node " + name + " to " + parent, e);
-               }
-       }
-
-       /**
-        * Add an {@link NodeType#NT_BASE} node to this parent.
-        * 
-        * @param parent the parent node
-        * @param name   the name of the node, cannot be <code>null</code>
-        * @return the created node
-        * 
-        * @see Node#addNode(String)
-        */
-       public static Node addNode(Node parent, String name) {
-               if (name == null)
-                       throw new IllegalArgumentException("Node name cannot be null");
-               try {
-                       Node newNode = parent.addNode(name);
-                       return newNode;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot add node " + name + " to " + parent, e);
-               }
-       }
-
-       /**
-        * Add mixins to a node.
-        * 
-        * @param node   the node
-        * @param mixins the mixins
-        * @see Node#addMixin(String)
-        */
-       public static void addMixin(Node node, String... mixins) {
-               try {
-                       for (String mixin : mixins) {
-                               node.addMixin(mixin);
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot add mixins " + Arrays.asList(mixins) + " to " + node, e);
-               }
-       }
-
-       /**
-        * Removes this node.
-        * 
-        * @see Node#remove()
-        */
-       public static void remove(Node node) {
-               try {
-                       node.remove();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot remove node " + node, e);
-               }
-       }
-
-       /**
-        * @return the node with htis id or <code>null</node> if not found
-        * @see Session#getNodeByIdentifier(String)
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static Node getNodeById(Session session, String id) {
-               try {
-                       return session.getNodeByIdentifier(id);
-               } catch (ItemNotFoundException e) {
-                       return null;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get node with id " + id, e);
-               }
-       }
-
-       /**
-        * Set a property to the given value, or remove it if the value is
-        * <code>null</code>.
-        * 
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static void set(Node node, String property, Object value) {
-               try {
-                       if (!node.hasProperty(property)) {
-                               if (value != null) {
-                                       if (value instanceof List) {// multiple
-                                               List<?> lst = (List<?>) value;
-                                               String[] values = new String[lst.size()];
-                                               for (int i = 0; i < lst.size(); i++) {
-                                                       values[i] = lst.get(i).toString();
-                                               }
-                                               node.setProperty(property, values);
-                                       } else {
-                                               node.setProperty(property, value.toString());
-                                       }
-                               }
-                               return;
-                       }
-                       Property prop = node.getProperty(property);
-                       if (value == null) {
-                               prop.remove();
-                               return;
-                       }
-
-                       // multiple
-                       if (value instanceof List) {
-                               List<?> lst = (List<?>) value;
-                               String[] values = new String[lst.size()];
-                               // TODO better cast?
-                               for (int i = 0; i < lst.size(); i++) {
-                                       values[i] = lst.get(i).toString();
-                               }
-                               if (!prop.isMultiple())
-                                       prop.remove();
-                               node.setProperty(property, values);
-                               return;
-                       }
-
-                       // single
-                       if (prop.isMultiple()) {
-                               prop.remove();
-                               node.setProperty(property, value.toString());
-                               return;
-                       }
-
-                       if (value instanceof String)
-                               prop.setValue((String) value);
-                       else if (value instanceof Long)
-                               prop.setValue((Long) value);
-                       else if (value instanceof Integer)
-                               prop.setValue(((Integer) value).longValue());
-                       else if (value instanceof Double)
-                               prop.setValue((Double) value);
-                       else if (value instanceof Float)
-                               prop.setValue(((Float) value).doubleValue());
-                       else if (value instanceof Calendar)
-                               prop.setValue((Calendar) value);
-                       else if (value instanceof BigDecimal)
-                               prop.setValue((BigDecimal) value);
-                       else if (value instanceof Boolean)
-                               prop.setValue((Boolean) value);
-                       else if (value instanceof byte[])
-                               JcrUtils.setBinaryAsBytes(prop, (byte[]) value);
-                       else if (value instanceof Instant) {
-                               Instant instant = (Instant) value;
-                               GregorianCalendar calendar = new GregorianCalendar();
-                               calendar.setTime(Date.from(instant));
-                               prop.setValue(calendar);
-                       } else // try with toString()
-                               prop.setValue(value.toString());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set property " + property + " of " + node + " to " + value, e);
-               }
-       }
-
-       /**
-        * Get property as {@link String}.
-        * 
-        * @return the value of
-        *         {@link Node#getProperty(String)}.{@link Property#getString()} or
-        *         <code>null</code> if the property does not exist.
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static String get(Node node, String property) {
-               return get(node, property, null);
-       }
-
-       /**
-        * Get property as a {@link String}. If the property is multiple it returns the
-        * first value.
-        * 
-        * @return the value of
-        *         {@link Node#getProperty(String)}.{@link Property#getString()} or
-        *         <code>defaultValue</code> if the property does not exist.
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static String get(Node node, String property, String defaultValue) {
-               try {
-                       if (node.hasProperty(property)) {
-                               Property p = node.getProperty(property);
-                               if (!p.isMultiple())
-                                       return p.getString();
-                               else {
-                                       Value[] values = p.getValues();
-                                       if (values.length == 0)
-                                               return defaultValue;
-                                       else
-                                               return values[0].getString();
-                               }
-                       } else
-                               return defaultValue;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve property " + property + " from " + node, e);
-               }
-       }
-
-       /**
-        * Get property as a {@link Value}.
-        * 
-        * @return {@link Node#getProperty(String)} or <code>null</code> if the property
-        *         does not exist.
-        * @throws JcrException caused by {@link RepositoryException}
-        */
-       public static Value getValue(Node node, String property) {
-               try {
-                       if (node.hasProperty(property))
-                               return node.getProperty(property).getValue();
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve property " + property + " from " + node, e);
-               }
-       }
-
-       /**
-        * Get property doing a best effort to cast it as the target object.
-        * 
-        * @return the value of {@link Node#getProperty(String)} or
-        *         <code>defaultValue</code> if the property does not exist.
-        * @throws IllegalArgumentException if the value could not be cast
-        * @throws JcrException             in case of unexpected
-        *                                  {@link RepositoryException}
-        */
-       @SuppressWarnings("unchecked")
-       public static <T> T getAs(Node node, String property, T defaultValue) {
-               try {
-                       // TODO deal with multiple
-                       if (node.hasProperty(property)) {
-                               Property p = node.getProperty(property);
-                               try {
-                                       if (p.isMultiple()) {
-                                               throw new UnsupportedOperationException("Multiple values properties are not supported");
-                                       }
-                                       Value value = p.getValue();
-                                       return (T) get(value);
-                               } catch (ClassCastException e) {
-                                       throw new IllegalArgumentException(
-                                                       "Cannot cast property of type " + PropertyType.nameFromValue(p.getType()), e);
-                               }
-                       } else {
-                               return defaultValue;
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve property " + property + " from " + node, e);
-               }
-       }
-
-       public static <T> T getAs(Node node, String property, Class<T> clss) {
-               if (String.class.isAssignableFrom(clss)) {
-                       return (T) get(node, property);
-               } else if (Long.class.isAssignableFrom(clss)) {
-                       return (T) get(node, property);
-               } else {
-                       throw new IllegalArgumentException("Unsupported format " + clss);
-               }
-       }
-
-       /**
-        * Get a multiple property as a list, doing a best effort to cast it as the
-        * target list.
-        * 
-        * @return the value of {@link Node#getProperty(String)}.
-        * @throws IllegalArgumentException if the value could not be cast
-        * @throws JcrException             in case of unexpected
-        *                                  {@link RepositoryException}
-        */
-       public static <T> List<T> getMultiple(Node node, String property) {
-               try {
-                       if (node.hasProperty(property)) {
-                               Property p = node.getProperty(property);
-                               return getMultiple(p);
-                       } else {
-                               return null;
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve multiple values property " + property + " from " + node, e);
-               }
-       }
-
-       /**
-        * Get a multiple property as a list, doing a best effort to cast it as the
-        * target list.
-        */
-       @SuppressWarnings("unchecked")
-       public static <T> List<T> getMultiple(Property p) {
-               try {
-                       List<T> res = new ArrayList<>();
-                       if (!p.isMultiple()) {
-                               res.add((T) get(p.getValue()));
-                               return res;
-                       }
-                       Value[] values = p.getValues();
-                       for (Value value : values) {
-                               res.add((T) get(value));
-                       }
-                       return res;
-               } catch (ClassCastException | RepositoryException e) {
-                       throw new IllegalArgumentException("Cannot get property " + p, e);
-               }
-       }
-
-       /** Cast a {@link Value} to a standard Java object. */
-       public static Object get(Value value) {
-               Binary binary = null;
-               try {
-                       switch (value.getType()) {
-                       case PropertyType.STRING:
-                               return value.getString();
-                       case PropertyType.DOUBLE:
-                               return (Double) value.getDouble();
-                       case PropertyType.LONG:
-                               return (Long) value.getLong();
-                       case PropertyType.BOOLEAN:
-                               return (Boolean) value.getBoolean();
-                       case PropertyType.DATE:
-                               return value.getDate();
-                       case PropertyType.BINARY:
-                               binary = value.getBinary();
-                               byte[] arr = null;
-                               try (InputStream in = binary.getStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
-                                       IOUtils.copy(in, out);
-                                       arr = out.toByteArray();
-                               } catch (IOException e) {
-                                       throw new RuntimeException("Cannot read binary from " + value, e);
-                               }
-                               return arr;
-                       default:
-                               return value.getString();
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot cast value from " + value, e);
-               } finally {
-                       if (binary != null)
-                               binary.dispose();
-               }
-       }
-
-       /**
-        * Retrieves the {@link Session} related to this node.
-        * 
-        * @deprecated Use {@link #getSession(Node)} instead.
-        */
-       @Deprecated
-       public static Session session(Node node) {
-               return getSession(node);
-       }
-
-       /** Retrieves the {@link Session} related to this node. */
-       public static Session getSession(Node node) {
-               try {
-                       return node.getSession();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve session related to " + node, e);
-               }
-       }
-
-       /** Retrieves the root node related to this session. */
-       public static Node getRootNode(Session session) {
-               try {
-                       return session.getRootNode();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get root node for " + session, e);
-               }
-       }
-
-       /** Whether this item exists. */
-       public static boolean itemExists(Session session, String path) {
-               try {
-                       return session.itemExists(path);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check whether " + path + " exists", e);
-               }
-       }
-
-       /**
-        * Saves the {@link Session} related to this node. Note that all other unrelated
-        * modifications in this session will also be saved.
-        */
-       public static void save(Node node) {
-               try {
-                       Session session = node.getSession();
-//                     if (node.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
-//                             set(node, Property.JCR_LAST_MODIFIED, Instant.now());
-//                             set(node, Property.JCR_LAST_MODIFIED_BY, session.getUserID());
-//                     }
-                       if (session.hasPendingChanges())
-                               session.save();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot save session related to " + node + " in workspace "
-                                       + session(node).getWorkspace().getName(), e);
-               }
-       }
-
-       /** Login to a JCR repository. */
-       public static Session login(Repository repository, String workspace) {
-               try {
-                       return repository.login(workspace);
-               } catch (RepositoryException e) {
-                       throw new IllegalArgumentException("Cannot login to repository", e);
-               }
-       }
-
-       /** Safely and silently logs out a session. */
-       public static void logout(Session session) {
-               try {
-                       if (session != null)
-                               if (session.isLive())
-                                       session.logout();
-               } catch (Exception e) {
-                       // silent
-               }
-       }
-
-       /** Safely and silently logs out the underlying session. */
-       public static void logout(Node node) {
-               Jcr.logout(session(node));
-       }
-
-       /*
-        * SECURITY
-        */
-       /**
-        * Add a single privilege to a node.
-        * 
-        * @see Privilege
-        */
-       public static void addPrivilege(Node node, String principal, String privilege) {
-               try {
-                       Session session = node.getSession();
-                       JcrUtils.addPrivilege(session, node.getPath(), principal, privilege);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot add privilege " + privilege + " to " + node, e);
-               }
-       }
-
-       /*
-        * VERSIONING
-        */
-       /** Get checked out status. */
-       public static boolean isCheckedOut(Node node) {
-               try {
-                       return node.isCheckedOut();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve checked out status of " + node, e);
-               }
-       }
-
-       /** @see VersionManager#checkpoint(String) */
-       public static void checkpoint(Node node) {
-               try {
-                       versionManager(node).checkpoint(node.getPath());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check in " + node, e);
-               }
-       }
-
-       /** @see VersionManager#checkin(String) */
-       public static void checkin(Node node) {
-               try {
-                       versionManager(node).checkin(node.getPath());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check in " + node, e);
-               }
-       }
-
-       /** @see VersionManager#checkout(String) */
-       public static void checkout(Node node) {
-               try {
-                       versionManager(node).checkout(node.getPath());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check out " + node, e);
-               }
-       }
-
-       /** Get the {@link VersionManager} related to this node. */
-       public static VersionManager versionManager(Node node) {
-               try {
-                       return node.getSession().getWorkspace().getVersionManager();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get version manager from " + node, e);
-               }
-       }
-
-       /** Get the {@link VersionHistory} related to this node. */
-       public static VersionHistory getVersionHistory(Node node) {
-               try {
-                       return versionManager(node).getVersionHistory(node.getPath());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get version history from " + node, e);
-               }
-       }
-
-       /**
-        * The linear versions of this version history in reverse order and without the
-        * root version.
-        */
-       public static List<Version> getLinearVersions(VersionHistory versionHistory) {
-               try {
-                       List<Version> lst = new ArrayList<>();
-                       VersionIterator vit = versionHistory.getAllLinearVersions();
-                       while (vit.hasNext())
-                               lst.add(vit.nextVersion());
-                       lst.remove(0);
-                       Collections.reverse(lst);
-                       return lst;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get linear versions from " + versionHistory, e);
-               }
-       }
-
-       /** The frozen node related to this {@link Version}. */
-       public static Node getFrozenNode(Version version) {
-               try {
-                       return version.getFrozenNode();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get frozen node from " + version, e);
-               }
-       }
-
-       /** Get the base {@link Version} related to this node. */
-       public static Version getBaseVersion(Node node) {
-               try {
-                       return versionManager(node).getBaseVersion(node.getPath());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get base version from " + node, e);
-               }
-       }
-
-       /*
-        * FILES
-        */
-       /**
-        * Returns the size of this file.
-        * 
-        * @see NodeType#NT_FILE
-        */
-       public static long getFileSize(Node fileNode) {
-               try {
-                       if (!fileNode.isNodeType(NodeType.NT_FILE))
-                               throw new IllegalArgumentException(fileNode + " must be a file.");
-                       return getBinarySize(fileNode.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get file size of " + fileNode, e);
-               }
-       }
-
-       /** Returns the size of this {@link Binary}. */
-       public static long getBinarySize(Binary binaryArg) {
-               try {
-                       try (Bin binary = new Bin(binaryArg)) {
-                               return binary.getSize();
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get file size of binary " + binaryArg, e);
-               }
-       }
-
-       // QUERY
-       /** Creates a JCR-SQL2 query using {@link MessageFormat}. */
-       public static Query createQuery(QueryManager qm, String sql, Object... args) {
-               // fix single quotes
-               sql = sql.replaceAll("'", "''");
-               String query = MessageFormat.format(sql, args);
-               try {
-                       return qm.createQuery(query, Query.JCR_SQL2);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot create JCR-SQL2 query from " + query, e);
-               }
-       }
-
-       /** Executes a JCR-SQL2 query using {@link MessageFormat}. */
-       public static NodeIterator executeQuery(QueryManager qm, String sql, Object... args) {
-               Query query = createQuery(qm, sql, args);
-               try {
-                       return query.execute().getNodes();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot execute query " + sql + " with arguments " + Arrays.asList(args), e);
-               }
-       }
-
-       /** Executes a JCR-SQL2 query using {@link MessageFormat}. */
-       public static NodeIterator executeQuery(Session session, String sql, Object... args) {
-               QueryManager queryManager;
-               try {
-                       queryManager = session.getWorkspace().getQueryManager();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get query manager from session " + session, e);
-               }
-               return executeQuery(queryManager, sql, args);
-       }
-
-       /**
-        * Executes a JCR-SQL2 query using {@link MessageFormat}, which must return a
-        * single node at most.
-        * 
-        * @return the node or <code>null</code> if not found.
-        */
-       public static Node getNode(QueryManager qm, String sql, Object... args) {
-               NodeIterator nit = executeQuery(qm, sql, args);
-               if (nit.hasNext()) {
-                       Node node = nit.nextNode();
-                       if (nit.hasNext())
-                               throw new IllegalStateException(
-                                               "Query " + sql + " with arguments " + Arrays.asList(args) + " returned more than one node.");
-                       return node;
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Executes a JCR-SQL2 query using {@link MessageFormat}, which must return a
-        * single node at most.
-        * 
-        * @return the node or <code>null</code> if not found.
-        */
-       public static Node getNode(Session session, String sql, Object... args) {
-               QueryManager queryManager;
-               try {
-                       queryManager = session.getWorkspace().getQueryManager();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get query manager from session " + session, e);
-               }
-               return getNode(queryManager, sql, args);
-       }
-
-       public static Node getRowNode(Row row, String selectorName) {
-               try {
-                       return row.getNode(selectorName);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get node " + selectorName + " from row", e);
-               }
-       }
-
-       /** Singleton. */
-       private Jcr() {
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrAuthorizations.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrAuthorizations.java
deleted file mode 100644 (file)
index 351929f..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-package org.argeo.jcr;
-
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.security.AccessControlManager;
-import javax.jcr.security.Privilege;
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-
-/** Apply authorizations to a JCR repository. */
-public class JcrAuthorizations implements Runnable {
-       // private final static Log log =
-       // LogFactory.getLog(JcrAuthorizations.class);
-
-       private Repository repository;
-       private String workspace = null;
-
-       private String securityWorkspace = "security";
-
-       /**
-        * key := privilege1,privilege2/path/to/node<br/>
-        * value := group1,group2,user1
-        */
-       private Map<String, String> principalPrivileges = new HashMap<String, String>();
-
-       public void run() {
-               String currentWorkspace = workspace;
-               Session session = null;
-               try {
-                       if (workspace != null && workspace.equals("*")) {
-                               session = repository.login();
-                               String[] workspaces = session.getWorkspace().getAccessibleWorkspaceNames();
-                               JcrUtils.logoutQuietly(session);
-                               for (String wksp : workspaces) {
-                                       currentWorkspace = wksp;
-                                       if (currentWorkspace.equals(securityWorkspace))
-                                               continue;
-                                       session = repository.login(currentWorkspace);
-                                       initAuthorizations(session);
-                                       JcrUtils.logoutQuietly(session);
-                               }
-                       } else {
-                               session = repository.login(workspace);
-                               initAuthorizations(session);
-                       }
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new JcrException(
-                                       "Cannot set authorizations " + principalPrivileges + " on workspace " + currentWorkspace, e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       protected void processWorkspace(String workspace) {
-               Session session = null;
-               try {
-                       session = repository.login(workspace);
-                       initAuthorizations(session);
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new JcrException(
-                                       "Cannot set authorizations " + principalPrivileges + " on repository " + repository, e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       /** @deprecated call {@link #run()} instead. */
-       @Deprecated
-       public void init() {
-               run();
-       }
-
-       protected void initAuthorizations(Session session) throws RepositoryException {
-               AccessControlManager acm = session.getAccessControlManager();
-
-               for (String privileges : principalPrivileges.keySet()) {
-                       String path = null;
-                       int slashIndex = privileges.indexOf('/');
-                       if (slashIndex == 0) {
-                               throw new IllegalArgumentException("Privilege " + privileges + " badly formatted it starts with /");
-                       } else if (slashIndex > 0) {
-                               path = privileges.substring(slashIndex);
-                               privileges = privileges.substring(0, slashIndex);
-                       }
-
-                       if (path == null)
-                               path = "/";
-
-                       List<Privilege> privs = new ArrayList<Privilege>();
-                       for (String priv : privileges.split(",")) {
-                               privs.add(acm.privilegeFromName(priv));
-                       }
-
-                       String principalNames = principalPrivileges.get(privileges);
-                       try {
-                               new LdapName(principalNames);
-                               // TODO differentiate groups and users ?
-                               Principal principal = getOrCreatePrincipal(session, principalNames);
-                               JcrUtils.addPrivileges(session, path, principal, privs);
-                       } catch (InvalidNameException e) {
-                               for (String principalName : principalNames.split(",")) {
-                                       Principal principal = getOrCreatePrincipal(session, principalName);
-                                       JcrUtils.addPrivileges(session, path, principal, privs);
-                                       // if (log.isDebugEnabled()) {
-                                       // StringBuffer privBuf = new StringBuffer();
-                                       // for (Privilege priv : privs)
-                                       // privBuf.append(priv.getName());
-                                       // log.debug("Added privileges " + privBuf + " to "
-                                       // + principal.getName() + " on " + path + " in '"
-                                       // + session.getWorkspace().getName() + "'");
-                                       // }
-                               }
-                       }
-               }
-
-               // if (log.isDebugEnabled())
-               // log.debug("JCR authorizations applied on '"
-               // + session.getWorkspace().getName() + "'");
-       }
-
-       /**
-        * Returns a {@link SimplePrincipal}, does not check whether it exists since
-        * such capabilities is not provided by the standard JCR API. Can be
-        * overridden to provide smarter handling
-        */
-       protected Principal getOrCreatePrincipal(Session session, String principalName) throws RepositoryException {
-               return new SimplePrincipal(principalName);
-       }
-
-       // public static void addPrivileges(Session session, Principal principal,
-       // String path, List<Privilege> privs) throws RepositoryException {
-       // AccessControlManager acm = session.getAccessControlManager();
-       // // search for an access control list
-       // AccessControlList acl = null;
-       // AccessControlPolicyIterator policyIterator = acm
-       // .getApplicablePolicies(path);
-       // if (policyIterator.hasNext()) {
-       // while (policyIterator.hasNext()) {
-       // AccessControlPolicy acp = policyIterator
-       // .nextAccessControlPolicy();
-       // if (acp instanceof AccessControlList)
-       // acl = ((AccessControlList) acp);
-       // }
-       // } else {
-       // AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
-       // for (AccessControlPolicy acp : existingPolicies) {
-       // if (acp instanceof AccessControlList)
-       // acl = ((AccessControlList) acp);
-       // }
-       // }
-       //
-       // if (acl != null) {
-       // acl.addAccessControlEntry(principal,
-       // privs.toArray(new Privilege[privs.size()]));
-       // acm.setPolicy(path, acl);
-       // session.save();
-       // if (log.isDebugEnabled()) {
-       // StringBuffer buf = new StringBuffer("");
-       // for (int i = 0; i < privs.size(); i++) {
-       // if (i != 0)
-       // buf.append(',');
-       // buf.append(privs.get(i).getName());
-       // }
-       // log.debug("Added privilege(s) '" + buf + "' to '"
-       // + principal.getName() + "' on " + path
-       // + " from workspace '"
-       // + session.getWorkspace().getName() + "'");
-       // }
-       // } else {
-       // throw new ArgeoJcrException("Don't know how to apply privileges "
-       // + privs + " to " + principal + " on " + path
-       // + " from workspace '" + session.getWorkspace().getName()
-       // + "'");
-       // }
-       // }
-
-       @Deprecated
-       public void setGroupPrivileges(Map<String, String> groupPrivileges) {
-               this.principalPrivileges = groupPrivileges;
-       }
-
-       public void setPrincipalPrivileges(Map<String, String> principalPrivileges) {
-               this.principalPrivileges = principalPrivileges;
-       }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setWorkspace(String workspace) {
-               this.workspace = workspace;
-       }
-
-       public void setSecurityWorkspace(String securityWorkspace) {
-               this.securityWorkspace = securityWorkspace;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrCallback.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrCallback.java
deleted file mode 100644 (file)
index efbaabe..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.argeo.jcr;
-
-import java.util.function.Function;
-
-import javax.jcr.Session;
-
-/** An arbitrary execution on a JCR session, optionally returning a result. */
-@FunctionalInterface
-public interface JcrCallback extends Function<Session, Object> {
-       /** @deprecated Use {@link #apply(Session)} instead. */
-       @Deprecated
-       public default Object execute(Session session) {
-               return apply(session);
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrException.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrException.java
deleted file mode 100644 (file)
index c778743..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.argeo.jcr;
-
-import javax.jcr.RepositoryException;
-
-/**
- * Wraps a {@link RepositoryException} in a {@link RuntimeException}.
- */
-public class JcrException extends IllegalStateException {
-       private static final long serialVersionUID = -4530350094877964989L;
-
-       public JcrException(String message, RepositoryException e) {
-               super(message, e);
-       }
-
-       public JcrException(RepositoryException e) {
-               super(e);
-       }
-
-       public RepositoryException getRepositoryCause() {
-               return (RepositoryException) getCause();
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrMonitor.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrMonitor.java
deleted file mode 100644 (file)
index 71cf961..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.argeo.jcr;
-
-
-/**
- * Simple monitor abstraction. Inspired by Eclipse IProgressMOnitor, but without
- * dependency to it.
- */
-public interface JcrMonitor {
-       /**
-        * Constant indicating an unknown amount of work.
-        */
-       public final static int UNKNOWN = -1;
-
-       /**
-        * Notifies that the main task is beginning. This must only be called once
-        * on a given progress monitor instance.
-        * 
-        * @param name
-        *            the name (or description) of the main task
-        * @param totalWork
-        *            the total number of work units into which the main task is
-        *            been subdivided. If the value is <code>UNKNOWN</code> the
-        *            implementation is free to indicate progress in a way which
-        *            doesn't require the total number of work units in advance.
-        */
-       public void beginTask(String name, int totalWork);
-
-       /**
-        * Notifies that the work is done; that is, either the main task is
-        * completed or the user canceled it. This method may be called more than
-        * once (implementations should be prepared to handle this case).
-        */
-       public void done();
-
-       /**
-        * Returns whether cancelation of current operation has been requested.
-        * Long-running operations should poll to see if cancelation has been
-        * requested.
-        * 
-        * @return <code>true</code> if cancellation has been requested, and
-        *         <code>false</code> otherwise
-        * @see #setCanceled(boolean)
-        */
-       public boolean isCanceled();
-
-       /**
-        * Sets the cancel state to the given value.
-        * 
-        * @param value
-        *            <code>true</code> indicates that cancelation has been
-        *            requested (but not necessarily acknowledged);
-        *            <code>false</code> clears this flag
-        * @see #isCanceled()
-        */
-       public void setCanceled(boolean value);
-
-       /**
-        * Sets the task name to the given value. This method is used to restore the
-        * task label after a nested operation was executed. Normally there is no
-        * need for clients to call this method.
-        * 
-        * @param name
-        *            the name (or description) of the main task
-        * @see #beginTask(java.lang.String, int)
-        */
-       public void setTaskName(String name);
-
-       /**
-        * Notifies that a subtask of the main task is beginning. Subtasks are
-        * optional; the main task might not have subtasks.
-        * 
-        * @param name
-        *            the name (or description) of the subtask
-        */
-       public void subTask(String name);
-
-       /**
-        * Notifies that a given number of work unit of the main task has been
-        * completed. Note that this amount represents an installment, as opposed to
-        * a cumulative amount of work done to date.
-        * 
-        * @param work
-        *            a non-negative number of work units just completed
-        */
-       public void worked(int work);
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrRepositoryWrapper.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrRepositoryWrapper.java
deleted file mode 100644 (file)
index 3228eee..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-package org.argeo.jcr;
-
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Binary;
-import javax.jcr.Credentials;
-import javax.jcr.LoginException;
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.PropertyType;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFormatException;
-
-/**
- * Wrapper around a JCR repository which allows to simplify configuration and
- * intercept some actions. It exposes itself as a {@link Repository}.
- */
-public abstract class JcrRepositoryWrapper implements Repository {
-       // private final static Log log = LogFactory
-       // .getLog(JcrRepositoryWrapper.class);
-
-       // wrapped repository
-       private Repository repository;
-
-       private Map<String, String> additionalDescriptors = new HashMap<>();
-
-       private Boolean autocreateWorkspaces = false;
-
-       public JcrRepositoryWrapper(Repository repository) {
-               setRepository(repository);
-       }
-
-       /**
-        * Empty constructor
-        */
-       public JcrRepositoryWrapper() {
-       }
-
-       // /** Initializes */
-       // public void init() {
-       // }
-       //
-       // /** Shutdown the repository */
-       // public void destroy() throws Exception {
-       // }
-
-       protected void putDescriptor(String key, String value) {
-               if (Arrays.asList(getRepository().getDescriptorKeys()).contains(key))
-                       throw new IllegalArgumentException("Descriptor key " + key + " is already defined in wrapped repository");
-               if (value == null)
-                       additionalDescriptors.remove(key);
-               else
-                       additionalDescriptors.put(key, value);
-       }
-
-       /*
-        * DELEGATED JCR REPOSITORY METHODS
-        */
-
-       public String getDescriptor(String key) {
-               if (additionalDescriptors.containsKey(key))
-                       return additionalDescriptors.get(key);
-               return getRepository().getDescriptor(key);
-       }
-
-       public String[] getDescriptorKeys() {
-               if (additionalDescriptors.size() == 0)
-                       return getRepository().getDescriptorKeys();
-               List<String> keys = Arrays.asList(getRepository().getDescriptorKeys());
-               keys.addAll(additionalDescriptors.keySet());
-               return keys.toArray(new String[keys.size()]);
-       }
-
-       /** Central login method */
-       public Session login(Credentials credentials, String workspaceName)
-                       throws LoginException, NoSuchWorkspaceException, RepositoryException {
-               Session session;
-               try {
-                       session = getRepository(workspaceName).login(credentials, workspaceName);
-               } catch (NoSuchWorkspaceException e) {
-                       if (autocreateWorkspaces && workspaceName != null)
-                               session = createWorkspaceAndLogsIn(credentials, workspaceName);
-                       else
-                               throw e;
-               }
-               processNewSession(session, workspaceName);
-               return session;
-       }
-
-       public Session login() throws LoginException, RepositoryException {
-               return login(null, null);
-       }
-
-       public Session login(Credentials credentials) throws LoginException, RepositoryException {
-               return login(credentials, null);
-       }
-
-       public Session login(String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException {
-               return login(null, workspaceName);
-       }
-
-       /** Called after a session has been created, does nothing by default. */
-       protected void processNewSession(Session session, String workspaceName) {
-       }
-
-       /**
-        * Wraps access to the repository, making sure it is available.
-        * 
-        * @deprecated Use {@link #getDefaultRepository()} instead.
-        */
-       @Deprecated
-       protected synchronized Repository getRepository() {
-               return getDefaultRepository();
-       }
-
-       protected synchronized Repository getDefaultRepository() {
-               return repository;
-       }
-
-       protected synchronized Repository getRepository(String workspaceName) {
-               return getDefaultRepository();
-       }
-
-       /**
-        * Logs in to the default workspace, creates the required workspace, logs out,
-        * logs in to the required workspace.
-        */
-       protected Session createWorkspaceAndLogsIn(Credentials credentials, String workspaceName)
-                       throws RepositoryException {
-               if (workspaceName == null)
-                       throw new IllegalArgumentException("No workspace specified.");
-               Session session = getRepository(workspaceName).login(credentials);
-               session.getWorkspace().createWorkspace(workspaceName);
-               session.logout();
-               return getRepository(workspaceName).login(credentials, workspaceName);
-       }
-
-       public boolean isStandardDescriptor(String key) {
-               return getRepository().isStandardDescriptor(key);
-       }
-
-       public boolean isSingleValueDescriptor(String key) {
-               if (additionalDescriptors.containsKey(key))
-                       return true;
-               return getRepository().isSingleValueDescriptor(key);
-       }
-
-       public Value getDescriptorValue(String key) {
-               if (additionalDescriptors.containsKey(key))
-                       return new StrValue(additionalDescriptors.get(key));
-               return getRepository().getDescriptorValue(key);
-       }
-
-       public Value[] getDescriptorValues(String key) {
-               return getRepository().getDescriptorValues(key);
-       }
-
-       public synchronized void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setAutocreateWorkspaces(Boolean autocreateWorkspaces) {
-               this.autocreateWorkspaces = autocreateWorkspaces;
-       }
-
-       protected static class StrValue implements Value {
-               private final String str;
-
-               public StrValue(String str) {
-                       this.str = str;
-               }
-
-               @Override
-               public String getString() throws ValueFormatException, IllegalStateException, RepositoryException {
-                       return str;
-               }
-
-               @Override
-               public InputStream getStream() throws RepositoryException {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public Binary getBinary() throws RepositoryException {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public long getLong() throws ValueFormatException, RepositoryException {
-                       try {
-                               return Long.parseLong(str);
-                       } catch (NumberFormatException e) {
-                               throw new ValueFormatException("Cannot convert", e);
-                       }
-               }
-
-               @Override
-               public double getDouble() throws ValueFormatException, RepositoryException {
-                       try {
-                               return Double.parseDouble(str);
-                       } catch (NumberFormatException e) {
-                               throw new ValueFormatException("Cannot convert", e);
-                       }
-               }
-
-               @Override
-               public BigDecimal getDecimal() throws ValueFormatException, RepositoryException {
-                       try {
-                               return new BigDecimal(str);
-                       } catch (NumberFormatException e) {
-                               throw new ValueFormatException("Cannot convert", e);
-                       }
-               }
-
-               @Override
-               public Calendar getDate() throws ValueFormatException, RepositoryException {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public boolean getBoolean() throws ValueFormatException, RepositoryException {
-                       try {
-                               return Boolean.parseBoolean(str);
-                       } catch (NumberFormatException e) {
-                               throw new ValueFormatException("Cannot convert", e);
-                       }
-               }
-
-               @Override
-               public int getType() {
-                       return PropertyType.STRING;
-               }
-
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUrlStreamHandler.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUrlStreamHandler.java
deleted file mode 100644 (file)
index 82a65e7..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.argeo.jcr;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLStreamHandler;
-
-import javax.jcr.Item;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-/** URL stream handler able to deal with nt:file node and properties. NOT FINISHED */
-public class JcrUrlStreamHandler extends URLStreamHandler {
-       private final Session session;
-
-       public JcrUrlStreamHandler(Session session) {
-               this.session = session;
-       }
-
-       @Override
-       protected URLConnection openConnection(final URL u) throws IOException {
-               // TODO Auto-generated method stub
-               return new URLConnection(u) {
-
-                       @Override
-                       public void connect() throws IOException {
-                               String itemPath = u.getPath();
-                               try {
-                                       if (!session.itemExists(itemPath))
-                                               throw new IOException("No item under " + itemPath);
-
-                                       Item item = session.getItem(u.getPath());
-                                       if (item.isNode()) {
-                                               // this should be a nt:file node
-                                               Node node = (Node) item;
-                                               if (!node.getPrimaryNodeType().isNodeType(
-                                                               NodeType.NT_FILE))
-                                                       throw new IOException("Node " + node + " is not a "
-                                                                       + NodeType.NT_FILE);
-
-                                       } else {
-                                               Property property = (Property) item;
-                                               if(property.getType()==PropertyType.BINARY){
-                                                       //Binary binary = property.getBinary();
-                                                       
-                                               }
-                                       }
-                               } catch (RepositoryException e) {
-                                       IOException ioe = new IOException(
-                                                       "Unexpected JCR exception");
-                                       ioe.initCause(e);
-                                       throw ioe;
-                               }
-                       }
-
-                       @Override
-                       public InputStream getInputStream() throws IOException {
-                               // TODO Auto-generated method stub
-                               return super.getInputStream();
-                       }
-
-               };
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUtils.java
deleted file mode 100644 (file)
index 1f1fa11..0000000
+++ /dev/null
@@ -1,1786 +0,0 @@
-package org.argeo.jcr;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.jcr.Binary;
-import javax.jcr.Credentials;
-import javax.jcr.ImportUUIDBehavior;
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.Workspace;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.observation.EventListener;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryResult;
-import javax.jcr.security.AccessControlEntry;
-import javax.jcr.security.AccessControlList;
-import javax.jcr.security.AccessControlManager;
-import javax.jcr.security.AccessControlPolicy;
-import javax.jcr.security.AccessControlPolicyIterator;
-import javax.jcr.security.Privilege;
-
-import org.apache.commons.io.IOUtils;
-
-/** Utility methods to simplify common JCR operations. */
-public class JcrUtils {
-
-//     final private static Log log = LogFactory.getLog(JcrUtils.class);
-
-       /**
-        * Not complete yet. See
-        * http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.2.2%20Local
-        * %20Names
-        */
-       public final static char[] INVALID_NAME_CHARACTERS = { '/', ':', '[', ']', '|', '*', /* invalid for XML: */ '<',
-                       '>', '&' };
-
-       /** Prevents instantiation */
-       private JcrUtils() {
-       }
-
-       /**
-        * Queries one single node.
-        * 
-        * @return one single node or null if none was found
-        * @throws JcrException if more than one node was found
-        */
-       public static Node querySingleNode(Query query) {
-               NodeIterator nodeIterator;
-               try {
-                       QueryResult queryResult = query.execute();
-                       nodeIterator = queryResult.getNodes();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot execute query " + query, e);
-               }
-               Node node;
-               if (nodeIterator.hasNext())
-                       node = nodeIterator.nextNode();
-               else
-                       return null;
-
-               if (nodeIterator.hasNext())
-                       throw new IllegalArgumentException("Query returned more than one node.");
-               return node;
-       }
-
-       /** Retrieves the node name from the provided path */
-       public static String nodeNameFromPath(String path) {
-               if (path.equals("/"))
-                       return "";
-               if (path.charAt(0) != '/')
-                       throw new IllegalArgumentException("Path " + path + " must start with a '/'");
-               String pathT = path;
-               if (pathT.charAt(pathT.length() - 1) == '/')
-                       pathT = pathT.substring(0, pathT.length() - 2);
-
-               int index = pathT.lastIndexOf('/');
-               return pathT.substring(index + 1);
-       }
-
-       /** Retrieves the parent path of the provided path */
-       public static String parentPath(String path) {
-               if (path.equals("/"))
-                       throw new IllegalArgumentException("Root path '/' has no parent path");
-               if (path.charAt(0) != '/')
-                       throw new IllegalArgumentException("Path " + path + " must start with a '/'");
-               String pathT = path;
-               if (pathT.charAt(pathT.length() - 1) == '/')
-                       pathT = pathT.substring(0, pathT.length() - 2);
-
-               int index = pathT.lastIndexOf('/');
-               return pathT.substring(0, index);
-       }
-
-       /** The provided data as a path ('/' at the end, not the beginning) */
-       public static String dateAsPath(Calendar cal) {
-               return dateAsPath(cal, false);
-       }
-
-       /**
-        * Creates a deep path based on a URL:
-        * http://subdomain.example.com/to/content?args becomes
-        * com/example/subdomain/to/content
-        */
-       public static String urlAsPath(String url) {
-               try {
-                       URL u = new URL(url);
-                       StringBuffer path = new StringBuffer(url.length());
-                       // invert host
-                       path.append(hostAsPath(u.getHost()));
-                       // we don't put port since it may not always be there and may change
-                       path.append(u.getPath());
-                       return path.toString();
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot generate URL path for " + url, e);
-               }
-       }
-
-       /** Set the {@link NodeType#NT_ADDRESS} properties based on this URL. */
-       public static void urlToAddressProperties(Node node, String url) {
-               try {
-                       URL u = new URL(url);
-                       node.setProperty(Property.JCR_PROTOCOL, u.getProtocol());
-                       node.setProperty(Property.JCR_HOST, u.getHost());
-                       node.setProperty(Property.JCR_PORT, Integer.toString(u.getPort()));
-                       node.setProperty(Property.JCR_PATH, normalizePath(u.getPath()));
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set URL " + url + " as nt:address properties", e);
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot set URL " + url + " as nt:address properties", e);
-               }
-       }
-
-       /** Build URL based on the {@link NodeType#NT_ADDRESS} properties. */
-       public static String urlFromAddressProperties(Node node) {
-               try {
-                       URL u = new URL(node.getProperty(Property.JCR_PROTOCOL).getString(),
-                                       node.getProperty(Property.JCR_HOST).getString(),
-                                       (int) node.getProperty(Property.JCR_PORT).getLong(),
-                                       node.getProperty(Property.JCR_PATH).getString());
-                       return u.toString();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get URL from nt:address properties of " + node, e);
-               } catch (MalformedURLException e) {
-                       throw new IllegalArgumentException("Cannot get URL from nt:address properties of " + node, e);
-               }
-       }
-
-       /*
-        * PATH UTILITIES
-        */
-
-       /**
-        * Make sure that: starts with '/', do not end with '/', do not have '//'
-        */
-       public static String normalizePath(String path) {
-               List<String> tokens = tokenize(path);
-               StringBuffer buf = new StringBuffer(path.length());
-               for (String token : tokens) {
-                       buf.append('/');
-                       buf.append(token);
-               }
-               return buf.toString();
-       }
-
-       /**
-        * Creates a path from a FQDN, inverting the order of the component:
-        * www.argeo.org becomes org.argeo.www
-        */
-       public static String hostAsPath(String host) {
-               StringBuffer path = new StringBuffer(host.length());
-               String[] hostTokens = host.split("\\.");
-               for (int i = hostTokens.length - 1; i >= 0; i--) {
-                       path.append(hostTokens[i]);
-                       if (i != 0)
-                               path.append('/');
-               }
-               return path.toString();
-       }
-
-       /**
-        * Creates a path from a UUID (e.g. 6ebda899-217d-4bf1-abe4-2839085c8f3c becomes
-        * 6ebda899-217d/4bf1/abe4/2839085c8f3c/). '/' at the end, not the beginning
-        */
-       public static String uuidAsPath(String uuid) {
-               StringBuffer path = new StringBuffer(uuid.length());
-               String[] tokens = uuid.split("-");
-               for (int i = 0; i < tokens.length; i++) {
-                       path.append(tokens[i]);
-                       if (i != 0)
-                               path.append('/');
-               }
-               return path.toString();
-       }
-
-       /**
-        * The provided data as a path ('/' at the end, not the beginning)
-        * 
-        * @param cal     the date
-        * @param addHour whether to add hour as well
-        */
-       public static String dateAsPath(Calendar cal, Boolean addHour) {
-               StringBuffer buf = new StringBuffer(14);
-               buf.append('Y');
-               buf.append(cal.get(Calendar.YEAR));
-               buf.append('/');
-
-               int month = cal.get(Calendar.MONTH) + 1;
-               buf.append('M');
-               if (month < 10)
-                       buf.append(0);
-               buf.append(month);
-               buf.append('/');
-
-               int day = cal.get(Calendar.DAY_OF_MONTH);
-               buf.append('D');
-               if (day < 10)
-                       buf.append(0);
-               buf.append(day);
-               buf.append('/');
-
-               if (addHour) {
-                       int hour = cal.get(Calendar.HOUR_OF_DAY);
-                       buf.append('H');
-                       if (hour < 10)
-                               buf.append(0);
-                       buf.append(hour);
-                       buf.append('/');
-               }
-               return buf.toString();
-
-       }
-
-       /** Converts in one call a string into a gregorian calendar. */
-       public static Calendar parseCalendar(DateFormat dateFormat, String value) {
-               try {
-                       Date date = dateFormat.parse(value);
-                       Calendar calendar = new GregorianCalendar();
-                       calendar.setTime(date);
-                       return calendar;
-               } catch (ParseException e) {
-                       throw new IllegalArgumentException("Cannot parse " + value + " with date format " + dateFormat, e);
-               }
-
-       }
-
-       /** The last element of a path. */
-       public static String lastPathElement(String path) {
-               if (path.charAt(path.length() - 1) == '/')
-                       throw new IllegalArgumentException("Path " + path + " cannot end with '/'");
-               int index = path.lastIndexOf('/');
-               if (index < 0)
-                       return path;
-               return path.substring(index + 1);
-       }
-
-       /**
-        * Call {@link Node#getName()} without exceptions (useful in super
-        * constructors).
-        */
-       public static String getNameQuietly(Node node) {
-               try {
-                       return node.getName();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get name from " + node, e);
-               }
-       }
-
-       /**
-        * Call {@link Node#getProperty(String)} without exceptions (useful in super
-        * constructors).
-        */
-       public static String getStringPropertyQuietly(Node node, String propertyName) {
-               try {
-                       return node.getProperty(propertyName).getString();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get name from " + node, e);
-               }
-       }
-
-//     /**
-//      * Routine that get the child with this name, adding it if it does not already
-//      * exist
-//      */
-//     public static Node getOrAdd(Node parent, String name, String primaryNodeType) throws RepositoryException {
-//             return parent.hasNode(name) ? parent.getNode(name) : parent.addNode(name, primaryNodeType);
-//     }
-
-       /**
-        * Routine that get the child with this name, adding it if it does not already
-        * exist
-        */
-       public static Node getOrAdd(Node parent, String name, String primaryNodeType, String... mixinNodeTypes)
-                       throws RepositoryException {
-               Node node;
-               if (parent.hasNode(name)) {
-                       node = parent.getNode(name);
-                       if (primaryNodeType != null && !node.isNodeType(primaryNodeType))
-                               throw new IllegalArgumentException("Node " + node + " exists but is of primary node type "
-                                               + node.getPrimaryNodeType().getName() + ", not " + primaryNodeType);
-                       for (String mixin : mixinNodeTypes) {
-                               if (!node.isNodeType(mixin))
-                                       node.addMixin(mixin);
-                       }
-                       return node;
-               } else {
-                       node = primaryNodeType != null ? parent.addNode(name, primaryNodeType) : parent.addNode(name);
-                       for (String mixin : mixinNodeTypes) {
-                               node.addMixin(mixin);
-                       }
-                       return node;
-               }
-       }
-
-       /**
-        * Routine that get the child with this name, adding it if it does not already
-        * exist
-        */
-       public static Node getOrAdd(Node parent, String name) throws RepositoryException {
-               return parent.hasNode(name) ? parent.getNode(name) : parent.addNode(name);
-       }
-
-       /** Convert a {@link NodeIterator} to a list of {@link Node} */
-       public static List<Node> nodeIteratorToList(NodeIterator nodeIterator) {
-               List<Node> nodes = new ArrayList<Node>();
-               while (nodeIterator.hasNext()) {
-                       nodes.add(nodeIterator.nextNode());
-               }
-               return nodes;
-       }
-
-       /*
-        * PROPERTIES
-        */
-
-       /**
-        * Concisely get the string value of a property or null if this node doesn't
-        * have this property
-        */
-       public static String get(Node node, String propertyName) {
-               try {
-                       if (!node.hasProperty(propertyName))
-                               return null;
-                       return node.getProperty(propertyName).getString();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get property " + propertyName + " of " + node, e);
-               }
-       }
-
-       /** Concisely get the path of the given node. */
-       public static String getPath(Node node) {
-               try {
-                       return node.getPath();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get path of " + node, e);
-               }
-       }
-
-       /** Concisely get the boolean value of a property */
-       public static Boolean check(Node node, String propertyName) {
-               try {
-                       return node.getProperty(propertyName).getBoolean();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get property " + propertyName + " of " + node, e);
-               }
-       }
-
-       /** Concisely get the bytes array value of a property */
-       public static byte[] getBytes(Node node, String propertyName) {
-               try {
-                       return getBinaryAsBytes(node.getProperty(propertyName));
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get property " + propertyName + " of " + node, e);
-               }
-       }
-
-       /*
-        * MKDIRS
-        */
-
-       /**
-        * Create sub nodes relative to a parent node
-        */
-       public static Node mkdirs(Node parentNode, String relativePath) {
-               return mkdirs(parentNode, relativePath, null, null);
-       }
-
-       /**
-        * Create sub nodes relative to a parent node
-        * 
-        * @param nodeType the type of the leaf node
-        */
-       public static Node mkdirs(Node parentNode, String relativePath, String nodeType) {
-               return mkdirs(parentNode, relativePath, nodeType, null);
-       }
-
-       /**
-        * Create sub nodes relative to a parent node
-        * 
-        * @param nodeType the type of the leaf node
-        */
-       public static Node mkdirs(Node parentNode, String relativePath, String nodeType, String intermediaryNodeType) {
-               List<String> tokens = tokenize(relativePath);
-               Node currParent = parentNode;
-               try {
-                       for (int i = 0; i < tokens.size(); i++) {
-                               String name = tokens.get(i);
-                               if (currParent.hasNode(name)) {
-                                       currParent = currParent.getNode(name);
-                               } else {
-                                       if (i != (tokens.size() - 1)) {// intermediary
-                                               currParent = currParent.addNode(name, intermediaryNodeType);
-                                       } else {// leaf
-                                               currParent = currParent.addNode(name, nodeType);
-                                       }
-                               }
-                       }
-                       return currParent;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot mkdirs relative path " + relativePath + " from " + parentNode, e);
-               }
-       }
-
-       /**
-        * Synchronized and save is performed, to avoid race conditions in initializers
-        * leading to duplicate nodes.
-        */
-       public synchronized static Node mkdirsSafe(Session session, String path, String type) {
-               try {
-                       if (session.hasPendingChanges())
-                               throw new IllegalStateException("Session has pending changes, save them first.");
-                       Node node = mkdirs(session, path, type);
-                       session.save();
-                       return node;
-               } catch (RepositoryException e) {
-                       discardQuietly(session);
-                       throw new JcrException("Cannot safely make directories", e);
-               }
-       }
-
-       public synchronized static Node mkdirsSafe(Session session, String path) {
-               return mkdirsSafe(session, path, null);
-       }
-
-       /** Creates the nodes making path, if they don't exist. */
-       public static Node mkdirs(Session session, String path) {
-               return mkdirs(session, path, null, null, false);
-       }
-
-       /**
-        * @param type the type of the leaf node
-        */
-       public static Node mkdirs(Session session, String path, String type) {
-               return mkdirs(session, path, type, null, false);
-       }
-
-       /**
-        * Creates the nodes making path, if they don't exist. This is up to the caller
-        * to save the session. Use with caution since it can create duplicate nodes if
-        * used concurrently. Requires read access to the root node of the workspace.
-        */
-       public static Node mkdirs(Session session, String path, String type, String intermediaryNodeType,
-                       Boolean versioning) {
-               try {
-                       if (path.equals("/"))
-                               return session.getRootNode();
-
-                       if (session.itemExists(path)) {
-                               Node node = session.getNode(path);
-                               // check type
-                               if (type != null && !node.isNodeType(type) && !node.getPath().equals("/"))
-                                       throw new IllegalArgumentException("Node " + node + " exists but is of type "
-                                                       + node.getPrimaryNodeType().getName() + " not of type " + type);
-                               // TODO: check versioning
-                               return node;
-                       }
-
-                       // StringBuffer current = new StringBuffer("/");
-                       // Node currentNode = session.getRootNode();
-
-                       Node currentNode = findClosestExistingParent(session, path);
-                       String closestExistingParentPath = currentNode.getPath();
-                       StringBuffer current = new StringBuffer(closestExistingParentPath);
-                       if (!closestExistingParentPath.endsWith("/"))
-                               current.append('/');
-                       Iterator<String> it = tokenize(path.substring(closestExistingParentPath.length())).iterator();
-                       while (it.hasNext()) {
-                               String part = it.next();
-                               current.append(part).append('/');
-                               if (!session.itemExists(current.toString())) {
-                                       if (!it.hasNext() && type != null)
-                                               currentNode = currentNode.addNode(part, type);
-                                       else if (it.hasNext() && intermediaryNodeType != null)
-                                               currentNode = currentNode.addNode(part, intermediaryNodeType);
-                                       else
-                                               currentNode = currentNode.addNode(part);
-                                       if (versioning)
-                                               currentNode.addMixin(NodeType.MIX_VERSIONABLE);
-//                                     if (log.isTraceEnabled())
-//                                             log.debug("Added folder " + part + " as " + current);
-                               } else {
-                                       currentNode = (Node) session.getItem(current.toString());
-                               }
-                       }
-                       return currentNode;
-               } catch (RepositoryException e) {
-                       discardQuietly(session);
-                       throw new JcrException("Cannot mkdirs " + path, e);
-               } finally {
-               }
-       }
-
-       private static Node findClosestExistingParent(Session session, String path) throws RepositoryException {
-               int idx = path.lastIndexOf('/');
-               if (idx == 0)
-                       return session.getRootNode();
-               String parentPath = path.substring(0, idx);
-               if (session.itemExists(parentPath))
-                       return session.getNode(parentPath);
-               else
-                       return findClosestExistingParent(session, parentPath);
-       }
-
-       /** Convert a path to the list of its tokens */
-       public static List<String> tokenize(String path) {
-               List<String> tokens = new ArrayList<String>();
-               boolean optimized = false;
-               if (!optimized) {
-                       String[] rawTokens = path.split("/");
-                       for (String token : rawTokens) {
-                               if (!token.equals(""))
-                                       tokens.add(token);
-                       }
-               } else {
-                       StringBuffer curr = new StringBuffer();
-                       char[] arr = path.toCharArray();
-                       chars: for (int i = 0; i < arr.length; i++) {
-                               char c = arr[i];
-                               if (c == '/') {
-                                       if (i == 0 || (i == arr.length - 1))
-                                               continue chars;
-                                       if (curr.length() > 0) {
-                                               tokens.add(curr.toString());
-                                               curr = new StringBuffer();
-                                       }
-                               } else
-                                       curr.append(c);
-                       }
-                       if (curr.length() > 0) {
-                               tokens.add(curr.toString());
-                               curr = new StringBuffer();
-                       }
-               }
-               return Collections.unmodifiableList(tokens);
-       }
-
-       // /**
-       // * use {@link #mkdirs(Session, String, String, String, Boolean)} instead.
-       // *
-       // * @deprecated
-       // */
-       // @Deprecated
-       // public static Node mkdirs(Session session, String path, String type,
-       // Boolean versioning) {
-       // return mkdirs(session, path, type, type, false);
-       // }
-
-       /**
-        * Safe and repository implementation independent registration of a namespace.
-        */
-       public static void registerNamespaceSafely(Session session, String prefix, String uri) {
-               try {
-                       registerNamespaceSafely(session.getWorkspace().getNamespaceRegistry(), prefix, uri);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot find namespace registry", e);
-               }
-       }
-
-       /**
-        * Safe and repository implementation independent registration of a namespace.
-        */
-       public static void registerNamespaceSafely(NamespaceRegistry nr, String prefix, String uri) {
-               try {
-                       String[] prefixes = nr.getPrefixes();
-                       for (String pref : prefixes)
-                               if (pref.equals(prefix)) {
-                                       String registeredUri = nr.getURI(pref);
-                                       if (!registeredUri.equals(uri))
-                                               throw new IllegalArgumentException("Prefix " + pref + " already registered for URI "
-                                                               + registeredUri + " which is different from provided URI " + uri);
-                                       else
-                                               return;// skip
-                               }
-                       nr.registerNamespace(prefix, uri);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot register namespace " + uri + " under prefix " + prefix, e);
-               }
-       }
-
-//     /** Recursively outputs the contents of the given node. */
-//     public static void debug(Node node) {
-//             debug(node, log);
-//     }
-//
-//     /** Recursively outputs the contents of the given node. */
-//     public static void debug(Node node, Log log) {
-//             try {
-//                     // First output the node path
-//                     log.debug(node.getPath());
-//                     // Skip the virtual (and large!) jcr:system subtree
-//                     if (node.getName().equals("jcr:system")) {
-//                             return;
-//                     }
-//
-//                     // Then the children nodes (recursive)
-//                     NodeIterator it = node.getNodes();
-//                     while (it.hasNext()) {
-//                             Node childNode = it.nextNode();
-//                             debug(childNode, log);
-//                     }
-//
-//                     // Then output the properties
-//                     PropertyIterator properties = node.getProperties();
-//                     // log.debug("Property are : ");
-//
-//                     properties: while (properties.hasNext()) {
-//                             Property property = properties.nextProperty();
-//                             if (property.getType() == PropertyType.BINARY)
-//                                     continue properties;// skip
-//                             if (property.getDefinition().isMultiple()) {
-//                                     // A multi-valued property, print all values
-//                                     Value[] values = property.getValues();
-//                                     for (int i = 0; i < values.length; i++) {
-//                                             log.debug(property.getPath() + "=" + values[i].getString());
-//                                     }
-//                             } else {
-//                                     // A single-valued property
-//                                     log.debug(property.getPath() + "=" + property.getString());
-//                             }
-//                     }
-//             } catch (Exception e) {
-//                     log.error("Could not debug " + node, e);
-//             }
-//
-//     }
-
-//     /** Logs the effective access control policies */
-//     public static void logEffectiveAccessPolicies(Node node) {
-//             try {
-//                     logEffectiveAccessPolicies(node.getSession(), node.getPath());
-//             } catch (RepositoryException e) {
-//                     log.error("Cannot log effective access policies of " + node, e);
-//             }
-//     }
-//
-//     /** Logs the effective access control policies */
-//     public static void logEffectiveAccessPolicies(Session session, String path) {
-//             if (!log.isDebugEnabled())
-//                     return;
-//
-//             try {
-//                     AccessControlPolicy[] effectivePolicies = session.getAccessControlManager().getEffectivePolicies(path);
-//                     if (effectivePolicies.length > 0) {
-//                             for (AccessControlPolicy policy : effectivePolicies) {
-//                                     if (policy instanceof AccessControlList) {
-//                                             AccessControlList acl = (AccessControlList) policy;
-//                                             log.debug("Access control list for " + path + "\n" + accessControlListSummary(acl));
-//                                     }
-//                             }
-//                     } else {
-//                             log.debug("No effective access control policy for " + path);
-//                     }
-//             } catch (RepositoryException e) {
-//                     log.error("Cannot log effective access policies of " + path, e);
-//             }
-//     }
-
-       /** Returns a human-readable summary of this access control list. */
-       public static String accessControlListSummary(AccessControlList acl) {
-               StringBuffer buf = new StringBuffer("");
-               try {
-                       for (AccessControlEntry ace : acl.getAccessControlEntries()) {
-                               buf.append('\t').append(ace.getPrincipal().getName()).append('\n');
-                               for (Privilege priv : ace.getPrivileges())
-                                       buf.append("\t\t").append(priv.getName()).append('\n');
-                       }
-                       return buf.toString();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot write summary of " + acl, e);
-               }
-       }
-
-       /** Copy the whole workspace via a system view XML. */
-       public static void copyWorkspaceXml(Session fromSession, Session toSession) {
-               Workspace fromWorkspace = fromSession.getWorkspace();
-               Workspace toWorkspace = toSession.getWorkspace();
-               String errorMsg = "Cannot copy workspace " + fromWorkspace + " to " + toWorkspace + " via XML.";
-
-               try (PipedInputStream in = new PipedInputStream(1024 * 1024);) {
-                       new Thread(() -> {
-                               try (PipedOutputStream out = new PipedOutputStream(in)) {
-                                       fromSession.exportSystemView("/", out, false, false);
-                                       out.flush();
-                               } catch (IOException e) {
-                                       throw new RuntimeException(errorMsg, e);
-                               } catch (RepositoryException e) {
-                                       throw new JcrException(errorMsg, e);
-                               }
-                       }, "Copy workspace" + fromWorkspace + " to " + toWorkspace).start();
-
-                       toSession.importXML("/", in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
-                       toSession.save();
-               } catch (IOException e) {
-                       throw new RuntimeException(errorMsg, e);
-               } catch (RepositoryException e) {
-                       throw new JcrException(errorMsg, e);
-               }
-       }
-
-       /**
-        * Copies recursively the content of a node to another one. Do NOT copy the
-        * property values of {@link NodeType#MIX_CREATED} and
-        * {@link NodeType#MIX_LAST_MODIFIED}, but update the
-        * {@link Property#JCR_LAST_MODIFIED} and {@link Property#JCR_LAST_MODIFIED_BY}
-        * properties if the target node has the {@link NodeType#MIX_LAST_MODIFIED}
-        * mixin.
-        */
-       public static void copy(Node fromNode, Node toNode) {
-               try {
-                       if (toNode.getDefinition().isProtected())
-                               return;
-
-                       // add mixins
-                       for (NodeType mixinType : fromNode.getMixinNodeTypes()) {
-                               try {
-                                       toNode.addMixin(mixinType.getName());
-                               } catch (NoSuchNodeTypeException e) {
-                                       // ignore unknown mixins
-                                       // TODO log it
-                               }
-                       }
-
-                       // process properties
-                       PropertyIterator pit = fromNode.getProperties();
-                       properties: while (pit.hasNext()) {
-                               Property fromProperty = pit.nextProperty();
-                               String propertyName = fromProperty.getName();
-                               if (toNode.hasProperty(propertyName) && toNode.getProperty(propertyName).getDefinition().isProtected())
-                                       continue properties;
-
-                               if (fromProperty.getDefinition().isProtected())
-                                       continue properties;
-
-                               if (propertyName.equals("jcr:created") || propertyName.equals("jcr:createdBy")
-                                               || propertyName.equals("jcr:lastModified") || propertyName.equals("jcr:lastModifiedBy"))
-                                       continue properties;
-
-                               if (fromProperty.isMultiple()) {
-                                       toNode.setProperty(propertyName, fromProperty.getValues());
-                               } else {
-                                       toNode.setProperty(propertyName, fromProperty.getValue());
-                               }
-                       }
-
-                       // update jcr:lastModified and jcr:lastModifiedBy in toNode in case
-                       // they existed, before adding the mixins
-                       updateLastModified(toNode, true);
-
-                       // process children nodes
-                       NodeIterator nit = fromNode.getNodes();
-                       while (nit.hasNext()) {
-                               Node fromChild = nit.nextNode();
-                               Integer index = fromChild.getIndex();
-                               String nodeRelPath = fromChild.getName() + "[" + index + "]";
-                               Node toChild;
-                               if (toNode.hasNode(nodeRelPath))
-                                       toChild = toNode.getNode(nodeRelPath);
-                               else {
-                                       try {
-                                               toChild = toNode.addNode(fromChild.getName(), fromChild.getPrimaryNodeType().getName());
-                                       } catch (NoSuchNodeTypeException e) {
-                                               // ignore unknown primary types
-                                               // TODO log it
-                                               return;
-                                       }
-                               }
-                               copy(fromChild, toChild);
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot copy " + fromNode + " to " + toNode, e);
-               }
-       }
-
-       /**
-        * Check whether all first-level properties (except jcr:* properties) are equal.
-        * Skip jcr:* properties
-        */
-       public static Boolean allPropertiesEquals(Node reference, Node observed, Boolean onlyCommonProperties) {
-               try {
-                       PropertyIterator pit = reference.getProperties();
-                       props: while (pit.hasNext()) {
-                               Property propReference = pit.nextProperty();
-                               String propName = propReference.getName();
-                               if (propName.startsWith("jcr:"))
-                                       continue props;
-
-                               if (!observed.hasProperty(propName))
-                                       if (onlyCommonProperties)
-                                               continue props;
-                                       else
-                                               return false;
-                               // TODO: deal with multiple property values?
-                               if (!observed.getProperty(propName).getValue().equals(propReference.getValue()))
-                                       return false;
-                       }
-                       return true;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot check all properties equals of " + reference + " and " + observed, e);
-               }
-       }
-
-       public static Map<String, PropertyDiff> diffProperties(Node reference, Node observed) {
-               Map<String, PropertyDiff> diffs = new TreeMap<String, PropertyDiff>();
-               diffPropertiesLevel(diffs, null, reference, observed);
-               return diffs;
-       }
-
-       /**
-        * Compare the properties of two nodes. Recursivity to child nodes is not yet
-        * supported. Skip jcr:* properties.
-        */
-       static void diffPropertiesLevel(Map<String, PropertyDiff> diffs, String baseRelPath, Node reference,
-                       Node observed) {
-               try {
-                       // check removed and modified
-                       PropertyIterator pit = reference.getProperties();
-                       props: while (pit.hasNext()) {
-                               Property p = pit.nextProperty();
-                               String name = p.getName();
-                               if (name.startsWith("jcr:"))
-                                       continue props;
-
-                               if (!observed.hasProperty(name)) {
-                                       String relPath = propertyRelPath(baseRelPath, name);
-                                       PropertyDiff pDiff = new PropertyDiff(PropertyDiff.REMOVED, relPath, p.getValue(), null);
-                                       diffs.put(relPath, pDiff);
-                               } else {
-                                       if (p.isMultiple()) {
-                                               // FIXME implement multiple
-                                       } else {
-                                               Value referenceValue = p.getValue();
-                                               Value newValue = observed.getProperty(name).getValue();
-                                               if (!referenceValue.equals(newValue)) {
-                                                       String relPath = propertyRelPath(baseRelPath, name);
-                                                       PropertyDiff pDiff = new PropertyDiff(PropertyDiff.MODIFIED, relPath, referenceValue,
-                                                                       newValue);
-                                                       diffs.put(relPath, pDiff);
-                                               }
-                                       }
-                               }
-                       }
-                       // check added
-                       pit = observed.getProperties();
-                       props: while (pit.hasNext()) {
-                               Property p = pit.nextProperty();
-                               String name = p.getName();
-                               if (name.startsWith("jcr:"))
-                                       continue props;
-                               if (!reference.hasProperty(name)) {
-                                       if (p.isMultiple()) {
-                                               // FIXME implement multiple
-                                       } else {
-                                               String relPath = propertyRelPath(baseRelPath, name);
-                                               PropertyDiff pDiff = new PropertyDiff(PropertyDiff.ADDED, relPath, null, p.getValue());
-                                               diffs.put(relPath, pDiff);
-                                       }
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot diff " + reference + " and " + observed, e);
-               }
-       }
-
-       /**
-        * Compare only a restricted list of properties of two nodes. No recursivity.
-        * 
-        */
-       public static Map<String, PropertyDiff> diffProperties(Node reference, Node observed, List<String> properties) {
-               Map<String, PropertyDiff> diffs = new TreeMap<String, PropertyDiff>();
-               try {
-                       Iterator<String> pit = properties.iterator();
-
-                       props: while (pit.hasNext()) {
-                               String name = pit.next();
-                               if (!reference.hasProperty(name)) {
-                                       if (!observed.hasProperty(name))
-                                               continue props;
-                                       Value val = observed.getProperty(name).getValue();
-                                       try {
-                                               // empty String but not null
-                                               if ("".equals(val.getString()))
-                                                       continue props;
-                                       } catch (Exception e) {
-                                               // not parseable as String, silent
-                                       }
-                                       PropertyDiff pDiff = new PropertyDiff(PropertyDiff.ADDED, name, null, val);
-                                       diffs.put(name, pDiff);
-                               } else if (!observed.hasProperty(name)) {
-                                       PropertyDiff pDiff = new PropertyDiff(PropertyDiff.REMOVED, name,
-                                                       reference.getProperty(name).getValue(), null);
-                                       diffs.put(name, pDiff);
-                               } else {
-                                       Value referenceValue = reference.getProperty(name).getValue();
-                                       Value newValue = observed.getProperty(name).getValue();
-                                       if (!referenceValue.equals(newValue)) {
-                                               PropertyDiff pDiff = new PropertyDiff(PropertyDiff.MODIFIED, name, referenceValue, newValue);
-                                               diffs.put(name, pDiff);
-                                       }
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot diff " + reference + " and " + observed, e);
-               }
-               return diffs;
-       }
-
-       /** Builds a property relPath to be used in the diff. */
-       private static String propertyRelPath(String baseRelPath, String propertyName) {
-               if (baseRelPath == null)
-                       return propertyName;
-               else
-                       return baseRelPath + '/' + propertyName;
-       }
-
-       /**
-        * Normalizes a name so that it can be stored in contexts not supporting names
-        * with ':' (typically databases). Replaces ':' by '_'.
-        */
-       public static String normalize(String name) {
-               return name.replace(':', '_');
-       }
-
-       /**
-        * Replaces characters which are invalid in a JCR name by '_'. Currently not
-        * exhaustive.
-        * 
-        * @see JcrUtils#INVALID_NAME_CHARACTERS
-        */
-       public static String replaceInvalidChars(String name) {
-               return replaceInvalidChars(name, '_');
-       }
-
-       /**
-        * Replaces characters which are invalid in a JCR name. Currently not
-        * exhaustive.
-        * 
-        * @see JcrUtils#INVALID_NAME_CHARACTERS
-        */
-       public static String replaceInvalidChars(String name, char replacement) {
-               boolean modified = false;
-               char[] arr = name.toCharArray();
-               for (int i = 0; i < arr.length; i++) {
-                       char c = arr[i];
-                       invalid: for (char invalid : INVALID_NAME_CHARACTERS) {
-                               if (c == invalid) {
-                                       arr[i] = replacement;
-                                       modified = true;
-                                       break invalid;
-                               }
-                       }
-               }
-               if (modified)
-                       return new String(arr);
-               else
-                       // do not create new object if unnecessary
-                       return name;
-       }
-
-       // /**
-       // * Removes forbidden characters from a path, replacing them with '_'
-       // *
-       // * @deprecated use {@link #replaceInvalidChars(String)} instead
-       // */
-       // public static String removeForbiddenCharacters(String str) {
-       // return str.replace('[', '_').replace(']', '_').replace('/', '_').replace('*',
-       // '_');
-       //
-       // }
-
-       /** Cleanly disposes a {@link Binary} even if it is null. */
-       public static void closeQuietly(Binary binary) {
-               if (binary == null)
-                       return;
-               binary.dispose();
-       }
-
-       /** Retrieve a {@link Binary} as a byte array */
-       public static byte[] getBinaryAsBytes(Property property) {
-               try (ByteArrayOutputStream out = new ByteArrayOutputStream();
-                               Bin binary = new Bin(property);
-                               InputStream in = binary.getStream()) {
-                       IOUtils.copy(in, out);
-                       return out.toByteArray();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot read binary " + property + " as bytes", e);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot read binary " + property + " as bytes", e);
-               }
-       }
-
-       /** Writes a {@link Binary} from a byte array */
-       public static void setBinaryAsBytes(Node node, String property, byte[] bytes) {
-               Binary binary = null;
-               try (InputStream in = new ByteArrayInputStream(bytes)) {
-                       binary = node.getSession().getValueFactory().createBinary(in);
-                       node.setProperty(property, binary);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set binary " + property + " as bytes", e);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot set binary " + property + " as bytes", e);
-               } finally {
-                       closeQuietly(binary);
-               }
-       }
-
-       /** Writes a {@link Binary} from a byte array */
-       public static void setBinaryAsBytes(Property prop, byte[] bytes) {
-               Binary binary = null;
-               try (InputStream in = new ByteArrayInputStream(bytes)) {
-                       binary = prop.getSession().getValueFactory().createBinary(in);
-                       prop.setValue(binary);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set binary " + prop + " as bytes", e);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot set binary " + prop + " as bytes", e);
-               } finally {
-                       closeQuietly(binary);
-               }
-       }
-
-       /**
-        * Creates depth from a string (typically a username) by adding levels based on
-        * its first characters: "aBcD",2 becomes a/aB
-        */
-       public static String firstCharsToPath(String str, Integer nbrOfChars) {
-               if (str.length() < nbrOfChars)
-                       throw new IllegalArgumentException("String " + str + " length must be greater or equal than " + nbrOfChars);
-               StringBuffer path = new StringBuffer("");
-               StringBuffer curr = new StringBuffer("");
-               for (int i = 0; i < nbrOfChars; i++) {
-                       curr.append(str.charAt(i));
-                       path.append(curr);
-                       if (i < nbrOfChars - 1)
-                               path.append('/');
-               }
-               return path.toString();
-       }
-
-       /**
-        * Discards the current changes in the session attached to this node. To be used
-        * typically in a catch block.
-        * 
-        * @see #discardQuietly(Session)
-        */
-       public static void discardUnderlyingSessionQuietly(Node node) {
-               try {
-                       discardQuietly(node.getSession());
-               } catch (RepositoryException e) {
-                       // silent
-               }
-       }
-
-       /**
-        * Discards the current changes in a session by calling
-        * {@link Session#refresh(boolean)} with <code>false</code>, only logging
-        * potential errors when doing so. To be used typically in a catch block.
-        */
-       public static void discardQuietly(Session session) {
-               try {
-                       if (session != null)
-                               session.refresh(false);
-               } catch (RepositoryException e) {
-                       // silent
-               }
-       }
-
-       /**
-        * Login to a workspace with implicit credentials, creates the workspace with
-        * these credentials if it does not already exist.
-        */
-       public static Session loginOrCreateWorkspace(Repository repository, String workspaceName)
-                       throws RepositoryException {
-               return loginOrCreateWorkspace(repository, workspaceName, null);
-       }
-
-       /**
-        * Login to a workspace with implicit credentials, creates the workspace with
-        * these credentials if it does not already exist.
-        */
-       public static Session loginOrCreateWorkspace(Repository repository, String workspaceName, Credentials credentials)
-                       throws RepositoryException {
-               Session workspaceSession = null;
-               Session defaultSession = null;
-               try {
-                       try {
-                               workspaceSession = repository.login(credentials, workspaceName);
-                       } catch (NoSuchWorkspaceException e) {
-                               // try to create workspace
-                               defaultSession = repository.login(credentials);
-                               defaultSession.getWorkspace().createWorkspace(workspaceName);
-
-                               // work around non-atomicity of workspace creation in Jackrabbit
-//                             try {
-//                                     Thread.sleep(5000);
-//                             } catch (InterruptedException e1) {
-//                                     // ignore
-//                             }
-                               
-                               workspaceSession = repository.login(credentials, workspaceName);
-                       }
-                       return workspaceSession;
-               } finally {
-                       logoutQuietly(defaultSession);
-               }
-       }
-
-       /**
-        * Logs out the session, not throwing any exception, even if it is null.
-        * {@link Jcr#logout(Session)} should rather be used.
-        */
-       public static void logoutQuietly(Session session) {
-               Jcr.logout(session);
-//             try {
-//                     if (session != null)
-//                             if (session.isLive())
-//                                     session.logout();
-//             } catch (Exception e) {
-//                     // silent
-//             }
-       }
-
-       /**
-        * Convenient method to add a listener. uuids passed as null, deep=true,
-        * local=true, only one node type
-        */
-       public static void addListener(Session session, EventListener listener, int eventTypes, String basePath,
-                       String nodeType) {
-               try {
-                       session.getWorkspace().getObservationManager().addEventListener(listener, eventTypes, basePath, true, null,
-                                       nodeType == null ? null : new String[] { nodeType }, true);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot add JCR listener " + listener + " to session " + session, e);
-               }
-       }
-
-       /** Removes a listener without throwing exception */
-       public static void removeListenerQuietly(Session session, EventListener listener) {
-               if (session == null || !session.isLive())
-                       return;
-               try {
-                       session.getWorkspace().getObservationManager().removeEventListener(listener);
-               } catch (RepositoryException e) {
-                       // silent
-               }
-       }
-
-       /**
-        * Quietly unregisters an {@link EventListener} from the udnerlying workspace of
-        * this node.
-        */
-       public static void unregisterQuietly(Node node, EventListener eventListener) {
-               try {
-                       unregisterQuietly(node.getSession().getWorkspace(), eventListener);
-               } catch (RepositoryException e) {
-                       // silent
-               }
-       }
-
-       /** Quietly unregisters an {@link EventListener} from this workspace */
-       public static void unregisterQuietly(Workspace workspace, EventListener eventListener) {
-               if (eventListener == null)
-                       return;
-               try {
-                       workspace.getObservationManager().removeEventListener(eventListener);
-               } catch (RepositoryException e) {
-                       // silent
-               }
-       }
-
-       /**
-        * Checks whether {@link Property#JCR_LAST_MODIFIED} or (afterwards)
-        * {@link Property#JCR_CREATED} are set and returns it as an {@link Instant}.
-        */
-       public static Instant getModified(Node node) {
-               Calendar calendar = null;
-               try {
-                       if (node.hasProperty(Property.JCR_LAST_MODIFIED))
-                               calendar = node.getProperty(Property.JCR_LAST_MODIFIED).getDate();
-                       else if (node.hasProperty(Property.JCR_CREATED))
-                               calendar = node.getProperty(Property.JCR_CREATED).getDate();
-                       else
-                               throw new IllegalArgumentException("No modification time found in " + node);
-                       return calendar.toInstant();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get modification time for " + node, e);
-               }
-
-       }
-
-       /**
-        * Get {@link Property#JCR_CREATED} as an {@link Instant}, if it is set.
-        */
-       public static Instant getCreated(Node node) {
-               Calendar calendar = null;
-               try {
-                       if (node.hasProperty(Property.JCR_CREATED))
-                               calendar = node.getProperty(Property.JCR_CREATED).getDate();
-                       else
-                               throw new IllegalArgumentException("No created time found in " + node);
-                       return calendar.toInstant();
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get created time for " + node, e);
-               }
-
-       }
-
-       /**
-        * Updates the {@link Property#JCR_LAST_MODIFIED} property with the current time
-        * and the {@link Property#JCR_LAST_MODIFIED_BY} property with the underlying
-        * session user id.
-        */
-       public static void updateLastModified(Node node) {
-               updateLastModified(node, false);
-       }
-
-       /**
-        * Updates the {@link Property#JCR_LAST_MODIFIED} property with the current time
-        * and the {@link Property#JCR_LAST_MODIFIED_BY} property with the underlying
-        * session user id. In Jackrabbit 2.x,
-        * <a href="https://issues.apache.org/jira/browse/JCR-2233">these properties are
-        * not automatically updated</a>, hence the need for manual update. The session
-        * is not saved.
-        */
-       public static void updateLastModified(Node node, boolean addMixin) {
-               try {
-                       if (addMixin && !node.isNodeType(NodeType.MIX_LAST_MODIFIED))
-                               node.addMixin(NodeType.MIX_LAST_MODIFIED);
-                       node.setProperty(Property.JCR_LAST_MODIFIED, new GregorianCalendar());
-                       node.setProperty(Property.JCR_LAST_MODIFIED_BY, node.getSession().getUserID());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot update last modified on " + node, e);
-               }
-       }
-
-       /**
-        * Update lastModified recursively until this parent.
-        * 
-        * @param node      the node
-        * @param untilPath the base path, null is equivalent to "/"
-        */
-       public static void updateLastModifiedAndParents(Node node, String untilPath) {
-               updateLastModifiedAndParents(node, untilPath, true);
-       }
-
-       /**
-        * Update lastModified recursively until this parent.
-        * 
-        * @param node      the node
-        * @param untilPath the base path, null is equivalent to "/"
-        */
-       public static void updateLastModifiedAndParents(Node node, String untilPath, boolean addMixin) {
-               try {
-                       if (untilPath != null && !node.getPath().startsWith(untilPath))
-                               throw new IllegalArgumentException(node + " is not under " + untilPath);
-                       updateLastModified(node, addMixin);
-                       if (untilPath == null) {
-                               if (!node.getPath().equals("/"))
-                                       updateLastModifiedAndParents(node.getParent(), untilPath, addMixin);
-                       } else {
-                               if (!node.getPath().equals(untilPath))
-                                       updateLastModifiedAndParents(node.getParent(), untilPath, addMixin);
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot update lastModified from " + node + " until " + untilPath, e);
-               }
-       }
-
-       /**
-        * Returns a String representing the short version (see
-        * <a href="http://jackrabbit.apache.org/node-type-notation.html"> Node type
-        * Notation </a> attributes grammar) of the main business attributes of this
-        * property definition
-        * 
-        * @param prop
-        */
-       public static String getPropertyDefinitionAsString(Property prop) {
-               StringBuffer sbuf = new StringBuffer();
-               try {
-                       if (prop.getDefinition().isAutoCreated())
-                               sbuf.append("a");
-                       if (prop.getDefinition().isMandatory())
-                               sbuf.append("m");
-                       if (prop.getDefinition().isProtected())
-                               sbuf.append("p");
-                       if (prop.getDefinition().isMultiple())
-                               sbuf.append("*");
-               } catch (RepositoryException re) {
-                       throw new JcrException("unexpected error while getting property definition as String", re);
-               }
-               return sbuf.toString();
-       }
-
-       /**
-        * Estimate the sub tree size from current node. Computation is based on the Jcr
-        * {@link Property#getLength()} method. Note : it is not the exact size used on
-        * the disk by the current part of the JCR Tree.
-        */
-
-       public static long getNodeApproxSize(Node node) {
-               long curNodeSize = 0;
-               try {
-                       PropertyIterator pi = node.getProperties();
-                       while (pi.hasNext()) {
-                               Property prop = pi.nextProperty();
-                               if (prop.isMultiple()) {
-                                       int nb = prop.getLengths().length;
-                                       for (int i = 0; i < nb; i++) {
-                                               curNodeSize += (prop.getLengths()[i] > 0 ? prop.getLengths()[i] : 0);
-                                       }
-                               } else
-                                       curNodeSize += (prop.getLength() > 0 ? prop.getLength() : 0);
-                       }
-
-                       NodeIterator ni = node.getNodes();
-                       while (ni.hasNext())
-                               curNodeSize += getNodeApproxSize(ni.nextNode());
-                       return curNodeSize;
-               } catch (RepositoryException re) {
-                       throw new JcrException("Unexpected error while recursively determining node size.", re);
-               }
-       }
-
-       /*
-        * SECURITY
-        */
-
-       /**
-        * Convenience method for adding a single privilege to a principal (user or
-        * role), typically jcr:all
-        */
-       public synchronized static void addPrivilege(Session session, String path, String principal, String privilege)
-                       throws RepositoryException {
-               List<Privilege> privileges = new ArrayList<Privilege>();
-               privileges.add(session.getAccessControlManager().privilegeFromName(privilege));
-               addPrivileges(session, path, new SimplePrincipal(principal), privileges);
-       }
-
-       /**
-        * Add privileges on a path to a {@link Principal}. The path must already exist.
-        * Session is saved. Synchronized to prevent concurrent modifications of the
-        * same node.
-        */
-       public synchronized static Boolean addPrivileges(Session session, String path, Principal principal,
-                       List<Privilege> privs) throws RepositoryException {
-               // make sure the session is in line with the persisted state
-               session.refresh(false);
-               AccessControlManager acm = session.getAccessControlManager();
-               AccessControlList acl = getAccessControlList(acm, path);
-
-               accessControlEntries: for (AccessControlEntry ace : acl.getAccessControlEntries()) {
-                       Principal currentPrincipal = ace.getPrincipal();
-                       if (currentPrincipal.getName().equals(principal.getName())) {
-                               Privilege[] currentPrivileges = ace.getPrivileges();
-                               if (currentPrivileges.length != privs.size())
-                                       break accessControlEntries;
-                               for (int i = 0; i < currentPrivileges.length; i++) {
-                                       Privilege currP = currentPrivileges[i];
-                                       Privilege p = privs.get(i);
-                                       if (!currP.getName().equals(p.getName())) {
-                                               break accessControlEntries;
-                                       }
-                               }
-                               return false;
-                       }
-               }
-
-               Privilege[] privileges = privs.toArray(new Privilege[privs.size()]);
-               acl.addAccessControlEntry(principal, privileges);
-               acm.setPolicy(path, acl);
-//             if (log.isDebugEnabled()) {
-//                     StringBuffer privBuf = new StringBuffer();
-//                     for (Privilege priv : privs)
-//                             privBuf.append(priv.getName());
-//                     log.debug("Added privileges " + privBuf + " to " + principal.getName() + " on " + path + " in '"
-//                                     + session.getWorkspace().getName() + "'");
-//             }
-               session.refresh(true);
-               session.save();
-               return true;
-       }
-
-       /**
-        * Gets the first available access control list for this path, throws exception
-        * if not found
-        */
-       public synchronized static AccessControlList getAccessControlList(AccessControlManager acm, String path)
-                       throws RepositoryException {
-               // search for an access control list
-               AccessControlList acl = null;
-               AccessControlPolicyIterator policyIterator = acm.getApplicablePolicies(path);
-               applicablePolicies: if (policyIterator.hasNext()) {
-                       while (policyIterator.hasNext()) {
-                               AccessControlPolicy acp = policyIterator.nextAccessControlPolicy();
-                               if (acp instanceof AccessControlList) {
-                                       acl = ((AccessControlList) acp);
-                                       break applicablePolicies;
-                               }
-                       }
-               } else {
-                       AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
-                       existingPolicies: for (AccessControlPolicy acp : existingPolicies) {
-                               if (acp instanceof AccessControlList) {
-                                       acl = ((AccessControlList) acp);
-                                       break existingPolicies;
-                               }
-                       }
-               }
-               if (acl != null)
-                       return acl;
-               else
-                       throw new IllegalArgumentException("ACL not found at " + path);
-       }
-
-       /** Clear authorizations for a user at this path */
-       public synchronized static void clearAccessControList(Session session, String path, String username)
-                       throws RepositoryException {
-               AccessControlManager acm = session.getAccessControlManager();
-               AccessControlList acl = getAccessControlList(acm, path);
-               for (AccessControlEntry ace : acl.getAccessControlEntries()) {
-                       if (ace.getPrincipal().getName().equals(username)) {
-                               acl.removeAccessControlEntry(ace);
-                       }
-               }
-               // the new access control list must be applied otherwise this call:
-               // acl.removeAccessControlEntry(ace); has no effect
-               acm.setPolicy(path, acl);
-               session.refresh(true);
-               session.save();
-       }
-
-       /*
-        * FILES UTILITIES
-        */
-       /**
-        * Creates the nodes making the path as {@link NodeType#NT_FOLDER}
-        */
-       public static Node mkfolders(Session session, String path) {
-               return mkdirs(session, path, NodeType.NT_FOLDER, NodeType.NT_FOLDER, false);
-       }
-
-       /**
-        * Copy only nt:folder and nt:file, without their additional types and
-        * properties.
-        * 
-        * @param recursive if true copies folders as well, otherwise only first level
-        *                  files
-        * @return how many files were copied
-        */
-       public static Long copyFiles(Node fromNode, Node toNode, Boolean recursive, JcrMonitor monitor, boolean onlyAdd) {
-               long count = 0l;
-
-               // Binary binary = null;
-               // InputStream in = null;
-               try {
-                       NodeIterator fromChildren = fromNode.getNodes();
-                       children: while (fromChildren.hasNext()) {
-                               if (monitor != null && monitor.isCanceled())
-                                       throw new IllegalStateException("Copy cancelled before it was completed");
-
-                               Node fromChild = fromChildren.nextNode();
-                               String fileName = fromChild.getName();
-                               if (fromChild.isNodeType(NodeType.NT_FILE)) {
-                                       if (onlyAdd && toNode.hasNode(fileName)) {
-                                               monitor.subTask("Skip existing " + fileName);
-                                               continue children;
-                                       }
-
-                                       if (monitor != null)
-                                               monitor.subTask("Copy " + fileName);
-                                       try (Bin binary = new Bin(fromChild.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA));
-                                                       InputStream in = binary.getStream();) {
-                                               copyStreamAsFile(toNode, fileName, in);
-                                       } catch (IOException e) {
-                                               throw new RuntimeException("Cannot copy " + fileName + " to " + toNode, e);
-                                       }
-
-                                       // save session
-                                       toNode.getSession().save();
-                                       count++;
-
-//                                     if (log.isDebugEnabled())
-//                                             log.debug("Copied file " + fromChild.getPath());
-                                       if (monitor != null)
-                                               monitor.worked(1);
-                               } else if (fromChild.isNodeType(NodeType.NT_FOLDER) && recursive) {
-                                       Node toChildFolder;
-                                       if (toNode.hasNode(fileName)) {
-                                               toChildFolder = toNode.getNode(fileName);
-                                               if (!toChildFolder.isNodeType(NodeType.NT_FOLDER))
-                                                       throw new IllegalArgumentException(toChildFolder + " is not of type nt:folder");
-                                       } else {
-                                               toChildFolder = toNode.addNode(fileName, NodeType.NT_FOLDER);
-
-                                               // save session
-                                               toNode.getSession().save();
-                                       }
-                                       count = count + copyFiles(fromChild, toChildFolder, recursive, monitor, onlyAdd);
-                               }
-                       }
-                       return count;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot copy files between " + fromNode + " and " + toNode, e);
-               } finally {
-                       // in case there was an exception
-                       // IOUtils.closeQuietly(in);
-                       // closeQuietly(binary);
-               }
-       }
-
-       /**
-        * Iteratively count all file nodes in subtree, inefficient but can be useful
-        * when query are poorly supported, such as in remoting.
-        */
-       public static Long countFiles(Node node) {
-               Long localCount = 0l;
-               try {
-                       for (NodeIterator nit = node.getNodes(); nit.hasNext();) {
-                               Node child = nit.nextNode();
-                               if (child.isNodeType(NodeType.NT_FOLDER))
-                                       localCount = localCount + countFiles(child);
-                               else if (child.isNodeType(NodeType.NT_FILE))
-                                       localCount = localCount + 1;
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot count all children of " + node, e);
-               }
-               return localCount;
-       }
-
-       /**
-        * Copy a file as an nt:file, assuming an nt:folder hierarchy. The session is
-        * NOT saved.
-        * 
-        * @return the created file node
-        */
-       @Deprecated
-       public static Node copyFile(Node folderNode, File file) {
-               try (InputStream in = new FileInputStream(file)) {
-                       return copyStreamAsFile(folderNode, file.getName(), in);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot copy file " + file + " under " + folderNode, e);
-               }
-       }
-
-       /** Copy bytes as an nt:file */
-       public static Node copyBytesAsFile(Node folderNode, String fileName, byte[] bytes) {
-               // InputStream in = null;
-               try (InputStream in = new ByteArrayInputStream(bytes)) {
-                       // in = new ByteArrayInputStream(bytes);
-                       return copyStreamAsFile(folderNode, fileName, in);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot copy file " + fileName + " under " + folderNode, e);
-                       // } finally {
-                       // IOUtils.closeQuietly(in);
-               }
-       }
-
-       /**
-        * Copy a stream as an nt:file, assuming an nt:folder hierarchy. The session is
-        * NOT saved.
-        * 
-        * @return the created file node
-        */
-       public static Node copyStreamAsFile(Node folderNode, String fileName, InputStream in) {
-               Binary binary = null;
-               try {
-                       Node fileNode;
-                       Node contentNode;
-                       if (folderNode.hasNode(fileName)) {
-                               fileNode = folderNode.getNode(fileName);
-                               if (!fileNode.isNodeType(NodeType.NT_FILE))
-                                       throw new IllegalArgumentException(fileNode + " is not of type nt:file");
-                               // we assume that the content node is already there
-                               contentNode = fileNode.getNode(Node.JCR_CONTENT);
-                       } else {
-                               fileNode = folderNode.addNode(fileName, NodeType.NT_FILE);
-                               contentNode = fileNode.addNode(Node.JCR_CONTENT, NodeType.NT_UNSTRUCTURED);
-                       }
-                       binary = contentNode.getSession().getValueFactory().createBinary(in);
-                       contentNode.setProperty(Property.JCR_DATA, binary);
-                       updateLastModified(contentNode);
-                       return fileNode;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot create file node " + fileName + " under " + folderNode, e);
-               } finally {
-                       closeQuietly(binary);
-               }
-       }
-
-       /** Read an an nt:file as an {@link InputStream}. */
-       public static InputStream getFileAsStream(Node fileNode) throws RepositoryException {
-               return fileNode.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary().getStream();
-       }
-
-       /**
-        * Set the properties of {@link NodeType#MIX_MIMETYPE} on the content of this
-        * file node.
-        */
-       public static void setFileMimeType(Node fileNode, String mimeType, String encoding) throws RepositoryException {
-               Node contentNode = fileNode.getNode(Node.JCR_CONTENT);
-               if (mimeType != null)
-                       contentNode.setProperty(Property.JCR_MIMETYPE, mimeType);
-               if (encoding != null)
-                       contentNode.setProperty(Property.JCR_ENCODING, encoding);
-               // TODO remove properties if args are null?
-       }
-
-       public static void copyFilesToFs(Node baseNode, Path targetDir, boolean recursive) {
-               try {
-                       Files.createDirectories(targetDir);
-                       for (NodeIterator nit = baseNode.getNodes(); nit.hasNext();) {
-                               Node node = nit.nextNode();
-                               if (node.isNodeType(NodeType.NT_FILE)) {
-                                       Path filePath = targetDir.resolve(node.getName());
-                                       try (OutputStream out = Files.newOutputStream(filePath); InputStream in = getFileAsStream(node)) {
-                                               IOUtils.copy(in, out);
-                                       }
-                               } else if (recursive && node.isNodeType(NodeType.NT_FOLDER)) {
-                                       Path dirPath = targetDir.resolve(node.getName());
-                                       copyFilesToFs(node, dirPath, true);
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot copy " + baseNode + " to " + targetDir, e);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot copy " + baseNode + " to " + targetDir, e);
-               }
-       }
-
-       /**
-        * Computes the checksum of an nt:file.
-        * 
-        * @deprecated use separate digest utilities
-        */
-       @Deprecated
-       public static String checksumFile(Node fileNode, String algorithm) {
-               try (InputStream in = fileNode.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary()
-                               .getStream()) {
-                       return digest(algorithm, in);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot checksum file " + fileNode + " with algorithm " + algorithm, e);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot checksum file " + fileNode + " with algorithm " + algorithm, e);
-               }
-       }
-
-       @Deprecated
-       private static String digest(String algorithm, InputStream in) {
-               final Integer byteBufferCapacity = 100 * 1024;// 100 KB
-               try {
-                       MessageDigest digest = MessageDigest.getInstance(algorithm);
-                       byte[] buffer = new byte[byteBufferCapacity];
-                       int read = 0;
-                       while ((read = in.read(buffer)) > 0) {
-                               digest.update(buffer, 0, read);
-                       }
-
-                       byte[] checksum = digest.digest();
-                       String res = encodeHexString(checksum);
-                       return res;
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot digest with algorithm " + algorithm, e);
-               } catch (NoSuchAlgorithmException e) {
-                       throw new IllegalArgumentException("Cannot digest with algorithm " + algorithm, e);
-               }
-       }
-
-       /**
-        * From
-        * http://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to
-        * -a-hex-string-in-java
-        */
-       @Deprecated
-       private static String encodeHexString(byte[] bytes) {
-               final char[] hexArray = "0123456789abcdef".toCharArray();
-               char[] hexChars = new char[bytes.length * 2];
-               for (int j = 0; j < bytes.length; j++) {
-                       int v = bytes[j] & 0xFF;
-                       hexChars[j * 2] = hexArray[v >>> 4];
-                       hexChars[j * 2 + 1] = hexArray[v & 0x0F];
-               }
-               return new String(hexChars);
-       }
-
-       /** Export a subtree as a compact XML without namespaces. */
-       public static void toSimpleXml(Node node, StringBuilder sb) throws RepositoryException {
-               sb.append('<');
-               String nodeName = node.getName();
-               int colIndex = nodeName.indexOf(':');
-               if (colIndex > 0) {
-                       nodeName = nodeName.substring(colIndex + 1);
-               }
-               sb.append(nodeName);
-               PropertyIterator pit = node.getProperties();
-               properties: while (pit.hasNext()) {
-                       Property p = pit.nextProperty();
-                       // skip multiple properties
-                       if (p.isMultiple())
-                               continue properties;
-                       String propertyName = p.getName();
-                       int pcolIndex = propertyName.indexOf(':');
-                       // skip properties with namespaces
-                       if (pcolIndex > 0)
-                               continue properties;
-                       // skip binaries
-                       if (p.getType() == PropertyType.BINARY) {
-                               continue properties;
-                               // TODO retrieve identifier?
-                       }
-                       sb.append(' ');
-                       sb.append(propertyName);
-                       sb.append('=');
-                       sb.append('\"').append(p.getString()).append('\"');
-               }
-
-               if (node.hasNodes()) {
-                       sb.append('>');
-                       NodeIterator children = node.getNodes();
-                       while (children.hasNext()) {
-                               toSimpleXml(children.nextNode(), sb);
-                       }
-                       sb.append("</");
-                       sb.append(nodeName);
-                       sb.append('>');
-               } else {
-                       sb.append("/>");
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxApi.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxApi.java
deleted file mode 100644 (file)
index 666b259..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-package org.argeo.jcr;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-/** Uilities around the JCR extensions. */
-public class JcrxApi {
-       public final static String MD5 = "MD5";
-       public final static String SHA1 = "SHA1";
-       public final static String SHA256 = "SHA-256";
-       public final static String SHA512 = "SHA-512";
-
-       public final static String EMPTY_MD5 = "d41d8cd98f00b204e9800998ecf8427e";
-       public final static String EMPTY_SHA1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
-       public final static String EMPTY_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
-       public final static String EMPTY_SHA512 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
-
-       public final static int LENGTH_MD5 = EMPTY_MD5.length();
-       public final static int LENGTH_SHA1 = EMPTY_SHA1.length();
-       public final static int LENGTH_SHA256 = EMPTY_SHA256.length();
-       public final static int LENGTH_SHA512 = EMPTY_SHA512.length();
-
-       /*
-        * XML
-        */
-       /**
-        * Get the XML text of this child node.
-        */
-       public static String getXmlValue(Node node, String name) {
-               try {
-                       if (!node.hasNode(name))
-                               return null;
-                       Node child = node.getNode(name);
-                       return getXmlValue(child);
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Cannot get " + name + " as XML text", e);
-               }
-       }
-
-       /**
-        * Get the XML text of this node.
-        */
-       public static String getXmlValue(Node node) {
-               try {
-                       if (!node.hasNode(Jcr.JCR_XMLTEXT))
-                               return null;
-                       Node xmlText = node.getNode(Jcr.JCR_XMLTEXT);
-                       if (!xmlText.hasProperty(Jcr.JCR_XMLCHARACTERS))
-                               throw new IllegalArgumentException(
-                                               "Node " + xmlText + " has no " + Jcr.JCR_XMLCHARACTERS + " property");
-                       return xmlText.getProperty(Jcr.JCR_XMLCHARACTERS).getString();
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Cannot get " + node + " as XML text", e);
-               }
-       }
-
-       /**
-        * Set as a subnode which will be exported as an XML element.
-        */
-       public static void setXmlValue(Node node, String name, String value) {
-               try {
-                       if (node.hasNode(name)) {
-                               Node child = node.getNode(name);
-                               setXmlValue(node, child, value);
-                       } else
-                               node.addNode(name, JcrxType.JCRX_XMLVALUE).addNode(Jcr.JCR_XMLTEXT, JcrxType.JCRX_XMLTEXT)
-                                               .setProperty(Jcr.JCR_XMLCHARACTERS, value);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set " + name + " as XML text", e);
-               }
-       }
-
-       public static void setXmlValue(Node node, Node child, String value) {
-               try {
-                       if (!child.hasNode(Jcr.JCR_XMLTEXT))
-                               child.addNode(Jcr.JCR_XMLTEXT, JcrxType.JCRX_XMLTEXT);
-                       child.getNode(Jcr.JCR_XMLTEXT).setProperty(Jcr.JCR_XMLCHARACTERS, value);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set " + child + " as XML text", e);
-               }
-       }
-
-       /**
-        * Add a checksum replacing the one which was previously set with the same
-        * length.
-        */
-       public static void addChecksum(Node node, String checksum) {
-               try {
-                       if (!node.hasProperty(JcrxName.JCRX_SUM)) {
-                               node.setProperty(JcrxName.JCRX_SUM, new String[] { checksum });
-                               return;
-                       } else {
-                               int stringLength = checksum.length();
-                               Property property = node.getProperty(JcrxName.JCRX_SUM);
-                               List<Value> values = Arrays.asList(property.getValues());
-                               Integer indexToRemove = null;
-                               values: for (int i = 0; i < values.size(); i++) {
-                                       Value value = values.get(i);
-                                       if (value.getString().length() == stringLength) {
-                                               indexToRemove = i;
-                                               break values;
-                                       }
-                               }
-                               if (indexToRemove != null)
-                                       values.set(indexToRemove, node.getSession().getValueFactory().createValue(checksum));
-                               else
-                                       values.add(0, node.getSession().getValueFactory().createValue(checksum));
-                               property.setValue(values.toArray(new Value[values.size()]));
-                       }
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set checksum on " + node, e);
-               }
-       }
-
-       /** Replace all checksums. */
-       public static void setChecksums(Node node, List<String> checksums) {
-               try {
-                       node.setProperty(JcrxName.JCRX_SUM, checksums.toArray(new String[checksums.size()]));
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot set checksums on " + node, e);
-               }
-       }
-
-       /** Replace all checksums. */
-       public static List<String> getChecksums(Node node) {
-               try {
-                       List<String> res = new ArrayList<>();
-                       if (!node.hasProperty(JcrxName.JCRX_SUM))
-                               return res;
-                       Property property = node.getProperty(JcrxName.JCRX_SUM);
-                       for (Value value : property.getValues()) {
-                               res.add(value.getString());
-                       }
-                       return res;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get checksums from " + node, e);
-               }
-       }
-
-//     /** Replace all checksums with this single one. */
-//     public static void setChecksum(Node node, String checksum) {
-//             setChecksums(node, Collections.singletonList(checksum));
-//     }
-
-       /** Retrieves the checksum with this algorithm, or null if not found. */
-       public static String getChecksum(Node node, String algorithm) {
-               int stringLength;
-               switch (algorithm) {
-               case MD5:
-                       stringLength = LENGTH_MD5;
-                       break;
-               case SHA1:
-                       stringLength = LENGTH_SHA1;
-                       break;
-               case SHA256:
-                       stringLength = LENGTH_SHA256;
-                       break;
-               case SHA512:
-                       stringLength = LENGTH_SHA512;
-                       break;
-               default:
-                       throw new IllegalArgumentException("Unkown algorithm " + algorithm);
-               }
-               return getChecksum(node, stringLength);
-       }
-
-       /** Retrieves the checksum with this string length, or null if not found. */
-       public static String getChecksum(Node node, int stringLength) {
-               try {
-                       if (!node.hasProperty(JcrxName.JCRX_SUM))
-                               return null;
-                       Property property = node.getProperty(JcrxName.JCRX_SUM);
-                       for (Value value : property.getValues()) {
-                               String str = value.getString();
-                               if (str.length() == stringLength)
-                                       return str;
-                       }
-                       return null;
-               } catch (RepositoryException e) {
-                       throw new IllegalStateException("Cannot get checksum for " + node, e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxName.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxName.java
deleted file mode 100644 (file)
index 9dd43ad..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.argeo.jcr;
-
-/** Names declared by the JCR extensions. */
-public interface JcrxName {
-       /** The multiple property holding various coherent checksums. */
-       public final static String JCRX_SUM = "{http://www.argeo.org/ns/jcrx}sum";
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxType.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxType.java
deleted file mode 100644 (file)
index 0cbad33..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.argeo.jcr;
-
-/** Node types declared by the JCR extensions. */
-public interface JcrxType {
-       /**
-        * Node type for an XML value, which will be serialized in XML as an element
-        * containing text.
-        */
-       public final static String JCRX_XMLVALUE = "{http://www.argeo.org/ns/jcrx}xmlvalue";
-
-       /** Node type for the node containing the text. */
-       public final static String JCRX_XMLTEXT = "{http://www.argeo.org/ns/jcrx}xmltext";
-
-       /** Mixin node type for a set of checksums. */
-       public final static String JCRX_CSUM = "{http://www.argeo.org/ns/jcrx}csum";
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/PropertyDiff.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/PropertyDiff.java
deleted file mode 100644 (file)
index 71e76fe..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.argeo.jcr;
-
-import javax.jcr.Value;
-
-/** The result of the comparison of two JCR properties. */
-public class PropertyDiff {
-       public final static Integer MODIFIED = 0;
-       public final static Integer ADDED = 1;
-       public final static Integer REMOVED = 2;
-
-       private final Integer type;
-       private final String relPath;
-       private final Value referenceValue;
-       private final Value newValue;
-
-       public PropertyDiff(Integer type, String relPath, Value referenceValue, Value newValue) {
-               super();
-
-               if (type == MODIFIED) {
-                       if (referenceValue == null || newValue == null)
-                               throw new IllegalArgumentException("Reference and new values must be specified.");
-               } else if (type == ADDED) {
-                       if (referenceValue != null || newValue == null)
-                               throw new IllegalArgumentException("New value and only it must be specified.");
-               } else if (type == REMOVED) {
-                       if (referenceValue == null || newValue != null)
-                               throw new IllegalArgumentException("Reference value and only it must be specified.");
-               } else {
-                       throw new IllegalArgumentException("Unkown diff type " + type);
-               }
-
-               if (relPath == null)
-                       throw new IllegalArgumentException("Relative path must be specified");
-
-               this.type = type;
-               this.relPath = relPath;
-               this.referenceValue = referenceValue;
-               this.newValue = newValue;
-       }
-
-       public Integer getType() {
-               return type;
-       }
-
-       public String getRelPath() {
-               return relPath;
-       }
-
-       public Value getReferenceValue() {
-               return referenceValue;
-       }
-
-       public Value getNewValue() {
-               return newValue;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/SimplePrincipal.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/SimplePrincipal.java
deleted file mode 100644 (file)
index 4f42f2d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.argeo.jcr;
-
-import java.security.Principal;
-
-/** Canonical implementation of a {@link Principal} */
-class SimplePrincipal implements Principal {
-       private final String name;
-
-       public SimplePrincipal(String name) {
-               if (name == null)
-                       throw new IllegalArgumentException("Principal name cannot be null");
-               this.name = name;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       @Override
-       public int hashCode() {
-               return name.hashCode();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (obj == null)
-                       return false;
-               if (obj instanceof Principal)
-                       return name.equals((((Principal) obj).getName()));
-               return name.equals(obj.toString());
-       }
-
-       @Override
-       protected Object clone() throws CloneNotSupportedException {
-               return new SimplePrincipal(name);
-       }
-
-       @Override
-       public String toString() {
-               return name;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java
deleted file mode 100644 (file)
index 2208627..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-package org.argeo.jcr;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.LoginException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.argeo.api.cms.CmsLog;
-
-/** Proxy JCR sessions and attach them to calling threads. */
-@Deprecated
-public abstract class ThreadBoundJcrSessionFactory {
-       private final static CmsLog log = CmsLog.getLog(ThreadBoundJcrSessionFactory.class);
-
-       private Repository repository;
-       /** can be injected as list, only used if repository is null */
-       private List<Repository> repositories;
-
-       private ThreadLocal<Session> session = new ThreadLocal<Session>();
-       private final Session proxiedSession;
-       /** If workspace is null, default will be used. */
-       private String workspace = null;
-
-       private String defaultUsername = "demo";
-       private String defaultPassword = "demo";
-       private Boolean forceDefaultCredentials = false;
-
-       private boolean active = true;
-
-       // monitoring
-       private final List<Thread> threads = Collections.synchronizedList(new ArrayList<Thread>());
-       private final Map<Long, Session> activeSessions = Collections.synchronizedMap(new HashMap<Long, Session>());
-       private MonitoringThread monitoringThread;
-
-       public ThreadBoundJcrSessionFactory() {
-               Class<?>[] interfaces = { Session.class };
-               proxiedSession = (Session) Proxy.newProxyInstance(ThreadBoundJcrSessionFactory.class.getClassLoader(),
-                               interfaces, new JcrSessionInvocationHandler());
-       }
-
-       /** Logs in to the repository using various strategies. */
-       protected synchronized Session login() {
-               if (!isActive())
-                       throw new IllegalStateException("Thread bound session factory inactive");
-
-               // discard session previously attached to this thread
-               Thread thread = Thread.currentThread();
-               if (activeSessions.containsKey(thread.getId())) {
-                       Session oldSession = activeSessions.remove(thread.getId());
-                       oldSession.logout();
-                       session.remove();
-               }
-
-               Session newSession = null;
-               // first try to login without credentials, assuming the underlying login
-               // module will have dealt with authentication (typically using Spring
-               // Security)
-               if (!forceDefaultCredentials)
-                       try {
-                               newSession = repository().login(workspace);
-                       } catch (LoginException e1) {
-                               log.warn("Cannot login without credentials: " + e1.getMessage());
-                               // invalid credentials, go to the next step
-                       } catch (RepositoryException e1) {
-                               // other kind of exception, fail
-                               throw new JcrException("Cannot log in to repository", e1);
-                       }
-
-               // log using default username / password (useful for testing purposes)
-               if (newSession == null)
-                       try {
-                               SimpleCredentials sc = new SimpleCredentials(defaultUsername, defaultPassword.toCharArray());
-                               newSession = repository().login(sc, workspace);
-                       } catch (RepositoryException e) {
-                               throw new JcrException("Cannot log in to repository", e);
-                       }
-
-               session.set(newSession);
-               // Log and monitor new session
-               if (log.isTraceEnabled())
-                       log.trace("Logged in to JCR session " + newSession + "; userId=" + newSession.getUserID());
-
-               // monitoring
-               activeSessions.put(thread.getId(), newSession);
-               threads.add(thread);
-               return newSession;
-       }
-
-       public Object getObject() {
-               return proxiedSession;
-       }
-
-       public void init() throws Exception {
-               // log.error("SHOULD NOT BE USED ANYMORE");
-               monitoringThread = new MonitoringThread();
-               monitoringThread.start();
-       }
-
-       public void dispose() throws Exception {
-               // if (activeSessions.size() == 0)
-               // return;
-
-               if (log.isTraceEnabled())
-                       log.trace("Cleaning up " + activeSessions.size() + " active JCR sessions...");
-
-               deactivate();
-               for (Session sess : activeSessions.values()) {
-                       JcrUtils.logoutQuietly(sess);
-               }
-               activeSessions.clear();
-       }
-
-       protected Boolean isActive() {
-               return active;
-       }
-
-       protected synchronized void deactivate() {
-               active = false;
-               notifyAll();
-       }
-
-       protected synchronized void removeSession(Thread thread) {
-               if (!isActive())
-                       return;
-               activeSessions.remove(thread.getId());
-               threads.remove(thread);
-       }
-
-       protected synchronized void cleanDeadThreads() {
-               if (!isActive())
-                       return;
-               Iterator<Thread> it = threads.iterator();
-               while (it.hasNext()) {
-                       Thread thread = it.next();
-                       if (!thread.isAlive() && isActive()) {
-                               if (activeSessions.containsKey(thread.getId())) {
-                                       Session session = activeSessions.get(thread.getId());
-                                       activeSessions.remove(thread.getId());
-                                       session.logout();
-                                       if (log.isTraceEnabled())
-                                               log.trace("Cleaned up JCR session (userID=" + session.getUserID() + ") from dead thread "
-                                                               + thread.getId());
-                               }
-                               it.remove();
-                       }
-               }
-               try {
-                       wait(1000);
-               } catch (InterruptedException e) {
-                       // silent
-               }
-       }
-
-       public Class<? extends Session> getObjectType() {
-               return Session.class;
-       }
-
-       public boolean isSingleton() {
-               return true;
-       }
-
-       /**
-        * Called before a method is actually called, allowing to check the session or
-        * re-login it (e.g. if authentication has changed). The default implementation
-        * returns the session.
-        */
-       protected Session preCall(Session session) {
-               return session;
-       }
-
-       protected Repository repository() {
-               if (repository != null)
-                       return repository;
-               if (repositories != null) {
-                       // hardened for OSGi dynamic services
-                       Iterator<Repository> it = repositories.iterator();
-                       if (it.hasNext())
-                               return it.next();
-               }
-               throw new IllegalStateException("No repository injected");
-       }
-
-       // /** Useful for declarative registration of OSGi services (blueprint) */
-       // public void register(Repository repository, Map<?, ?> params) {
-       // this.repository = repository;
-       // }
-       //
-       // /** Useful for declarative registration of OSGi services (blueprint) */
-       // public void unregister(Repository repository, Map<?, ?> params) {
-       // this.repository = null;
-       // }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setRepositories(List<Repository> repositories) {
-               this.repositories = repositories;
-       }
-
-       public void setDefaultUsername(String defaultUsername) {
-               this.defaultUsername = defaultUsername;
-       }
-
-       public void setDefaultPassword(String defaultPassword) {
-               this.defaultPassword = defaultPassword;
-       }
-
-       public void setForceDefaultCredentials(Boolean forceDefaultCredentials) {
-               this.forceDefaultCredentials = forceDefaultCredentials;
-       }
-
-       public void setWorkspace(String workspace) {
-               this.workspace = workspace;
-       }
-
-       protected class JcrSessionInvocationHandler implements InvocationHandler {
-
-               public Object invoke(Object proxy, Method method, Object[] args) throws Throwable, RepositoryException {
-                       Session threadSession = session.get();
-                       if (threadSession == null) {
-                               if ("logout".equals(method.getName()))// no need to login
-                                       return Void.TYPE;
-                               else if ("toString".equals(method.getName()))// maybe logging
-                                       return "Uninitialized Argeo thread bound JCR session";
-                               threadSession = login();
-                       }
-
-                       preCall(threadSession);
-                       Object ret;
-                       try {
-                               ret = method.invoke(threadSession, args);
-                       } catch (InvocationTargetException e) {
-                               Throwable cause = e.getCause();
-                               if (cause instanceof RepositoryException)
-                                       throw (RepositoryException) cause;
-                               else
-                                       throw cause;
-                       }
-                       if ("logout".equals(method.getName())) {
-                               session.remove();
-                               Thread thread = Thread.currentThread();
-                               removeSession(thread);
-                               if (log.isTraceEnabled())
-                                       log.trace("Logged out JCR session (userId=" + threadSession.getUserID() + ") on thread "
-                                                       + thread.getId());
-                       }
-                       return ret;
-               }
-       }
-
-       /** Monitors registered thread in order to clean up dead ones. */
-       private class MonitoringThread extends Thread {
-
-               public MonitoringThread() {
-                       super("ThreadBound JCR Session Monitor");
-               }
-
-               @Override
-               public void run() {
-                       while (isActive()) {
-                               cleanDeadThreads();
-                       }
-               }
-
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/VersionDiff.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/VersionDiff.java
deleted file mode 100644 (file)
index dab5554..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.argeo.jcr;
-
-import java.util.Calendar;
-import java.util.Map;
-
-/**
- * Generic Object that enables the creation of history reports based on a JCR
- * versionable node. userId and creation date are added to the map of
- * PropertyDiff.
- * 
- * These two fields might be null
- * 
- */
-public class VersionDiff {
-
-       private String userId;
-       private Map<String, PropertyDiff> diffs;
-       private Calendar updateTime;
-
-       public VersionDiff(String userId, Calendar updateTime,
-                       Map<String, PropertyDiff> diffs) {
-               this.userId = userId;
-               this.updateTime = updateTime;
-               this.diffs = diffs;
-       }
-
-       public String getUserId() {
-               return userId;
-       }
-
-       public Map<String, PropertyDiff> getDiffs() {
-               return diffs;
-       }
-
-       public Calendar getUpdateTime() {
-               return updateTime;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/BinaryChannel.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/BinaryChannel.java
deleted file mode 100644 (file)
index d6550fe..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-package org.argeo.jcr.fs;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.FileChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.SeekableByteChannel;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.jcr.JcrUtils;
-
-/** A read/write {@link SeekableByteChannel} based on a {@link Binary}. */
-public class BinaryChannel implements SeekableByteChannel {
-       private final Node file;
-       private Binary binary;
-       private boolean open = true;
-
-       private long position = 0;
-
-       private FileChannel fc = null;
-
-       public BinaryChannel(Node file, Path path) throws RepositoryException, IOException {
-               this.file = file;
-               Session session = file.getSession();
-               synchronized (session) {
-                       if (file.isNodeType(NodeType.NT_FILE)) {
-                               if (file.hasNode(Node.JCR_CONTENT)) {
-                                       Node data = file.getNode(Property.JCR_CONTENT);
-                                       this.binary = data.getProperty(Property.JCR_DATA).getBinary();
-                               } else {
-                                       Node data = file.addNode(Node.JCR_CONTENT, NodeType.NT_UNSTRUCTURED);
-                                       data.addMixin(NodeType.MIX_LAST_MODIFIED);
-                                       try (InputStream in = new ByteArrayInputStream(new byte[0])) {
-                                               this.binary = data.getSession().getValueFactory().createBinary(in);
-                                       }
-                                       data.setProperty(Property.JCR_DATA, this.binary);
-
-                                       // MIME type
-                                       String mime = Files.probeContentType(path);
-                                       // String mime = fileTypeMap.getContentType(file.getName());
-                                       data.setProperty(Property.JCR_MIMETYPE, mime);
-
-                                       session.refresh(true);
-                                       session.save();
-                                       session.notifyAll();
-                               }
-                       } else {
-                               throw new IllegalArgumentException(
-                                               "Unsupported file node " + file + " (" + file.getPrimaryNodeType() + ")");
-                       }
-               }
-       }
-
-       @Override
-       public synchronized boolean isOpen() {
-               return open;
-       }
-
-       @Override
-       public synchronized void close() throws IOException {
-               if (isModified()) {
-                       Binary newBinary = null;
-                       try {
-                               Session session = file.getSession();
-                               synchronized (session) {
-                                       fc.position(0);
-                                       InputStream in = Channels.newInputStream(fc);
-                                       newBinary = session.getValueFactory().createBinary(in);
-                                       file.getNode(Property.JCR_CONTENT).setProperty(Property.JCR_DATA, newBinary);
-                                       session.refresh(true);
-                                       session.save();
-                                       open = false;
-                                       session.notifyAll();
-                               }
-                       } catch (RepositoryException e) {
-                               throw new IOException("Cannot close " + file, e);
-                       } finally {
-                               JcrUtils.closeQuietly(newBinary);
-                               // IOUtils.closeQuietly(fc);
-                               if (fc != null) {
-                                       fc.close();
-                               }
-                       }
-               } else {
-                       clearReadState();
-                       open = false;
-               }
-       }
-
-       @Override
-       public int read(ByteBuffer dst) throws IOException {
-               if (isModified()) {
-                       return fc.read(dst);
-               } else {
-
-                       try {
-                               int read;
-                               byte[] arr = dst.array();
-                               read = binary.read(arr, position);
-
-                               if (read != -1)
-                                       position = position + read;
-                               return read;
-                       } catch (RepositoryException e) {
-                               throw new IOException("Cannot read into buffer", e);
-                       }
-               }
-       }
-
-       @Override
-       public int write(ByteBuffer src) throws IOException {
-               int written = getFileChannel().write(src);
-               return written;
-       }
-
-       @Override
-       public long position() throws IOException {
-               if (isModified())
-                       return getFileChannel().position();
-               else
-                       return position;
-       }
-
-       @Override
-       public SeekableByteChannel position(long newPosition) throws IOException {
-               if (isModified()) {
-                       getFileChannel().position(position);
-               } else {
-                       this.position = newPosition;
-               }
-               return this;
-       }
-
-       @Override
-       public long size() throws IOException {
-               if (isModified()) {
-                       return getFileChannel().size();
-               } else {
-                       try {
-                               return binary.getSize();
-                       } catch (RepositoryException e) {
-                               throw new IOException("Cannot get size", e);
-                       }
-               }
-       }
-
-       @Override
-       public SeekableByteChannel truncate(long size) throws IOException {
-               getFileChannel().truncate(size);
-               return this;
-       }
-
-       private FileChannel getFileChannel() throws IOException {
-               try {
-                       if (fc == null) {
-                               Path tempPath = Files.createTempFile(getClass().getSimpleName(), null);
-                               fc = FileChannel.open(tempPath, StandardOpenOption.WRITE, StandardOpenOption.READ,
-                                               StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.SPARSE);
-                               ReadableByteChannel readChannel = Channels.newChannel(binary.getStream());
-                               fc.transferFrom(readChannel, 0, binary.getSize());
-                               clearReadState();
-                       }
-                       return fc;
-               } catch (RepositoryException e) {
-                       throw new IOException("Cannot get temp file channel", e);
-               }
-       }
-
-       private boolean isModified() {
-               return fc != null;
-       }
-
-       private void clearReadState() {
-               position = -1;
-               JcrUtils.closeQuietly(binary);
-               binary = null;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java
deleted file mode 100644 (file)
index 7c9711b..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-package org.argeo.jcr.fs;
-
-import static javax.jcr.Property.JCR_CREATED;
-import static javax.jcr.Property.JCR_LAST_MODIFIED;
-
-import java.nio.file.attribute.FileTime;
-import java.time.Instant;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.jcr.JcrUtils;
-
-public class JcrBasicfileAttributes implements NodeFileAttributes {
-       private final Node node;
-
-       private final static FileTime EPOCH = FileTime.fromMillis(0);
-
-       public JcrBasicfileAttributes(Node node) {
-               if (node == null)
-                       throw new JcrFsException("Node underlying the attributes cannot be null");
-               this.node = node;
-       }
-
-       @Override
-       public FileTime lastModifiedTime() {
-               try {
-                       if (node.hasProperty(JCR_LAST_MODIFIED)) {
-                               Instant instant = node.getProperty(JCR_LAST_MODIFIED).getDate().toInstant();
-                               return FileTime.from(instant);
-                       } else if (node.hasProperty(JCR_CREATED)) {
-                               Instant instant = node.getProperty(JCR_CREATED).getDate().toInstant();
-                               return FileTime.from(instant);
-                       }
-//                     if (node.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
-//                             Instant instant = node.getProperty(Property.JCR_LAST_MODIFIED).getDate().toInstant();
-//                             return FileTime.from(instant);
-//                     }
-                       return EPOCH;
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot get last modified time", e);
-               }
-       }
-
-       @Override
-       public FileTime lastAccessTime() {
-               return lastModifiedTime();
-       }
-
-       @Override
-       public FileTime creationTime() {
-               try {
-                       if (node.hasProperty(JCR_CREATED)) {
-                               Instant instant = node.getProperty(JCR_CREATED).getDate().toInstant();
-                               return FileTime.from(instant);
-                       } else if (node.hasProperty(JCR_LAST_MODIFIED)) {
-                               Instant instant = node.getProperty(JCR_LAST_MODIFIED).getDate().toInstant();
-                               return FileTime.from(instant);
-                       }
-//                     if (node.isNodeType(NodeType.MIX_CREATED)) {
-//                             Instant instant = node.getProperty(JCR_CREATED).getDate().toInstant();
-//                             return FileTime.from(instant);
-//                     }
-                       return EPOCH;
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot get creation time", e);
-               }
-       }
-
-       @Override
-       public boolean isRegularFile() {
-               try {
-                       return node.isNodeType(NodeType.NT_FILE);
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot check if regular file", e);
-               }
-       }
-
-       @Override
-       public boolean isDirectory() {
-               try {
-                       if (node.isNodeType(NodeType.NT_FOLDER))
-                               return true;
-                       // all other non file nodes
-                       return !(node.isNodeType(NodeType.NT_FILE) || node.isNodeType(NodeType.NT_LINKED_FILE));
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot check if directory", e);
-               }
-       }
-
-       @Override
-       public boolean isSymbolicLink() {
-               try {
-                       return node.isNodeType(NodeType.NT_LINKED_FILE);
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot check if linked file", e);
-               }
-       }
-
-       @Override
-       public boolean isOther() {
-               return !(isDirectory() || isRegularFile() || isSymbolicLink());
-       }
-
-       @Override
-       public long size() {
-               if (isRegularFile()) {
-                       Binary binary = null;
-                       try {
-                               binary = node.getNode(Property.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary();
-                               return binary.getSize();
-                       } catch (RepositoryException e) {
-                               throw new JcrFsException("Cannot check size", e);
-                       } finally {
-                               JcrUtils.closeQuietly(binary);
-                       }
-               }
-               return -1;
-       }
-
-       @Override
-       public Object fileKey() {
-               try {
-                       return node.getIdentifier();
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot get identifier", e);
-               }
-       }
-
-       @Override
-       public Node getNode() {
-               return node;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java
deleted file mode 100644 (file)
index 4b32981..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-package org.argeo.jcr.fs;
-
-import java.io.IOException;
-import java.nio.file.FileStore;
-import java.nio.file.FileSystem;
-import java.nio.file.Path;
-import java.nio.file.PathMatcher;
-import java.nio.file.WatchService;
-import java.nio.file.attribute.UserPrincipalLookupService;
-import java.nio.file.spi.FileSystemProvider;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import javax.jcr.Credentials;
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.api.acr.fs.AbstractFsStore;
-import org.argeo.api.acr.fs.AbstractFsSystem;
-import org.argeo.jcr.Jcr;
-import org.argeo.jcr.JcrUtils;
-
-public class JcrFileSystem extends AbstractFsSystem<WorkspaceFileStore> {
-       private final JcrFileSystemProvider provider;
-
-       private final Repository repository;
-       private Session session;
-       private WorkspaceFileStore baseFileStore;
-
-       private Map<String, WorkspaceFileStore> mounts = new TreeMap<>();
-
-       private String userHomePath = null;
-
-       @Deprecated
-       public JcrFileSystem(JcrFileSystemProvider provider, Session session) throws IOException {
-               super();
-               this.provider = provider;
-               baseFileStore = new WorkspaceFileStore(null, session.getWorkspace());
-               this.session = session;
-//             Node userHome = provider.getUserHome(session);
-//             if (userHome != null)
-//                     try {
-//                             userHomePath = userHome.getPath();
-//                     } catch (RepositoryException e) {
-//                             throw new IOException("Cannot retrieve user home path", e);
-//                     }
-               this.repository = null;
-       }
-
-       public JcrFileSystem(JcrFileSystemProvider provider, Repository repository) throws IOException {
-               this(provider, repository, null);
-       }
-
-       public JcrFileSystem(JcrFileSystemProvider provider, Repository repository, Credentials credentials)
-                       throws IOException {
-               super();
-               this.provider = provider;
-               this.repository = repository;
-               try {
-                       this.session = credentials == null ? repository.login() : repository.login(credentials);
-                       baseFileStore = new WorkspaceFileStore(null, session.getWorkspace());
-                       workspaces: for (String workspaceName : baseFileStore.getWorkspace().getAccessibleWorkspaceNames()) {
-                               if (workspaceName.equals(baseFileStore.getWorkspace().getName()))
-                                       continue workspaces;// do not mount base
-                               if (workspaceName.equals("security")) {
-                                       continue workspaces;// do not mount security workspace
-                                       // TODO make it configurable
-                               }
-                               Session mountSession = credentials == null ? repository.login(workspaceName)
-                                               : repository.login(credentials, workspaceName);
-                               String mountPath = JcrPath.separator + workspaceName;
-                               mounts.put(mountPath, new WorkspaceFileStore(mountPath, mountSession.getWorkspace()));
-                       }
-               } catch (RepositoryException e) {
-                       throw new IOException("Cannot initialise file system", e);
-               }
-
-               Node userHome = provider.getUserHome(repository);
-               if (userHome != null)
-                       try {
-                               userHomePath = toFsPath(userHome);
-                       } catch (RepositoryException e) {
-                               throw new IOException("Cannot retrieve user home path", e);
-                       } finally {
-                               JcrUtils.logoutQuietly(Jcr.session(userHome));
-                       }
-       }
-
-       public String toFsPath(Node node) throws RepositoryException {
-               return getFileStore(node).toFsPath(node);
-       }
-
-       /** Whether this node should be skipped in directory listings */
-       public boolean skipNode(Node node) throws RepositoryException {
-               if (node.isNodeType(NodeType.NT_HIERARCHY_NODE))
-                       return false;
-               return true;
-       }
-
-       public String getUserHomePath() {
-               return userHomePath;
-       }
-
-       public WorkspaceFileStore getFileStore(String path) {
-               WorkspaceFileStore res = baseFileStore;
-               for (String mountPath : mounts.keySet()) {
-                       if (path.equals(mountPath))
-                               return mounts.get(mountPath);
-                       if (path.startsWith(mountPath + JcrPath.separator)) {
-                               res = mounts.get(mountPath);
-                               // we keep the last one
-                       }
-               }
-               assert res != null;
-               return res;
-       }
-
-       public WorkspaceFileStore getFileStore(Node node) throws RepositoryException {
-               String workspaceName = node.getSession().getWorkspace().getName();
-               if (workspaceName.equals(baseFileStore.getWorkspace().getName()))
-                       return baseFileStore;
-               for (String mountPath : mounts.keySet()) {
-                       WorkspaceFileStore fileStore = mounts.get(mountPath);
-                       if (workspaceName.equals(fileStore.getWorkspace().getName()))
-                               return fileStore;
-               }
-               throw new IllegalStateException("No workspace mount found for " + node + " in workspace " + workspaceName);
-       }
-
-       public Iterator<JcrPath> listDirectMounts(Path base) {
-               String baseStr = base.toString();
-               Set<JcrPath> res = new HashSet<>();
-               mounts: for (String mountPath : mounts.keySet()) {
-                       if (mountPath.equals(baseStr))
-                               continue mounts;
-                       if (mountPath.startsWith(baseStr)) {
-                               JcrPath path = new JcrPath(this, mountPath);
-                               Path relPath = base.relativize(path);
-                               if (relPath.getNameCount() == 1)
-                                       res.add(path);
-                       }
-               }
-               return res.iterator();
-       }
-
-       public WorkspaceFileStore getBaseFileStore() {
-               return baseFileStore;
-       }
-
-       @Override
-       public FileSystemProvider provider() {
-               return provider;
-       }
-
-       @Override
-       public void close() throws IOException {
-               JcrUtils.logoutQuietly(session);
-               for (String mountPath : mounts.keySet()) {
-                       WorkspaceFileStore fileStore = mounts.get(mountPath);
-                       try {
-                               fileStore.close();
-                       } catch (Exception e) {
-                               e.printStackTrace();
-                       }
-               }
-       }
-
-       @Override
-       public boolean isOpen() {
-               return session.isLive();
-       }
-
-       @Override
-       public boolean isReadOnly() {
-               return false;
-       }
-
-       @Override
-       public String getSeparator() {
-               return JcrPath.separator;
-       }
-
-       @Override
-       public Iterable<Path> getRootDirectories() {
-               Set<Path> single = new HashSet<>();
-               single.add(new JcrPath(this, JcrPath.separator));
-               return single;
-       }
-
-       @Override
-       public Iterable<FileStore> getFileStores() {
-               List<FileStore> stores = new ArrayList<>();
-               stores.add(baseFileStore);
-               stores.addAll(mounts.values());
-               return stores;
-       }
-
-       @Override
-       public Set<String> supportedFileAttributeViews() {
-               try {
-                       String[] prefixes = session.getNamespacePrefixes();
-                       Set<String> res = new HashSet<>();
-                       for (String prefix : prefixes)
-                               res.add(prefix);
-                       res.add("basic");
-                       return res;
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot get supported file attributes views", e);
-               }
-       }
-
-       @Override
-       public Path getPath(String first, String... more) {
-               StringBuilder sb = new StringBuilder(first);
-               // TODO Make it more robust
-               for (String part : more)
-                       sb.append('/').append(part);
-               return new JcrPath(this, sb.toString());
-       }
-
-       @Override
-       public PathMatcher getPathMatcher(String syntaxAndPattern) {
-               throw new UnsupportedOperationException();
-       }
-
-       @Override
-       public UserPrincipalLookupService getUserPrincipalLookupService() {
-               throw new UnsupportedOperationException();
-       }
-
-       @Override
-       public WatchService newWatchService() throws IOException {
-               throw new UnsupportedOperationException();
-       }
-
-//     public Session getSession() {
-//             return session;
-//     }
-
-       public Repository getRepository() {
-               return repository;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java
deleted file mode 100644 (file)
index 74d9a19..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-package org.argeo.jcr.fs;
-
-import java.io.IOException;
-import java.nio.channels.SeekableByteChannel;
-import java.nio.file.AccessMode;
-import java.nio.file.CopyOption;
-import java.nio.file.DirectoryNotEmptyException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.DirectoryStream.Filter;
-import java.nio.file.FileStore;
-import java.nio.file.LinkOption;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.spi.FileSystemProvider;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.PropertyDefinition;
-
-import org.argeo.jcr.JcrUtils;
-
-/** Operations on a {@link JcrFileSystem}. */
-public abstract class JcrFileSystemProvider extends FileSystemProvider {
-
-       @Override
-       public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs)
-                       throws IOException {
-               Node node = toNode(path);
-               try {
-                       if (node == null) {
-                               Node parent = toNode(path.getParent());
-                               if (parent == null)
-                                       throw new IOException("No parent directory for " + path);
-                               if (parent.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)
-                                               || parent.getPrimaryNodeType().isNodeType(NodeType.NT_LINKED_FILE))
-                                       throw new IOException(path + " parent is a file");
-
-                               String fileName = path.getFileName().toString();
-                               fileName = Text.escapeIllegalJcrChars(fileName);
-                               node = parent.addNode(fileName, NodeType.NT_FILE);
-                               node.addMixin(NodeType.MIX_CREATED);
-//                             node.addMixin(NodeType.MIX_LAST_MODIFIED);
-                       }
-                       if (!node.isNodeType(NodeType.NT_FILE))
-                               throw new UnsupportedOperationException(node + " must be a file");
-                       return new BinaryChannel(node, path);
-               } catch (RepositoryException e) {
-                       discardChanges(node);
-                       throw new IOException("Cannot read file", e);
-               }
-       }
-
-       @Override
-       public DirectoryStream<Path> newDirectoryStream(Path dir, Filter<? super Path> filter) throws IOException {
-               try {
-                       Node base = toNode(dir);
-                       if (base == null)
-                               throw new IOException(dir + " is not a JCR node");
-                       JcrFileSystem fileSystem = (JcrFileSystem) dir.getFileSystem();
-                       return new NodeDirectoryStream(fileSystem, base.getNodes(), fileSystem.listDirectMounts(dir), filter);
-               } catch (RepositoryException e) {
-                       throw new IOException("Cannot list directory", e);
-               }
-       }
-
-       @Override
-       public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
-               Node node = toNode(dir);
-               try {
-                       if (node == null) {
-                               Node parent = toNode(dir.getParent());
-                               if (parent == null)
-                                       throw new IOException("Parent of " + dir + " does not exist");
-                               Session session = parent.getSession();
-                               synchronized (session) {
-                                       if (parent.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)
-                                                       || parent.getPrimaryNodeType().isNodeType(NodeType.NT_LINKED_FILE))
-                                               throw new IOException(dir + " parent is a file");
-                                       String fileName = dir.getFileName().toString();
-                                       fileName = Text.escapeIllegalJcrChars(fileName);
-                                       node = parent.addNode(fileName, NodeType.NT_FOLDER);
-                                       node.addMixin(NodeType.MIX_CREATED);
-                                       node.addMixin(NodeType.MIX_LAST_MODIFIED);
-                                       save(session);
-                               }
-                       } else {
-                               // if (!node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER))
-                               // throw new FileExistsException(dir + " exists and is not a directory");
-                       }
-               } catch (RepositoryException e) {
-                       discardChanges(node);
-                       throw new IOException("Cannot create directory " + dir, e);
-               }
-       }
-
-       @Override
-       public void delete(Path path) throws IOException {
-               Node node = toNode(path);
-               try {
-                       if (node == null)
-                               throw new NoSuchFileException(path + " does not exist");
-                       Session session = node.getSession();
-                       synchronized (session) {
-                               session.refresh(false);
-                               if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FILE))
-                                       node.remove();
-                               else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER)) {
-                                       if (node.hasNodes())// TODO check only files
-                                               throw new DirectoryNotEmptyException(path.toString());
-                                       node.remove();
-                               }
-                               save(session);
-                       }
-               } catch (RepositoryException e) {
-                       discardChanges(node);
-                       throw new IOException("Cannot delete " + path, e);
-               }
-
-       }
-
-       @Override
-       public void copy(Path source, Path target, CopyOption... options) throws IOException {
-               Node sourceNode = toNode(source);
-               Node targetNode = toNode(target);
-               try {
-                       Session targetSession = targetNode.getSession();
-                       synchronized (targetSession) {
-                               JcrUtils.copy(sourceNode, targetNode);
-                               save(targetSession);
-                       }
-               } catch (RepositoryException e) {
-                       discardChanges(sourceNode);
-                       discardChanges(targetNode);
-                       throw new IOException("Cannot copy from " + source + " to " + target, e);
-               }
-       }
-
-       @Override
-       public void move(Path source, Path target, CopyOption... options) throws IOException {
-               JcrFileSystem sourceFileSystem = (JcrFileSystem) source.getFileSystem();
-               WorkspaceFileStore sourceStore = sourceFileSystem.getFileStore(source.toString());
-               WorkspaceFileStore targetStore = sourceFileSystem.getFileStore(target.toString());
-               try {
-                       if (sourceStore.equals(targetStore)) {
-                               sourceStore.getWorkspace().move(sourceStore.toJcrPath(source.toString()),
-                                               targetStore.toJcrPath(target.toString()));
-                       } else {
-                               // TODO implement it
-                               throw new UnsupportedOperationException("Can only move paths within the same workspace.");
-                       }
-               } catch (RepositoryException e) {
-                       throw new IOException("Cannot move from " + source + " to " + target, e);
-               }
-
-//             Node sourceNode = toNode(source);
-//             try {
-//                     Session session = sourceNode.getSession();
-//                     synchronized (session) {
-//                             session.move(sourceNode.getPath(), target.toString());
-//                             save(session);
-//                     }
-//             } catch (RepositoryException e) {
-//                     discardChanges(sourceNode);
-//                     throw new IOException("Cannot move from " + source + " to " + target, e);
-//             }
-       }
-
-       @Override
-       public boolean isSameFile(Path path, Path path2) throws IOException {
-               if (path.getFileSystem() != path2.getFileSystem())
-                       return false;
-               boolean equ = path.equals(path2);
-               if (equ)
-                       return true;
-               else {
-                       try {
-                               Node node = toNode(path);
-                               Node node2 = toNode(path2);
-                               return node.isSame(node2);
-                       } catch (RepositoryException e) {
-                               throw new IOException("Cannot check whether " + path + " and " + path2 + " are same", e);
-                       }
-               }
-
-       }
-
-       @Override
-       public boolean isHidden(Path path) throws IOException {
-               return path.getFileName().toString().charAt(0) == '.';
-       }
-
-       @Override
-       public FileStore getFileStore(Path path) throws IOException {
-               JcrFileSystem fileSystem = (JcrFileSystem) path.getFileSystem();
-               return fileSystem.getFileStore(path.toString());
-       }
-
-       @Override
-       public void checkAccess(Path path, AccessMode... modes) throws IOException {
-               Node node = toNode(path);
-               if (node == null)
-                       throw new NoSuchFileException(path + " does not exist");
-               // TODO check access via JCR api
-       }
-
-       @Override
-       public <V extends FileAttributeView> V getFileAttributeView(Path path, Class<V> type, LinkOption... options) {
-               throw new UnsupportedOperationException();
-       }
-
-       @SuppressWarnings("unchecked")
-       @Override
-       public <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options)
-                       throws IOException {
-               // TODO check if assignable
-               Node node = toNode(path);
-               if (node == null) {
-                       throw new IOException("JCR node not found for " + path);
-               }
-               return (A) new JcrBasicfileAttributes(node);
-       }
-
-       @Override
-       public Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options) throws IOException {
-               try {
-                       Node node = toNode(path);
-                       String pattern = attributes.replace(',', '|');
-                       Map<String, Object> res = new HashMap<String, Object>();
-                       PropertyIterator it = node.getProperties(pattern);
-                       props: while (it.hasNext()) {
-                               Property prop = it.nextProperty();
-                               PropertyDefinition pd = prop.getDefinition();
-                               if (pd.isMultiple())
-                                       continue props;
-                               int requiredType = pd.getRequiredType();
-                               switch (requiredType) {
-                               case PropertyType.LONG:
-                                       res.put(prop.getName(), prop.getLong());
-                                       break;
-                               case PropertyType.DOUBLE:
-                                       res.put(prop.getName(), prop.getDouble());
-                                       break;
-                               case PropertyType.BOOLEAN:
-                                       res.put(prop.getName(), prop.getBoolean());
-                                       break;
-                               case PropertyType.DATE:
-                                       res.put(prop.getName(), prop.getDate());
-                                       break;
-                               case PropertyType.BINARY:
-                                       byte[] arr = JcrUtils.getBinaryAsBytes(prop);
-                                       res.put(prop.getName(), arr);
-                                       break;
-                               default:
-                                       res.put(prop.getName(), prop.getString());
-                               }
-                       }
-                       return res;
-               } catch (RepositoryException e) {
-                       throw new IOException("Cannot read attributes of " + path, e);
-               }
-       }
-
-       @Override
-       public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException {
-               Node node = toNode(path);
-               try {
-                       Session session = node.getSession();
-                       synchronized (session) {
-                               if (value instanceof byte[]) {
-                                       JcrUtils.setBinaryAsBytes(node, attribute, (byte[]) value);
-                               } else if (value instanceof Calendar) {
-                                       node.setProperty(attribute, (Calendar) value);
-                               } else {
-                                       node.setProperty(attribute, value.toString());
-                               }
-                               save(session);
-                       }
-               } catch (RepositoryException e) {
-                       discardChanges(node);
-                       throw new IOException("Cannot set attribute " + attribute + " on " + path, e);
-               }
-       }
-
-       protected Node toNode(Path path) {
-               try {
-                       return ((JcrPath) path).getNode();
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot convert path " + path + " to JCR Node", e);
-               }
-       }
-
-       /** Discard changes in the underlying session */
-       protected void discardChanges(Node node) {
-               if (node == null)
-                       return;
-               try {
-                       // discard changes
-                       node.getSession().refresh(false);
-               } catch (RepositoryException e) {
-                       e.printStackTrace();
-                       // TODO log out session?
-                       // TODO use Commons logging?
-               }
-       }
-
-       /** Make sure save is robust. */
-       protected void save(Session session) throws RepositoryException {
-               session.refresh(true);
-               session.save();
-               session.notifyAll();
-       }
-
-       /**
-        * To be overriden in order to support the ~ path, with an implementation
-        * specific concept of user home.
-        * 
-        * @return null by default
-        */
-       public Node getUserHome(Repository session) {
-               return null;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFsException.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrFsException.java
deleted file mode 100644 (file)
index f214fdc..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.argeo.jcr.fs;
-
-
-/** Exception related to the JCR FS */
-public class JcrFsException extends RuntimeException {
-       private static final long serialVersionUID = -7973896038244922980L;
-
-       public JcrFsException(String message, Throwable e) {
-               super(message, e);
-       }
-
-       public JcrFsException(String message) {
-               super(message);
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrPath.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/JcrPath.java
deleted file mode 100644 (file)
index 7318b70..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-package org.argeo.jcr.fs;
-
-import java.nio.file.Path;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.acr.fs.AbstractFsPath;
-
-/** A {@link Path} which contains a reference to a JCR {@link Node}. */
-public class JcrPath extends AbstractFsPath<JcrFileSystem, WorkspaceFileStore> {
-       final static String separator = "/";
-       final static char separatorChar = '/';
-
-//     private final JcrFileSystem fs;
-//     /** null for non absolute paths */
-//     private final WorkspaceFileStore fileStore;
-//     private final String[] path;// null means root
-//     private final boolean absolute;
-//
-//     // optim
-//     private final int hashCode;
-
-       public JcrPath(JcrFileSystem filesSystem, String path) {
-               super(filesSystem, path);
-//             this.fs = filesSystem;
-//             if (path == null)
-//                     throw new JcrFsException("Path cannot be null");
-//             if (path.equals(separator)) {// root
-//                     this.path = null;
-//                     this.absolute = true;
-//                     this.hashCode = 0;
-//                     this.fileStore = fs.getBaseFileStore();
-//                     return;
-//             } else if (path.equals("")) {// empty path
-//                     this.path = new String[] { "" };
-//                     this.absolute = false;
-//                     this.fileStore = null;
-//                     this.hashCode = "".hashCode();
-//                     return;
-//             }
-//
-//             if (path.equals("~")) {// home
-//                     path = filesSystem.getUserHomePath();
-//                     if (path == null)
-//                             throw new JcrFsException("No home directory available");
-//             }
-//
-//             this.absolute = path.charAt(0) == separatorChar ? true : false;
-//
-//             this.fileStore = absolute ? fs.getFileStore(path) : null;
-//
-//             String trimmedPath = path.substring(absolute ? 1 : 0,
-//                             path.charAt(path.length() - 1) == separatorChar ? path.length() - 1 : path.length());
-//             this.path = trimmedPath.split(separator);
-//             for (int i = 0; i < this.path.length; i++) {
-//                     this.path[i] = Text.unescapeIllegalJcrChars(this.path[i]);
-//             }
-//             this.hashCode = this.path[this.path.length - 1].hashCode();
-//             assert !(absolute && fileStore == null);
-       }
-
-       public JcrPath(JcrFileSystem filesSystem, Node node) throws RepositoryException {
-               this(filesSystem, filesSystem.getFileStore(node).toFsPath(node));
-       }
-
-       /** Internal optimisation */
-       private JcrPath(JcrFileSystem filesSystem, WorkspaceFileStore fileStore, String[] path, boolean absolute) {
-               super(filesSystem, fileStore, path, absolute);
-//             this.fs = filesSystem;
-//             this.path = path;
-//             this.absolute = path == null ? true : absolute;
-//             if (this.absolute && fileStore == null)
-//                     throw new IllegalArgumentException("Absolute path requires a file store");
-//             if (!this.absolute && fileStore != null)
-//                     throw new IllegalArgumentException("A file store should not be provided for a relative path");
-//             this.fileStore = fileStore;
-//             this.hashCode = path == null ? 0 : path[path.length - 1].hashCode();
-//             assert !(absolute && fileStore == null);
-       }
-
-       protected String cleanUpSegment(String segment) {
-               return Text.unescapeIllegalJcrChars(segment);
-       }
-
-       @Override
-       protected JcrPath newInstance(String path) {
-               return new JcrPath(getFileSystem(), path);
-       }
-
-       @Override
-       protected JcrPath newInstance(String[] segments, boolean absolute) {
-               return new JcrPath(getFileSystem(), getFileStore(), segments, absolute);
-
-       }
-
-//     @Override
-//     public FileSystem getFileSystem() {
-//             return fs;
-//     }
-//
-//     @Override
-//     public boolean isAbsolute() {
-//             return absolute;
-//     }
-//
-//     @Override
-//     public Path getRoot() {
-//             if (path == null)
-//                     return this;
-//             return new JcrPath(fs, separator);
-//     }
-//
-//     @Override
-//     public String toString() {
-//             return toFsPath(path);
-//     }
-//
-//     private String toFsPath(String[] path) {
-//             if (path == null)
-//                     return "/";
-//             StringBuilder sb = new StringBuilder();
-//             if (isAbsolute())
-//                     sb.append('/');
-//             for (int i = 0; i < path.length; i++) {
-//                     if (i != 0)
-//                             sb.append('/');
-//                     sb.append(path[i]);
-//             }
-//             return sb.toString();
-//     }
-
-//     @Deprecated
-//     private String toJcrPath() {
-//             return toJcrPath(path);
-//     }
-//
-//     @Deprecated
-//     private String toJcrPath(String[] path) {
-//             if (path == null)
-//                     return "/";
-//             StringBuilder sb = new StringBuilder();
-//             if (isAbsolute())
-//                     sb.append('/');
-//             for (int i = 0; i < path.length; i++) {
-//                     if (i != 0)
-//                             sb.append('/');
-//                     sb.append(Text.escapeIllegalJcrChars(path[i]));
-//             }
-//             return sb.toString();
-//     }
-
-//     @Override
-//     public Path getFileName() {
-//             if (path == null)
-//                     return null;
-//             return new JcrPath(fs, path[path.length - 1]);
-//     }
-//
-//     @Override
-//     public Path getParent() {
-//             if (path == null)
-//                     return null;
-//             if (path.length == 1)// root
-//                     return new JcrPath(fs, separator);
-//             String[] parentPath = Arrays.copyOfRange(path, 0, path.length - 1);
-//             if (!absolute)
-//                     return new JcrPath(fs, null, parentPath, absolute);
-//             else
-//                     return new JcrPath(fs, toFsPath(parentPath));
-//     }
-//
-//     @Override
-//     public int getNameCount() {
-//             if (path == null)
-//                     return 0;
-//             return path.length;
-//     }
-//
-//     @Override
-//     public Path getName(int index) {
-//             if (path == null)
-//                     return null;
-//             return new JcrPath(fs, path[index]);
-//     }
-//
-//     @Override
-//     public Path subpath(int beginIndex, int endIndex) {
-//             if (path == null)
-//                     return null;
-//             String[] parentPath = Arrays.copyOfRange(path, beginIndex, endIndex);
-//             return new JcrPath(fs, null, parentPath, false);
-//     }
-//
-//     @Override
-//     public boolean startsWith(Path other) {
-//             return toString().startsWith(other.toString());
-//     }
-//
-//     @Override
-//     public boolean startsWith(String other) {
-//             return toString().startsWith(other);
-//     }
-//
-//     @Override
-//     public boolean endsWith(Path other) {
-//             return toString().endsWith(other.toString());
-//     }
-//
-//     @Override
-//     public boolean endsWith(String other) {
-//             return toString().endsWith(other);
-//     }
-
-//     @Override
-//     public Path normalize() {
-//             // always normalized
-//             return this;
-//     }
-
-//     @Override
-//     public Path resolve(Path other) {
-//             JcrPath otherPath = (JcrPath) other;
-//             if (otherPath.isAbsolute())
-//                     return other;
-//             String[] newPath;
-//             if (path == null) {
-//                     newPath = new String[otherPath.path.length];
-//                     System.arraycopy(otherPath.path, 0, newPath, 0, otherPath.path.length);
-//             } else {
-//                     newPath = new String[path.length + otherPath.path.length];
-//                     System.arraycopy(path, 0, newPath, 0, path.length);
-//                     System.arraycopy(otherPath.path, 0, newPath, path.length, otherPath.path.length);
-//             }
-//             if (!absolute)
-//                     return new JcrPath(fs, null, newPath, absolute);
-//             else {
-//                     return new JcrPath(fs, toFsPath(newPath));
-//             }
-//     }
-//
-//     @Override
-//     public final Path resolve(String other) {
-//             return resolve(getFileSystem().getPath(other));
-//     }
-//
-//     @Override
-//     public final Path resolveSibling(Path other) {
-//             if (other == null)
-//                     throw new NullPointerException();
-//             Path parent = getParent();
-//             return (parent == null) ? other : parent.resolve(other);
-//     }
-//
-//     @Override
-//     public final Path resolveSibling(String other) {
-//             return resolveSibling(getFileSystem().getPath(other));
-//     }
-//
-//     @Override
-//     public final Iterator<Path> iterator() {
-//             return new Iterator<Path>() {
-//                     private int i = 0;
-//
-//                     @Override
-//                     public boolean hasNext() {
-//                             return (i < getNameCount());
-//                     }
-//
-//                     @Override
-//                     public Path next() {
-//                             if (i < getNameCount()) {
-//                                     Path result = getName(i);
-//                                     i++;
-//                                     return result;
-//                             } else {
-//                                     throw new NoSuchElementException();
-//                             }
-//                     }
-//
-//                     @Override
-//                     public void remove() {
-//                             throw new UnsupportedOperationException();
-//                     }
-//             };
-//     }
-//
-//     @Override
-//     public Path relativize(Path other) {
-//             if (equals(other))
-//                     return new JcrPath(fs, "");
-//             if (other.startsWith(this)) {
-//                     String p1 = toString();
-//                     String p2 = other.toString();
-//                     String relative = p2.substring(p1.length(), p2.length());
-//                     if (relative.charAt(0) == '/')
-//                             relative = relative.substring(1);
-//                     return new JcrPath(fs, relative);
-//             }
-//             throw new IllegalArgumentException(other + " cannot be relativized against " + this);
-//     }
-
-//     @Override
-//     public URI toUri() {
-//             try {
-//                     return new URI(fs.provider().getScheme(), toString(), null);
-//             } catch (URISyntaxException e) {
-//                     throw new JcrFsException("Cannot create URI for " + toString(), e);
-//             }
-//     }
-//
-//     @Override
-//     public Path toAbsolutePath() {
-//             if (isAbsolute())
-//                     return this;
-//             return new JcrPath(fs, fileStore, path, true);
-//     }
-//
-//     @Override
-//     public Path toRealPath(LinkOption... options) throws IOException {
-//             return this;
-//     }
-//
-//     @Override
-//     public File toFile() {
-//             throw new UnsupportedOperationException();
-//     }
-
-       public Node getNode() throws RepositoryException {
-               if (!isAbsolute())// TODO default dir
-                       throw new JcrFsException("Cannot get a JCR node from a relative path");
-               assert getFileStore() != null;
-               return getFileStore().toNode(getSegments());
-//             String pathStr = toJcrPath();
-//             Session session = fs.getSession();
-//             // TODO synchronize on the session ?
-//             if (!session.itemExists(pathStr))
-//                     return null;
-//             return session.getNode(pathStr);
-       }
-//
-//     @Override
-//     public boolean equals(Object obj) {
-//             if (!(obj instanceof JcrPath))
-//                     return false;
-//             JcrPath other = (JcrPath) obj;
-//
-//             if (path == null) {// root
-//                     if (other.path == null)// root
-//                             return true;
-//                     else
-//                             return false;
-//             } else {
-//                     if (other.path == null)// root
-//                             return false;
-//             }
-//             // non root
-//             if (path.length != other.path.length)
-//                     return false;
-//             for (int i = 0; i < path.length; i++) {
-//                     if (!path[i].equals(other.path[i]))
-//                             return false;
-//             }
-//             return true;
-//     }
-
-//     @Override
-//     public int hashCode() {
-//             return hashCode;
-//     }
-
-//     @Override
-//     protected Object clone() throws CloneNotSupportedException {
-//             return new JcrPath(fs, toString());
-//     }
-
-//     @Override
-//     protected void finalize() throws Throwable {
-//             Arrays.fill(path, null);
-//     }
-
-       
-       
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java
deleted file mode 100644 (file)
index eda07a5..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.argeo.jcr.fs;
-
-import java.io.IOException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Path;
-import java.util.Iterator;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-
-public class NodeDirectoryStream implements DirectoryStream<Path> {
-       private final JcrFileSystem fs;
-       private final NodeIterator nodeIterator;
-       private final Iterator<JcrPath> additionalPaths;
-       private final Filter<? super Path> filter;
-
-       public NodeDirectoryStream(JcrFileSystem fs, NodeIterator nodeIterator, Iterator<JcrPath> additionalPaths,
-                       Filter<? super Path> filter) {
-               this.fs = fs;
-               this.nodeIterator = nodeIterator;
-               this.additionalPaths = additionalPaths;
-               this.filter = filter;
-       }
-
-       @Override
-       public void close() throws IOException {
-       }
-
-       @Override
-       public Iterator<Path> iterator() {
-               return new Iterator<Path>() {
-                       private JcrPath next = null;
-
-                       @Override
-                       public synchronized boolean hasNext() {
-                               if (next != null)
-                                       return true;
-                               nodes: while (nodeIterator.hasNext()) {
-                                       try {
-                                               Node node = nodeIterator.nextNode();
-                                               String nodeName = node.getName();
-                                               if (nodeName.startsWith("rep:") || nodeName.startsWith("jcr:"))
-                                                       continue nodes;
-                                               if (fs.skipNode(node))
-                                                       continue nodes;
-                                               next = new JcrPath(fs, node);
-                                               if (filter != null) {
-                                                       if (filter.accept(next))
-                                                               break nodes;
-                                               } else
-                                                       break nodes;
-                                       } catch (Exception e) {
-                                               throw new JcrFsException("Could not get next path", e);
-                                       }
-                               }
-
-                               if (next == null) {
-                                       if (additionalPaths.hasNext())
-                                               next = additionalPaths.next();
-                               }
-
-                               return next != null;
-                       }
-
-                       @Override
-                       public synchronized Path next() {
-                               if (!hasNext())// make sure has next has been called
-                                       return null;
-                               JcrPath res = next;
-                               next = null;
-                               return res;
-                       }
-
-               };
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/NodeFileAttributes.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/NodeFileAttributes.java
deleted file mode 100644 (file)
index 8054d52..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.argeo.jcr.fs;
-
-import java.nio.file.attribute.BasicFileAttributes;
-
-import javax.jcr.Node;
-
-public interface NodeFileAttributes extends BasicFileAttributes {
-       public Node getNode();
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/Text.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/Text.java
deleted file mode 100644 (file)
index 4643c8c..0000000
+++ /dev/null
@@ -1,877 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.jcr.fs;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Properties;
-
-/**
- * <b>Hacked from org.apache.jackrabbit.util.Text in Jackrabbit JCR Commons</b>
- * This Class provides some text related utilities
- */
-class Text {
-
-       /**
-        * Hidden constructor.
-        */
-       private Text() {
-       }
-
-       /**
-        * used for the md5
-        */
-       public static final char[] hexTable = "0123456789abcdef".toCharArray();
-
-       /**
-        * Calculate an MD5 hash of the string given.
-        *
-        * @param data
-        *            the data to encode
-        * @param enc
-        *            the character encoding to use
-        * @return a hex encoded string of the md5 digested input
-        */
-       public static String md5(String data, String enc) throws UnsupportedEncodingException {
-               try {
-                       return digest("MD5", data.getBytes(enc));
-               } catch (NoSuchAlgorithmException e) {
-                       throw new InternalError("MD5 digest not available???");
-               }
-       }
-
-       /**
-        * Calculate an MD5 hash of the string given using 'utf-8' encoding.
-        *
-        * @param data
-        *            the data to encode
-        * @return a hex encoded string of the md5 digested input
-        */
-       public static String md5(String data) {
-               try {
-                       return md5(data, "utf-8");
-               } catch (UnsupportedEncodingException e) {
-                       throw new InternalError("UTF8 digest not available???");
-               }
-       }
-
-       /**
-        * Digest the plain string using the given algorithm.
-        *
-        * @param algorithm
-        *            The alogrithm for the digest. This algorithm must be supported
-        *            by the MessageDigest class.
-        * @param data
-        *            The plain text String to be digested.
-        * @param enc
-        *            The character encoding to use
-        * @return The digested plain text String represented as Hex digits.
-        * @throws java.security.NoSuchAlgorithmException
-        *             if the desired algorithm is not supported by the
-        *             MessageDigest class.
-        * @throws java.io.UnsupportedEncodingException
-        *             if the encoding is not supported
-        */
-       public static String digest(String algorithm, String data, String enc)
-                       throws NoSuchAlgorithmException, UnsupportedEncodingException {
-
-               return digest(algorithm, data.getBytes(enc));
-       }
-
-       /**
-        * Digest the plain string using the given algorithm.
-        *
-        * @param algorithm
-        *            The algorithm for the digest. This algorithm must be supported
-        *            by the MessageDigest class.
-        * @param data
-        *            the data to digest with the given algorithm
-        * @return The digested plain text String represented as Hex digits.
-        * @throws java.security.NoSuchAlgorithmException
-        *             if the desired algorithm is not supported by the
-        *             MessageDigest class.
-        */
-       public static String digest(String algorithm, byte[] data) throws NoSuchAlgorithmException {
-
-               MessageDigest md = MessageDigest.getInstance(algorithm);
-               byte[] digest = md.digest(data);
-               StringBuilder res = new StringBuilder(digest.length * 2);
-               for (byte b : digest) {
-                       res.append(hexTable[(b >> 4) & 15]);
-                       res.append(hexTable[b & 15]);
-               }
-               return res.toString();
-       }
-
-       /**
-        * returns an array of strings decomposed of the original string, split at
-        * every occurrence of 'ch'. if 2 'ch' follow each other with no
-        * intermediate characters, empty "" entries are avoided.
-        *
-        * @param str
-        *            the string to decompose
-        * @param ch
-        *            the character to use a split pattern
-        * @return an array of strings
-        */
-       public static String[] explode(String str, int ch) {
-               return explode(str, ch, false);
-       }
-
-       /**
-        * returns an array of strings decomposed of the original string, split at
-        * every occurrence of 'ch'.
-        *
-        * @param str
-        *            the string to decompose
-        * @param ch
-        *            the character to use a split pattern
-        * @param respectEmpty
-        *            if <code>true</code>, empty elements are generated
-        * @return an array of strings
-        */
-       public static String[] explode(String str, int ch, boolean respectEmpty) {
-               if (str == null || str.length() == 0) {
-                       return new String[0];
-               }
-
-               ArrayList<String> strings = new ArrayList<String>();
-               int pos;
-               int lastpos = 0;
-
-               // add snipples
-               while ((pos = str.indexOf(ch, lastpos)) >= 0) {
-                       if (pos - lastpos > 0 || respectEmpty) {
-                               strings.add(str.substring(lastpos, pos));
-                       }
-                       lastpos = pos + 1;
-               }
-               // add rest
-               if (lastpos < str.length()) {
-                       strings.add(str.substring(lastpos));
-               } else if (respectEmpty && lastpos == str.length()) {
-                       strings.add("");
-               }
-
-               // return string array
-               return strings.toArray(new String[strings.size()]);
-       }
-
-       /**
-        * Concatenates all strings in the string array using the specified
-        * delimiter.
-        * 
-        * @param arr
-        * @param delim
-        * @return the concatenated string
-        */
-       public static String implode(String[] arr, String delim) {
-               StringBuilder buf = new StringBuilder();
-               for (int i = 0; i < arr.length; i++) {
-                       if (i > 0) {
-                               buf.append(delim);
-                       }
-                       buf.append(arr[i]);
-               }
-               return buf.toString();
-       }
-
-       /**
-        * Replaces all occurrences of <code>oldString</code> in <code>text</code>
-        * with <code>newString</code>.
-        *
-        * @param text
-        * @param oldString
-        *            old substring to be replaced with <code>newString</code>
-        * @param newString
-        *            new substring to replace occurrences of <code>oldString</code>
-        * @return a string
-        */
-       public static String replace(String text, String oldString, String newString) {
-               if (text == null || oldString == null || newString == null) {
-                       throw new IllegalArgumentException("null argument");
-               }
-               int pos = text.indexOf(oldString);
-               if (pos == -1) {
-                       return text;
-               }
-               int lastPos = 0;
-               StringBuilder sb = new StringBuilder(text.length());
-               while (pos != -1) {
-                       sb.append(text.substring(lastPos, pos));
-                       sb.append(newString);
-                       lastPos = pos + oldString.length();
-                       pos = text.indexOf(oldString, lastPos);
-               }
-               if (lastPos < text.length()) {
-                       sb.append(text.substring(lastPos));
-               }
-               return sb.toString();
-       }
-
-       /**
-        * Replaces XML characters in the given string that might need escaping as
-        * XML text or attribute
-        *
-        * @param text
-        *            text to be escaped
-        * @return a string
-        */
-       public static String encodeIllegalXMLCharacters(String text) {
-               return encodeMarkupCharacters(text, false);
-       }
-
-       /**
-        * Replaces HTML characters in the given string that might need escaping as
-        * HTML text or attribute
-        *
-        * @param text
-        *            text to be escaped
-        * @return a string
-        */
-       public static String encodeIllegalHTMLCharacters(String text) {
-               return encodeMarkupCharacters(text, true);
-       }
-
-       private static String encodeMarkupCharacters(String text, boolean isHtml) {
-               if (text == null) {
-                       throw new IllegalArgumentException("null argument");
-               }
-               StringBuilder buf = null;
-               int length = text.length();
-               int pos = 0;
-               for (int i = 0; i < length; i++) {
-                       int ch = text.charAt(i);
-                       switch (ch) {
-                       case '<':
-                       case '>':
-                       case '&':
-                       case '"':
-                       case '\'':
-                               if (buf == null) {
-                                       buf = new StringBuilder();
-                               }
-                               if (i > 0) {
-                                       buf.append(text.substring(pos, i));
-                               }
-                               pos = i + 1;
-                               break;
-                       default:
-                               continue;
-                       }
-                       if (ch == '<') {
-                               buf.append("&lt;");
-                       } else if (ch == '>') {
-                               buf.append("&gt;");
-                       } else if (ch == '&') {
-                               buf.append("&amp;");
-                       } else if (ch == '"') {
-                               buf.append("&quot;");
-                       } else if (ch == '\'') {
-                               buf.append(isHtml ? "&#39;" : "&apos;");
-                       }
-               }
-               if (buf == null) {
-                       return text;
-               } else {
-                       if (pos < length) {
-                               buf.append(text.substring(pos));
-                       }
-                       return buf.toString();
-               }
-       }
-
-       /**
-        * The list of characters that are not encoded by the <code>escape()</code>
-        * and <code>unescape()</code> METHODS. They contains the characters as
-        * defined 'unreserved' in section 2.3 of the RFC 2396 'URI generic syntax':
-        * <p>
-        * 
-        * <pre>
-        * unreserved  = alphanum | mark
-        * mark        = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
-        * </pre>
-        */
-       public static BitSet URISave;
-
-       /**
-        * Same as {@link #URISave} but also contains the '/'
-        */
-       public static BitSet URISaveEx;
-
-       static {
-               URISave = new BitSet(256);
-               int i;
-               for (i = 'a'; i <= 'z'; i++) {
-                       URISave.set(i);
-               }
-               for (i = 'A'; i <= 'Z'; i++) {
-                       URISave.set(i);
-               }
-               for (i = '0'; i <= '9'; i++) {
-                       URISave.set(i);
-               }
-               URISave.set('-');
-               URISave.set('_');
-               URISave.set('.');
-               URISave.set('!');
-               URISave.set('~');
-               URISave.set('*');
-               URISave.set('\'');
-               URISave.set('(');
-               URISave.set(')');
-
-               URISaveEx = (BitSet) URISave.clone();
-               URISaveEx.set('/');
-       }
-
-       /**
-        * Does an URL encoding of the <code>string</code> using the
-        * <code>escape</code> character. The characters that don't need encoding
-        * are those defined 'unreserved' in section 2.3 of the 'URI generic syntax'
-        * RFC 2396, but without the escape character.
-        *
-        * @param string
-        *            the string to encode.
-        * @param escape
-        *            the escape character.
-        * @return the escaped string
-        * @throws NullPointerException
-        *             if <code>string</code> is <code>null</code>.
-        */
-       public static String escape(String string, char escape) {
-               return escape(string, escape, false);
-       }
-
-       /**
-        * Does an URL encoding of the <code>string</code> using the
-        * <code>escape</code> character. The characters that don't need encoding
-        * are those defined 'unreserved' in section 2.3 of the 'URI generic syntax'
-        * RFC 2396, but without the escape character. If <code>isPath</code> is
-        * <code>true</code>, additionally the slash '/' is ignored, too.
-        *
-        * @param string
-        *            the string to encode.
-        * @param escape
-        *            the escape character.
-        * @param isPath
-        *            if <code>true</code>, the string is treated as path
-        * @return the escaped string
-        * @throws NullPointerException
-        *             if <code>string</code> is <code>null</code>.
-        */
-       public static String escape(String string, char escape, boolean isPath) {
-               try {
-                       BitSet validChars = isPath ? URISaveEx : URISave;
-                       byte[] bytes = string.getBytes("utf-8");
-                       StringBuilder out = new StringBuilder(bytes.length);
-                       for (byte aByte : bytes) {
-                               int c = aByte & 0xff;
-                               if (validChars.get(c) && c != escape) {
-                                       out.append((char) c);
-                               } else {
-                                       out.append(escape);
-                                       out.append(hexTable[(c >> 4) & 0x0f]);
-                                       out.append(hexTable[(c) & 0x0f]);
-                               }
-                       }
-                       return out.toString();
-               } catch (UnsupportedEncodingException e) {
-                       throw new InternalError(e.toString());
-               }
-       }
-
-       /**
-        * Does a URL encoding of the <code>string</code>. The characters that don't
-        * need encoding are those defined 'unreserved' in section 2.3 of the 'URI
-        * generic syntax' RFC 2396.
-        *
-        * @param string
-        *            the string to encode
-        * @return the escaped string
-        * @throws NullPointerException
-        *             if <code>string</code> is <code>null</code>.
-        */
-       public static String escape(String string) {
-               return escape(string, '%');
-       }
-
-       /**
-        * Does a URL encoding of the <code>path</code>. The characters that don't
-        * need encoding are those defined 'unreserved' in section 2.3 of the 'URI
-        * generic syntax' RFC 2396. In contrast to the {@link #escape(String)}
-        * method, not the entire path string is escaped, but every individual part
-        * (i.e. the slashes are not escaped).
-        *
-        * @param path
-        *            the path to encode
-        * @return the escaped path
-        * @throws NullPointerException
-        *             if <code>path</code> is <code>null</code>.
-        */
-       public static String escapePath(String path) {
-               return escape(path, '%', true);
-       }
-
-       /**
-        * Does a URL decoding of the <code>string</code> using the
-        * <code>escape</code> character. Please note that in opposite to the
-        * {@link java.net.URLDecoder} it does not transform the + into spaces.
-        *
-        * @param string
-        *            the string to decode
-        * @param escape
-        *            the escape character
-        * @return the decoded string
-        * @throws NullPointerException
-        *             if <code>string</code> is <code>null</code>.
-        * @throws IllegalArgumentException
-        *             if the 2 characters following the escape character do not
-        *             represent a hex-number or if not enough characters follow an
-        *             escape character
-        */
-       public static String unescape(String string, char escape) {
-               try {
-                       byte[] utf8 = string.getBytes("utf-8");
-
-                       // Check whether escape occurs at invalid position
-                       if ((utf8.length >= 1 && utf8[utf8.length - 1] == escape)
-                                       || (utf8.length >= 2 && utf8[utf8.length - 2] == escape)) {
-                               throw new IllegalArgumentException("Premature end of escape sequence at end of input");
-                       }
-
-                       ByteArrayOutputStream out = new ByteArrayOutputStream(utf8.length);
-                       for (int k = 0; k < utf8.length; k++) {
-                               byte b = utf8[k];
-                               if (b == escape) {
-                                       out.write((decodeDigit(utf8[++k]) << 4) + decodeDigit(utf8[++k]));
-                               } else {
-                                       out.write(b);
-                               }
-                       }
-
-                       return new String(out.toByteArray(), "utf-8");
-               } catch (UnsupportedEncodingException e) {
-                       throw new InternalError(e.toString());
-               }
-       }
-
-       /**
-        * Does a URL decoding of the <code>string</code>. Please note that in
-        * opposite to the {@link java.net.URLDecoder} it does not transform the +
-        * into spaces.
-        *
-        * @param string
-        *            the string to decode
-        * @return the decoded string
-        * @throws NullPointerException
-        *             if <code>string</code> is <code>null</code>.
-        * @throws ArrayIndexOutOfBoundsException
-        *             if not enough character follow an escape character
-        * @throws IllegalArgumentException
-        *             if the 2 characters following the escape character do not
-        *             represent a hex-number.
-        */
-       public static String unescape(String string) {
-               return unescape(string, '%');
-       }
-
-       /**
-        * Escapes all illegal JCR name characters of a string. The encoding is
-        * loosely modeled after URI encoding, but only encodes the characters it
-        * absolutely needs to in order to make the resulting string a valid JCR
-        * name. Use {@link #unescapeIllegalJcrChars(String)} for decoding.
-        * <p>
-        * QName EBNF:<br>
-        * <xmp> simplename ::= onecharsimplename | twocharsimplename |
-        * threeormorecharname onecharsimplename ::= (* Any Unicode character
-        * except: '.', '/', ':', '[', ']', '*', '|' or any whitespace character *)
-        * twocharsimplename ::= '.' onecharsimplename | onecharsimplename '.' |
-        * onecharsimplename onecharsimplename threeormorecharname ::= nonspace
-        * string nonspace string ::= char | string char char ::= nonspace | ' '
-        * nonspace ::= (* Any Unicode character except: '/', ':', '[', ']', '*',
-        * '|' or any whitespace character *) </xmp>
-        *
-        * @param name
-        *            the name to escape
-        * @return the escaped name
-        */
-       public static String escapeIllegalJcrChars(String name) {
-               return escapeIllegalChars(name, "%/:[]*|\t\r\n");
-       }
-
-       /**
-        * Escapes all illegal JCR 1.0 name characters of a string. Use
-        * {@link #unescapeIllegalJcrChars(String)} for decoding.
-        * <p>
-        * QName EBNF:<br>
-        * <xmp> simplename ::= onecharsimplename | twocharsimplename |
-        * threeormorecharname onecharsimplename ::= (* Any Unicode character
-        * except: '.', '/', ':', '[', ']', '*', ''', '"', '|' or any whitespace
-        * character *) twocharsimplename ::= '.' onecharsimplename |
-        * onecharsimplename '.' | onecharsimplename onecharsimplename
-        * threeormorecharname ::= nonspace string nonspace string ::= char | string
-        * char char ::= nonspace | ' ' nonspace ::= (* Any Unicode character
-        * except: '/', ':', '[', ']', '*', ''', '"', '|' or any whitespace
-        * character *) </xmp>
-        *
-        * @since Apache Jackrabbit 2.3.2 and 2.2.10
-        * @see <a href=
-        *      "https://issues.apache.org/jira/browse/JCR-3128">JCR-3128</a>
-        * @param name
-        *            the name to escape
-        * @return the escaped name
-        */
-       public static String escapeIllegalJcr10Chars(String name) {
-               return escapeIllegalChars(name, "%/:[]*'\"|\t\r\n");
-       }
-
-       private static String escapeIllegalChars(String name, String illegal) {
-               StringBuilder buffer = new StringBuilder(name.length() * 2);
-               for (int i = 0; i < name.length(); i++) {
-                       char ch = name.charAt(i);
-                       if (illegal.indexOf(ch) != -1 || (ch == '.' && name.length() < 3)
-                                       || (ch == ' ' && (i == 0 || i == name.length() - 1))) {
-                               buffer.append('%');
-                               buffer.append(Character.toUpperCase(Character.forDigit(ch / 16, 16)));
-                               buffer.append(Character.toUpperCase(Character.forDigit(ch % 16, 16)));
-                       } else {
-                               buffer.append(ch);
-                       }
-               }
-               return buffer.toString();
-       }
-
-       /**
-        * Escapes illegal XPath search characters at the end of a string.
-        * <p>
-        * Example:<br>
-        * A search string like 'test?' will run into a ParseException documented in
-        * http://issues.apache.org/jira/browse/JCR-1248
-        *
-        * @param s
-        *            the string to encode
-        * @return the escaped string
-        */
-       public static String escapeIllegalXpathSearchChars(String s) {
-               StringBuilder sb = new StringBuilder();
-               sb.append(s.substring(0, (s.length() - 1)));
-               char c = s.charAt(s.length() - 1);
-               // NOTE: keep this in sync with _ESCAPED_CHAR below!
-               if (c == '!' || c == '(' || c == ':' || c == '^' || c == '[' || c == ']' || c == '{' || c == '}' || c == '?') {
-                       sb.append('\\');
-               }
-               sb.append(c);
-               return sb.toString();
-       }
-
-       /**
-        * Unescapes previously escaped jcr chars.
-        * <p>
-        * Please note, that this does not exactly the same as the url related
-        * {@link #unescape(String)}, since it handles the byte-encoding
-        * differently.
-        *
-        * @param name
-        *            the name to unescape
-        * @return the unescaped name
-        */
-       public static String unescapeIllegalJcrChars(String name) {
-               StringBuilder buffer = new StringBuilder(name.length());
-               int i = name.indexOf('%');
-               while (i > -1 && i + 2 < name.length()) {
-                       buffer.append(name.toCharArray(), 0, i);
-                       int a = Character.digit(name.charAt(i + 1), 16);
-                       int b = Character.digit(name.charAt(i + 2), 16);
-                       if (a > -1 && b > -1) {
-                               buffer.append((char) (a * 16 + b));
-                               name = name.substring(i + 3);
-                       } else {
-                               buffer.append('%');
-                               name = name.substring(i + 1);
-                       }
-                       i = name.indexOf('%');
-               }
-               buffer.append(name);
-               return buffer.toString();
-       }
-
-       /**
-        * Returns the name part of the path. If the given path is already a name
-        * (i.e. contains no slashes) it is returned.
-        *
-        * @param path
-        *            the path
-        * @return the name part or <code>null</code> if <code>path</code> is
-        *         <code>null</code>.
-        */
-       public static String getName(String path) {
-               return getName(path, '/');
-       }
-
-       /**
-        * Returns the name part of the path, delimited by the given
-        * <code>delim</code>. If the given path is already a name (i.e. contains no
-        * <code>delim</code> characters) it is returned.
-        *
-        * @param path
-        *            the path
-        * @param delim
-        *            the delimiter
-        * @return the name part or <code>null</code> if <code>path</code> is
-        *         <code>null</code>.
-        */
-       public static String getName(String path, char delim) {
-               return path == null ? null : path.substring(path.lastIndexOf(delim) + 1);
-       }
-
-       /**
-        * Same as {@link #getName(String)} but adding the possibility to pass paths
-        * that end with a trailing '/'
-        *
-        * @see #getName(String)
-        */
-       public static String getName(String path, boolean ignoreTrailingSlash) {
-               if (ignoreTrailingSlash && path != null && path.endsWith("/") && path.length() > 1) {
-                       path = path.substring(0, path.length() - 1);
-               }
-               return getName(path);
-       }
-
-       /**
-        * Returns the namespace prefix of the given <code>qname</code>. If the
-        * prefix is missing, an empty string is returned. Please note, that this
-        * method does not validate the name or prefix.
-        * </p>
-        * the qname has the format: qname := [prefix ':'] local;
-        *
-        * @param qname
-        *            a qualified name
-        * @return the prefix of the name or "".
-        *
-        * @see #getLocalName(String)
-        *
-        * @throws NullPointerException
-        *             if <code>qname</code> is <code>null</code>
-        */
-       public static String getNamespacePrefix(String qname) {
-               int pos = qname.indexOf(':');
-               return pos >= 0 ? qname.substring(0, pos) : "";
-       }
-
-       /**
-        * Returns the local name of the given <code>qname</code>. Please note, that
-        * this method does not validate the name.
-        * </p>
-        * the qname has the format: qname := [prefix ':'] local;
-        *
-        * @param qname
-        *            a qualified name
-        * @return the localname
-        *
-        * @see #getNamespacePrefix(String)
-        *
-        * @throws NullPointerException
-        *             if <code>qname</code> is <code>null</code>
-        */
-       public static String getLocalName(String qname) {
-               int pos = qname.indexOf(':');
-               return pos >= 0 ? qname.substring(pos + 1) : qname;
-       }
-
-       /**
-        * Determines, if two paths denote hierarchical siblins.
-        *
-        * @param p1
-        *            first path
-        * @param p2
-        *            second path
-        * @return true if on same level, false otherwise
-        */
-       public static boolean isSibling(String p1, String p2) {
-               int pos1 = p1.lastIndexOf('/');
-               int pos2 = p2.lastIndexOf('/');
-               return (pos1 == pos2 && pos1 >= 0 && p1.regionMatches(0, p2, 0, pos1));
-       }
-
-       /**
-        * Determines if the <code>descendant</code> path is hierarchical a
-        * descendant of <code>path</code>.
-        *
-        * @param path
-        *            the current path
-        * @param descendant
-        *            the potential descendant
-        * @return <code>true</code> if the <code>descendant</code> is a descendant;
-        *         <code>false</code> otherwise.
-        */
-       public static boolean isDescendant(String path, String descendant) {
-               String pattern = path.endsWith("/") ? path : path + "/";
-               return !pattern.equals(descendant) && descendant.startsWith(pattern);
-       }
-
-       /**
-        * Determines if the <code>descendant</code> path is hierarchical a
-        * descendant of <code>path</code> or equal to it.
-        *
-        * @param path
-        *            the path to check
-        * @param descendant
-        *            the potential descendant
-        * @return <code>true</code> if the <code>descendant</code> is a descendant
-        *         or equal; <code>false</code> otherwise.
-        */
-       public static boolean isDescendantOrEqual(String path, String descendant) {
-               if (path.equals(descendant)) {
-                       return true;
-               } else {
-                       String pattern = path.endsWith("/") ? path : path + "/";
-                       return descendant.startsWith(pattern);
-               }
-       }
-
-       /**
-        * Returns the n<sup>th</sup> relative parent of the path, where n=level.
-        * <p>
-        * Example:<br>
-        * <code>
-        * Text.getRelativeParent("/foo/bar/test", 1) == "/foo/bar"
-        * </code>
-        *
-        * @param path
-        *            the path of the page
-        * @param level
-        *            the level of the parent
-        */
-       public static String getRelativeParent(String path, int level) {
-               int idx = path.length();
-               while (level > 0) {
-                       idx = path.lastIndexOf('/', idx - 1);
-                       if (idx < 0) {
-                               return "";
-                       }
-                       level--;
-               }
-               return (idx == 0) ? "/" : path.substring(0, idx);
-       }
-
-       /**
-        * Same as {@link #getRelativeParent(String, int)} but adding the
-        * possibility to pass paths that end with a trailing '/'
-        *
-        * @see #getRelativeParent(String, int)
-        */
-       public static String getRelativeParent(String path, int level, boolean ignoreTrailingSlash) {
-               if (ignoreTrailingSlash && path.endsWith("/") && path.length() > 1) {
-                       path = path.substring(0, path.length() - 1);
-               }
-               return getRelativeParent(path, level);
-       }
-
-       /**
-        * Returns the n<sup>th</sup> absolute parent of the path, where n=level.
-        * <p>
-        * Example:<br>
-        * <code>
-        * Text.getAbsoluteParent("/foo/bar/test", 1) == "/foo/bar"
-        * </code>
-        *
-        * @param path
-        *            the path of the page
-        * @param level
-        *            the level of the parent
-        */
-       public static String getAbsoluteParent(String path, int level) {
-               int idx = 0;
-               int len = path.length();
-               while (level >= 0 && idx < len) {
-                       idx = path.indexOf('/', idx + 1);
-                       if (idx < 0) {
-                               idx = len;
-                       }
-                       level--;
-               }
-               return level >= 0 ? "" : path.substring(0, idx);
-       }
-
-       /**
-        * Performs variable replacement on the given string value. Each
-        * <code>${...}</code> sequence within the given value is replaced with the
-        * value of the named parser variable. If a variable is not found in the
-        * properties an IllegalArgumentException is thrown unless
-        * <code>ignoreMissing</code> is <code>true</code>. In the later case, the
-        * missing variable is replaced by the empty string.
-        *
-        * @param value
-        *            the original value
-        * @param ignoreMissing
-        *            if <code>true</code>, missing variables are replaced by the
-        *            empty string.
-        * @return value after variable replacements
-        * @throws IllegalArgumentException
-        *             if the replacement of a referenced variable is not found
-        */
-       public static String replaceVariables(Properties variables, String value, boolean ignoreMissing)
-                       throws IllegalArgumentException {
-               StringBuilder result = new StringBuilder();
-
-               // Value:
-               // +--+-+--------+-+-----------------+
-               // | |p|--> |q|--> |
-               // +--+-+--------+-+-----------------+
-               int p = 0, q = value.indexOf("${"); // Find first ${
-               while (q != -1) {
-                       result.append(value.substring(p, q)); // Text before ${
-                       p = q;
-                       q = value.indexOf("}", q + 2); // Find }
-                       if (q != -1) {
-                               String variable = value.substring(p + 2, q);
-                               String replacement = variables.getProperty(variable);
-                               if (replacement == null) {
-                                       if (ignoreMissing) {
-                                               replacement = "";
-                                       } else {
-                                               throw new IllegalArgumentException("Replacement not found for ${" + variable + "}.");
-                                       }
-                               }
-                               result.append(replacement);
-                               p = q + 1;
-                               q = value.indexOf("${", p); // Find next ${
-                       }
-               }
-               result.append(value.substring(p, value.length())); // Trailing text
-
-               return result.toString();
-       }
-
-       private static byte decodeDigit(byte b) {
-               if (b >= 0x30 && b <= 0x39) {
-                       return (byte) (b - 0x30);
-               } else if (b >= 0x41 && b <= 0x46) {
-                       return (byte) (b - 0x37);
-               } else if (b >= 0x61 && b <= 0x66) {
-                       return (byte) (b - 0x57);
-               } else {
-                       throw new IllegalArgumentException("Escape sequence is not hexadecimal: " + (char) b);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/WorkspaceFileStore.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/WorkspaceFileStore.java
deleted file mode 100644 (file)
index ce4205a..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-package org.argeo.jcr.fs;
-
-import java.io.IOException;
-import java.nio.file.FileStore;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileStoreAttributeView;
-import java.util.Arrays;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Workspace;
-
-import org.argeo.api.acr.fs.AbstractFsStore;
-import org.argeo.jcr.JcrUtils;
-
-/** A {@link FileStore} implementation based on JCR {@link Workspace}. */
-public class WorkspaceFileStore extends AbstractFsStore {
-       private final String mountPath;
-       private final Workspace workspace;
-       private final String workspaceName;
-       private final int mountDepth;
-
-       public WorkspaceFileStore(String mountPath, Workspace workspace) {
-               if ("/".equals(mountPath) || "".equals(mountPath))
-                       throw new IllegalArgumentException(
-                                       "Mount path '" + mountPath + "' is unsupported, use null for the base file store");
-               if (mountPath != null && !mountPath.startsWith(JcrPath.separator))
-                       throw new IllegalArgumentException("Mount path '" + mountPath + "' cannot end with /");
-               if (mountPath != null && mountPath.endsWith(JcrPath.separator))
-                       throw new IllegalArgumentException("Mount path '" + mountPath + "' cannot end with /");
-               this.mountPath = mountPath;
-               if (mountPath == null)
-                       mountDepth = 0;
-               else {
-                       mountDepth = mountPath.split(JcrPath.separator).length - 1;
-               }
-               this.workspace = workspace;
-               this.workspaceName = workspace.getName();
-       }
-
-       public void close() {
-               JcrUtils.logoutQuietly(workspace.getSession());
-       }
-
-       @Override
-       public String name() {
-               return workspace.getName();
-       }
-
-       @Override
-       public String type() {
-               return "workspace";
-       }
-
-       @Override
-       public boolean isReadOnly() {
-               return false;
-       }
-
-       @Override
-       public long getTotalSpace() throws IOException {
-               return 0;
-       }
-
-       @Override
-       public long getUsableSpace() throws IOException {
-               return 0;
-       }
-
-       @Override
-       public long getUnallocatedSpace() throws IOException {
-               return 0;
-       }
-
-       @Override
-       public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
-               return false;
-       }
-
-       @Override
-       public boolean supportsFileAttributeView(String name) {
-               return false;
-       }
-
-       @Override
-       public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
-               return null;
-       }
-
-       @Override
-       public Object getAttribute(String attribute) throws IOException {
-               return workspace.getSession().getRepository().getDescriptor(attribute);
-       }
-
-       public Workspace getWorkspace() {
-               return workspace;
-       }
-
-       public String toFsPath(Node node) throws RepositoryException {
-               String nodeWorkspaceName = node.getSession().getWorkspace().getName();
-               if (!nodeWorkspaceName.equals(workspace.getName()))
-                       throw new IllegalArgumentException("Icompatible " + node + " from workspace '" + nodeWorkspaceName
-                                       + "' in file store '" + workspace.getName() + "'");
-               return mountPath == null ? node.getPath() : mountPath + node.getPath();
-       }
-
-       public boolean isBase() {
-               return mountPath == null;
-       }
-
-       Node toNode(String[] fullPath) throws RepositoryException {
-               String jcrPath = toJcrPath(fullPath);
-               Session session = workspace.getSession();
-               if (!session.itemExists(jcrPath))
-                       return null;
-               Node node = session.getNode(jcrPath);
-               return node;
-       }
-
-       String toJcrPath(String fsPath) {
-               if (fsPath.length() == 1)
-                       return toJcrPath((String[]) null);// root
-               String[] arr = fsPath.substring(1).split("/");
-//             if (arr.length == 0 || (arr.length == 1 && arr[0].equals("")))
-//                     return toJcrPath((String[]) null);// root
-//             else
-               return toJcrPath(arr);
-       }
-
-       private String toJcrPath(String[] path) {
-               if (path == null)
-                       return "/";
-               if (path.length < mountDepth)
-                       throw new IllegalArgumentException(
-                                       "Path " + Arrays.asList(path) + " is no compatible with mount " + mountPath);
-
-               if (!isBase()) {
-                       // check mount compatibility
-                       StringBuilder mount = new StringBuilder();
-                       mount.append('/');
-                       for (int i = 0; i < mountDepth; i++) {
-                               if (i != 0)
-                                       mount.append('/');
-                               mount.append(Text.escapeIllegalJcrChars(path[i]));
-                       }
-                       if (!mountPath.equals(mount.toString()))
-                               throw new IllegalArgumentException(
-                                               "Path " + Arrays.asList(path) + " is no compatible with mount " + mountPath);
-               }
-
-               StringBuilder sb = new StringBuilder();
-               sb.append('/');
-               for (int i = mountDepth; i < path.length; i++) {
-                       if (i != mountDepth)
-                               sb.append('/');
-                       sb.append(Text.escapeIllegalJcrChars(path[i]));
-               }
-               return sb.toString();
-       }
-
-       public String getMountPath() {
-               return mountPath;
-       }
-
-       public String getWorkspaceName() {
-               return workspaceName;
-       }
-
-       public int getMountDepth() {
-               return mountDepth;
-       }
-
-       @Override
-       public int hashCode() {
-               return workspaceName.hashCode();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (!(obj instanceof WorkspaceFileStore))
-                       return false;
-               WorkspaceFileStore other = (WorkspaceFileStore) obj;
-               return workspaceName.equals(other.workspaceName);
-       }
-
-       @Override
-       public String toString() {
-               return "WorkspaceFileStore " + workspaceName;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/fs/package-info.java
deleted file mode 100644 (file)
index 0cdfdaf..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Java NIO file system implementation based on plain JCR. */
-package org.argeo.jcr.fs;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/jcrx.cnd b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/jcrx.cnd
deleted file mode 100644 (file)
index 3eb0e7a..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-// JCR EXTENSIONS
-//
-<jcrx = "http://www.argeo.org/ns/jcrx">
-
-[jcrx:xmlvalue]
-- *
-+ jcr:xmltext (jcrx:xmltext) = jcrx:xmltext
-
-[jcrx:xmltext]
- - jcr:xmlcharacters (STRING) mandatory
-
-[jcrx:csum]
-mixin
- - jcrx:sum (STRING) *
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/package-info.java
deleted file mode 100644 (file)
index 1837749..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Generic JCR utilities. */
-package org.argeo.jcr;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java
deleted file mode 100644 (file)
index 0177636..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-package org.argeo.jcr.proxy;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-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 CmsLog log = CmsLog.getLog(AbstractUrlProxy.class);
-
-       private Repository jcrRepository;
-       private Session jcrAdminSession;
-       private String proxyWorkspace = "proxy";
-
-       protected abstract Node retrieve(Session session, String path);
-
-       void init() {
-               try {
-                       jcrAdminSession = JcrUtils.loginOrCreateWorkspace(jcrRepository, proxyWorkspace);
-                       beforeInitSessionSave(jcrAdminSession);
-                       if (jcrAdminSession.hasPendingChanges())
-                               jcrAdminSession.save();
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(jcrAdminSession);
-                       throw new JcrException("Cannot initialize URL proxy", e);
-               }
-       }
-
-       /**
-        * Called before the (admin) session is saved at the end of the initialization.
-        * Does nothing by default, to be overridden.
-        */
-       protected void beforeInitSessionSave(Session session) throws RepositoryException {
-       }
-
-       void destroy() {
-               JcrUtils.logoutQuietly(jcrAdminSession);
-       }
-
-       /**
-        * Called before the (admin) session is logged out when resources are released.
-        * Does nothing by default, to be overridden.
-        */
-       protected void beforeDestroySessionLogout() throws RepositoryException {
-       }
-
-       public Node proxy(String path) {
-               // we open a JCR session with client credentials in order not to use the
-               // admin session in multiple thread or make it a bottleneck.
-               Node nodeAdmin = null;
-               Node nodeClient = null;
-               Session clientSession = null;
-               try {
-                       clientSession = jcrRepository.login(proxyWorkspace);
-                       if (!clientSession.itemExists(path) || shouldUpdate(clientSession, path)) {
-                               nodeAdmin = retrieveAndSave(path);
-                               if (nodeAdmin != null)
-                                       nodeClient = clientSession.getNode(path);
-                       } else
-                               nodeClient = clientSession.getNode(path);
-                       return nodeClient;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot proxy " + path, e);
-               } finally {
-                       if (nodeClient == null)
-                               JcrUtils.logoutQuietly(clientSession);
-               }
-       }
-
-       protected synchronized Node retrieveAndSave(String path) {
-               try {
-                       Node node = retrieve(jcrAdminSession, path);
-                       if (node == null)
-                               return null;
-                       jcrAdminSession.save();
-                       return node;
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(jcrAdminSession);
-                       throw new JcrException("Cannot retrieve and save " + path, e);
-               } finally {
-                       notifyAll();
-               }
-       }
-
-       /** Session is not saved */
-       protected synchronized Node proxyUrl(Session session, String remoteUrl, String path) throws RepositoryException {
-               Node node = null;
-               if (session.itemExists(path)) {
-                       // throw new ArgeoJcrException("Node " + path + " already exists");
-               }
-               try (InputStream in = new URL(remoteUrl).openStream()) {
-                       // URL u = new URL(remoteUrl);
-                       // in = u.openStream();
-                       node = importFile(session, path, in);
-               } catch (IOException e) {
-                       if (log.isDebugEnabled()) {
-                               log.debug("Cannot read " + remoteUrl + ", skipping... " + e.getMessage());
-                               // log.trace("Cannot read because of ", e);
-                       }
-                       JcrUtils.discardQuietly(session);
-                       // } finally {
-                       // IOUtils.closeQuietly(in);
-               }
-               return node;
-       }
-
-       protected synchronized Node importFile(Session session, String path, InputStream in) throws RepositoryException {
-               Binary binary = null;
-               try {
-                       Node content = null;
-                       Node node = null;
-                       if (!session.itemExists(path)) {
-                               node = JcrUtils.mkdirs(session, path, NodeType.NT_FILE, NodeType.NT_FOLDER, false);
-                               content = node.addNode(Node.JCR_CONTENT, NodeType.NT_UNSTRUCTURED);
-                       } else {
-                               node = session.getNode(path);
-                               content = node.getNode(Node.JCR_CONTENT);
-                       }
-                       binary = session.getValueFactory().createBinary(in);
-                       content.setProperty(Property.JCR_DATA, binary);
-                       JcrUtils.updateLastModifiedAndParents(node, null, true);
-                       return node;
-               } finally {
-                       JcrUtils.closeQuietly(binary);
-               }
-       }
-
-       /** Whether the file should be updated. */
-       protected Boolean shouldUpdate(Session clientSession, String nodePath) {
-               return false;
-       }
-
-       public void setJcrRepository(Repository jcrRepository) {
-               this.jcrRepository = jcrRepository;
-       }
-
-       public void setProxyWorkspace(String localWorkspace) {
-               this.proxyWorkspace = localWorkspace;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxy.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxy.java
deleted file mode 100644 (file)
index 84eea1f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.argeo.jcr.proxy;
-
-import javax.jcr.Node;
-
-/** A proxy which nows how to resolve and synchronize relative URLs */
-public interface ResourceProxy {
-       /**
-        * Proxy the file referenced by this relative path in the underlying
-        * repository. A new session is created by each call, so the underlying
-        * session of the returned node must be closed by the caller.
-        * 
-        * @return the proxied Node, <code>null</code> if the resource was not found
-        *         (e.g. HTTP 404)
-        */
-       public Node proxy(String relativePath);
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java
deleted file mode 100644 (file)
index a8e00df..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-package org.argeo.jcr.proxy;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.argeo.jcr.JcrException;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.jcr.Bin;
-import org.argeo.jcr.JcrUtils;
-
-/** Wraps a proxy via HTTP */
-public class ResourceProxyServlet extends HttpServlet {
-       private static final long serialVersionUID = -8886549549223155801L;
-
-       private final static CmsLog log = CmsLog
-                       .getLog(ResourceProxyServlet.class);
-
-       private ResourceProxy proxy;
-
-       private String contentTypeCharset = "UTF-8";
-
-       @Override
-       protected void doGet(HttpServletRequest request,
-                       HttpServletResponse response) throws ServletException, IOException {
-               String path = request.getPathInfo();
-
-               if (log.isTraceEnabled()) {
-                       log.trace("path=" + path);
-                       log.trace("UserPrincipal = " + request.getUserPrincipal().getName());
-                       log.trace("SessionID = " + request.getSession(false).getId());
-                       log.trace("ContextPath = " + request.getContextPath());
-                       log.trace("ServletPath = " + request.getServletPath());
-                       log.trace("PathInfo = " + request.getPathInfo());
-                       log.trace("Method = " + request.getMethod());
-                       log.trace("User-Agent = " + request.getHeader("User-Agent"));
-               }
-
-               Node node = null;
-               try {
-                       node = proxy.proxy(path);
-                       if (node == null)
-                               response.sendError(404);
-                       else
-                               processResponse(node, response);
-               } finally {
-                       if (node != null)
-                               try {
-                                       JcrUtils.logoutQuietly(node.getSession());
-                               } catch (RepositoryException e) {
-                                       // silent
-                               }
-               }
-
-       }
-
-       /** Retrieve the content of the node. */
-       protected void processResponse(Node node, HttpServletResponse response) {
-//             Binary binary = null;
-//             InputStream in = null;
-               try(Bin binary = new Bin( node.getNode(Property.JCR_CONTENT)
-                               .getProperty(Property.JCR_DATA));InputStream in = binary.getStream()) {
-                       String fileName = node.getName();
-                       String ext = FilenameUtils.getExtension(fileName);
-
-                       // TODO use a more generic / standard approach
-                       // see http://svn.apache.org/viewvc/tomcat/trunk/conf/web.xml
-                       String contentType;
-                       if ("xml".equals(ext))
-                               contentType = "text/xml;charset=" + contentTypeCharset;
-                       else if ("jar".equals(ext))
-                               contentType = "application/java-archive";
-                       else if ("zip".equals(ext))
-                               contentType = "application/zip";
-                       else if ("gz".equals(ext))
-                               contentType = "application/x-gzip";
-                       else if ("bz2".equals(ext))
-                               contentType = "application/x-bzip2";
-                       else if ("tar".equals(ext))
-                               contentType = "application/x-tar";
-                       else if ("rpm".equals(ext))
-                               contentType = "application/x-redhat-package-manager";
-                       else
-                               contentType = "application/octet-stream";
-                       contentType = contentType + ";name=\"" + fileName + "\"";
-                       response.setHeader("Content-Disposition", "attachment; filename=\""
-                                       + fileName + "\"");
-                       response.setHeader("Expires", "0");
-                       response.setHeader("Cache-Control", "no-cache, must-revalidate");
-                       response.setHeader("Pragma", "no-cache");
-
-                       response.setContentType(contentType);
-
-                       IOUtils.copy(in, response.getOutputStream());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot download " + node, e);
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot download " + node, e);
-               }
-       }
-
-       public void setProxy(ResourceProxy resourceProxy) {
-               this.proxy = resourceProxy;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/package-info.java
deleted file mode 100644 (file)
index a578c45..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Components to build proxys based on JCR. */
-package org.argeo.jcr.proxy;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/xml/JcrXmlUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/xml/JcrXmlUtils.java
deleted file mode 100644 (file)
index 2adb6a9..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-package org.argeo.jcr.xml;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.jcr.Jcr;
-
-/** Utilities around JCR and XML. */
-public class JcrXmlUtils {
-       /**
-        * Convenience method calling {@link #toXmlElements(Writer, Node, boolean)} with
-        * <code>false</code>.
-        */
-       public static void toXmlElements(Writer writer, Node node) throws RepositoryException, IOException {
-               toXmlElements(writer, node, null, false, false, false);
-       }
-
-       /**
-        * Write JCR properties as XML elements in a tree structure whose elements are
-        * named by node primary type.
-        * 
-        * @param writer               the writer to use
-        * @param node                 the subtree
-        * @param depth                maximal depth, or if <code>null</code> the whole
-        *                             subtree. It must be positive, with depth 0
-        *                             describing just the node without its children.
-        * @param withMetadata         whether to write the primary type and mixins as
-        *                             elements
-        * @param withPrefix           whether to keep the namespace prefixes
-        * @param propertiesAsElements whether single properties should be written as
-        *                             elements rather than attributes. If
-        *                             <code>false</code>, multiple properties will be
-        *                             skipped.
-        */
-       public static void toXmlElements(Writer writer, Node node, Integer depth, boolean withMetadata, boolean withPrefix,
-                       boolean propertiesAsElements) throws RepositoryException, IOException {
-               if (depth != null && depth < 0)
-                       throw new IllegalArgumentException("Depth " + depth + " is negative.");
-
-               if (node.getName().equals(Jcr.JCR_XMLTEXT)) {
-                       writer.write(node.getProperty(Jcr.JCR_XMLCHARACTERS).getString());
-                       return;
-               }
-
-               if (!propertiesAsElements) {
-                       Map<String, String> attrs = new TreeMap<>();
-                       PropertyIterator pit = node.getProperties();
-                       properties: while (pit.hasNext()) {
-                               Property p = pit.nextProperty();
-                               if (!p.isMultiple()) {
-                                       String pName = p.getName();
-                                       if (!withMetadata && (pName.equals(Jcr.JCR_PRIMARY_TYPE) || pName.equals(Jcr.JCR_UUID)
-                                                       || pName.equals(Jcr.JCR_CREATED) || pName.equals(Jcr.JCR_CREATED_BY)
-                                                       || pName.equals(Jcr.JCR_LAST_MODIFIED) || pName.equals(Jcr.JCR_LAST_MODIFIED_BY)))
-                                               continue properties;
-                                       attrs.put(withPrefix(p.getName(), withPrefix), p.getString());
-                               }
-                       }
-                       if (withMetadata && node.hasProperty(Property.JCR_UUID))
-                               attrs.put("id", "urn:uuid:" + node.getProperty(Property.JCR_UUID).getString());
-                       attrs.put(withPrefix ? Jcr.JCR_NAME : "name", node.getName());
-                       writeStart(writer, withPrefix(node.getPrimaryNodeType().getName(), withPrefix), attrs, node.hasNodes());
-               } else {
-                       if (withMetadata && node.hasProperty(Property.JCR_UUID)) {
-                               writeStart(writer, withPrefix(node.getPrimaryNodeType().getName(), withPrefix), "id",
-                                               "urn:uuid:" + node.getProperty(Property.JCR_UUID).getString());
-                       } else {
-                               writeStart(writer, withPrefix(node.getPrimaryNodeType().getName(), withPrefix));
-                       }
-                       // name
-                       writeStart(writer, withPrefix ? Jcr.JCR_NAME : "name");
-                       writer.append(node.getName());
-                       writeEnd(writer, withPrefix ? Jcr.JCR_NAME : "name");
-               }
-
-               // mixins
-               if (withMetadata) {
-                       for (NodeType mixin : node.getMixinNodeTypes()) {
-                               writeStart(writer, withPrefix ? Jcr.JCR_MIXIN_TYPES : "mixinTypes");
-                               writer.append(mixin.getName());
-                               writeEnd(writer, withPrefix ? Jcr.JCR_MIXIN_TYPES : "mixinTypes");
-                       }
-               }
-
-               // properties as elements
-               if (propertiesAsElements) {
-                       PropertyIterator pit = node.getProperties();
-                       properties: while (pit.hasNext()) {
-                               Property p = pit.nextProperty();
-                               if (p.isMultiple()) {
-                                       for (Value value : p.getValues()) {
-                                               writeStart(writer, withPrefix(p.getName(), withPrefix));
-                                               writer.write(value.getString());
-                                               writeEnd(writer, withPrefix(p.getName(), withPrefix));
-                                       }
-                               } else {
-                                       Value value = p.getValue();
-                                       String pName = p.getName();
-                                       if (!withMetadata && (pName.equals(Jcr.JCR_PRIMARY_TYPE) || pName.equals(Jcr.JCR_UUID)
-                                                       || pName.equals(Jcr.JCR_CREATED) || pName.equals(Jcr.JCR_CREATED_BY)
-                                                       || pName.equals(Jcr.JCR_LAST_MODIFIED) || pName.equals(Jcr.JCR_LAST_MODIFIED_BY)))
-                                               continue properties;
-                                       writeStart(writer, withPrefix(p.getName(), withPrefix));
-                                       writer.write(value.getString());
-                                       writeEnd(writer, withPrefix(p.getName(), withPrefix));
-                               }
-                       }
-               }
-
-               // children
-               if (node.hasNodes()) {
-                       if (depth == null || depth > 0) {
-                               NodeIterator nit = node.getNodes();
-                               while (nit.hasNext()) {
-                                       toXmlElements(writer, nit.nextNode(), depth == null ? null : depth - 1, withMetadata, withPrefix,
-                                                       propertiesAsElements);
-                               }
-                       }
-                       writeEnd(writer, withPrefix(node.getPrimaryNodeType().getName(), withPrefix));
-               }
-       }
-
-       private static String withPrefix(String str, boolean withPrefix) {
-               if (withPrefix)
-                       return str;
-               int index = str.indexOf(':');
-               if (index < 0)
-                       return str;
-               return str.substring(index + 1);
-       }
-
-       private static void writeStart(Writer writer, String tagName) throws IOException {
-               writer.append('<');
-               writer.append(tagName);
-               writer.append('>');
-       }
-
-       private static void writeStart(Writer writer, String tagName, String attr, String value) throws IOException {
-               writer.append('<');
-               writer.append(tagName);
-               writer.append(' ');
-               writer.append(attr);
-               writer.append("=\"");
-               writer.append(value);
-               writer.append("\">");
-       }
-
-       private static void writeStart(Writer writer, String tagName, Map<String, String> attrs, boolean hasChildren)
-                       throws IOException {
-               writer.append('<');
-               writer.append(tagName);
-               for (String attr : attrs.keySet()) {
-                       writer.append(' ');
-                       writer.append(attr);
-                       writer.append("=\"");
-                       writer.append(attrs.get(attr));
-                       writer.append('\"');
-               }
-               if (hasChildren)
-                       writer.append('>');
-               else
-                       writer.append("/>");
-       }
-
-       private static void writeEnd(Writer writer, String tagName) throws IOException {
-               writer.append("</");
-               writer.append(tagName);
-               writer.append('>');
-       }
-
-       /** Singleton. */
-       private JcrXmlUtils() {
-
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/xml/removePrefixes.xsl b/jcr/org.argeo.cms.jcr/src/org/argeo/jcr/xml/removePrefixes.xsl
deleted file mode 100644 (file)
index 813d065..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-  <xsl:output method="xml" indent="yes"/>
-  <xsl:template match="/|comment()|processing-instruction()">
-    <xsl:copy>
-      <xsl:apply-templates/>
-    </xsl:copy>
-  </xsl:template>
-  <xsl:template match="*">
-    <xsl:element name="{local-name()}">
-      <xsl:apply-templates select="@*|node()"/>
-    </xsl:element>
-  </xsl:template>
-  <xsl:template match="@*">
-    <xsl:attribute name="{local-name()}">
-      <xsl:value-of select="."/>
-    </xsl:attribute>
-  </xsl:template>
-</xsl:stylesheet>
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java
deleted file mode 100644 (file)
index 977adac..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-package org.argeo.maintenance;
-
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.api.acr.spi.ProvidedRepository;
-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.util.naming.Distinguished;
-import org.argeo.util.transaction.WorkTransaction;
-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 CmsLog log = CmsLog.getLog(AbstractMaintenanceService.class);
-
-       private Repository repository;
-//     private UserAdminService userAdminService;
-       private UserAdmin userAdmin;
-       private WorkTransaction userTransaction;
-
-       private ProvidedRepository contentRepository;
-
-       public void init() {
-               makeSureRolesExists(getRequiredRoles());
-               configureStandardRoles();
-
-               Set<String> workspaceNames = getWorkspaceNames();
-               if (workspaceNames == null || workspaceNames.isEmpty()) {
-                       configureJcr(repository, null);
-               } else {
-                       for (String workspaceName : workspaceNames)
-                               configureJcr(repository, workspaceName);
-               }
-       }
-
-       /** Configures a workspace. */
-       protected void configureJcr(Repository repository, String workspaceName) {
-               Session adminSession;
-               try {
-                       adminSession = CmsJcrUtils.openDataAdminSession(repository, workspaceName);
-               } catch (RuntimeException e1) {
-                       if (e1.getCause() != null && e1.getCause() instanceof NoSuchWorkspaceException) {
-                               Session defaultAdminSession = CmsJcrUtils.openDataAdminSession(repository, null);
-                               try {
-                                       defaultAdminSession.getWorkspace().createWorkspace(workspaceName);
-                                       log.info("Created JCR workspace " + workspaceName);
-                               } catch (RepositoryException e) {
-                                       throw new IllegalStateException("Cannot create workspace " + workspaceName, e);
-                               } finally {
-                                       Jcr.logout(defaultAdminSession);
-                               }
-                               adminSession = CmsJcrUtils.openDataAdminSession(repository, workspaceName);
-                       } else
-                               throw e1;
-               }
-               try {
-                       if (prepareJcrTree(adminSession)) {
-                               configurePrivileges(adminSession);
-                       }
-               } catch (RepositoryException | IOException e) {
-                       throw new IllegalStateException("Cannot initialise JCR data layer.", e);
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-       }
-
-       /** To be overridden. */
-       protected Set<String> getWorkspaceNames() {
-               return null;
-       }
-
-       /**
-        * To be overridden in order to programmatically set relationships between
-        * roles. Does nothing by default.
-        */
-       protected void configureStandardRoles() {
-       }
-
-       /**
-        * Creates the base JCR tree structure expected for this app if necessary.
-        * 
-        * Expects a clean session ({@link Session#hasPendingChanges()} should return
-        * false) and saves it once the changes have been done. Thus the session can be
-        * rolled back if an exception occurs.
-        * 
-        * @return true if something as been updated
-        */
-       public boolean prepareJcrTree(Session adminSession) throws RepositoryException, IOException {
-               return false;
-       }
-
-       /**
-        * Adds app specific default privileges.
-        * 
-        * Expects a clean session ({@link Session#hasPendingChanges()} should return
-        * false} and saves it once the changes have been done. Thus the session can be
-        * rolled back if an exception occurs.
-        * 
-        * Warning: no check is done and corresponding privileges are always added, so
-        * only call this when necessary
-        */
-       public void configurePrivileges(Session session) throws RepositoryException {
-       }
-
-       /** The system roles that must be available in the system. */
-       protected Set<String> getRequiredRoles() {
-               return new HashSet<>();
-       }
-
-       public void destroy() {
-
-       }
-
-       /*
-        * UTILITIES
-        */
-
-       /** Create these roles as group if they don't exist. */
-       protected void makeSureRolesExists(EnumSet<? extends Distinguished> enumSet) {
-               makeSureRolesExists(Distinguished.enumToDns(enumSet));
-       }
-
-       /** Create these roles as group if they don't exist. */
-       protected void makeSureRolesExists(Set<String> requiredRoles) {
-               if (requiredRoles == null)
-                       return;
-               if (getUserAdmin() == null) {
-                       log.warn("No user admin service available, cannot make sure that role exists");
-                       return;
-               }
-               for (String role : requiredRoles) {
-                       Role systemRole = getUserAdmin().getRole(role);
-                       if (systemRole == null) {
-                               try {
-                                       getUserTransaction().begin();
-                                       getUserAdmin().createRole(role, Role.GROUP);
-                                       getUserTransaction().commit();
-                                       log.info("Created role " + role);
-                               } catch (Exception e) {
-                                       try {
-                                               getUserTransaction().rollback();
-                                       } catch (Exception e1) {
-                                               // silent
-                                       }
-                                       throw new IllegalStateException("Cannot create role " + role, e);
-                               }
-                       }
-               }
-       }
-
-       /** Add a user or group to a group. */
-       protected void addToGroup(String groupToAddDn, String groupDn) {
-               if (groupToAddDn.contentEquals(groupDn)) {
-                       if (log.isTraceEnabled())
-                               log.trace("Ignore adding group " + groupDn + " to itself");
-                       return;
-               }
-
-               if (getUserAdmin() == null) {
-                       log.warn("No user admin service available, cannot add group " + groupToAddDn + " to " + groupDn);
-                       return;
-               }
-               Group groupToAdd = (Group) getUserAdmin().getRole(groupToAddDn);
-               if (groupToAdd == null)
-                       throw new IllegalArgumentException("Group " + groupToAddDn + " not found");
-               Group group = (Group) getUserAdmin().getRole(groupDn);
-               if (group == null)
-                       throw new IllegalArgumentException("Group " + groupDn + " not found");
-               try {
-                       getUserTransaction().begin();
-                       if (group.addMember(groupToAdd))
-                               log.info("Added " + groupToAddDn + " to " + group);
-                       getUserTransaction().commit();
-               } catch (Exception e) {
-                       try {
-                               getUserTransaction().rollback();
-                       } catch (Exception e1) {
-                               // silent
-                       }
-                       throw new IllegalStateException("Cannot add " + groupToAddDn + " to " + groupDn);
-               }
-       }
-
-       /*
-        * DEPENDENCY INJECTION
-        */
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-//     public void setUserAdminService(UserAdminService userAdminService) {
-//             this.userAdminService = userAdminService;
-//     }
-
-       protected WorkTransaction getUserTransaction() {
-               return userTransaction;
-       }
-
-       protected UserAdmin getUserAdmin() {
-               return userAdmin;
-       }
-
-       public void setUserAdmin(UserAdmin userAdmin) {
-               this.userAdmin = userAdmin;
-       }
-
-       public void setUserTransaction(WorkTransaction userTransaction) {
-               this.userTransaction = userTransaction;
-       }
-
-       public void setContentRepository(ProvidedRepository contentRepository) {
-               this.contentRepository = contentRepository;
-       }
-
-       protected ProvidedRepository getContentRepository() {
-               return contentRepository;
-       }
-
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java
deleted file mode 100644 (file)
index e65e46a..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-package org.argeo.maintenance;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.util.transaction.WorkTransaction;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.UserAdmin;
-
-/**
- * Register one or many roles via a user admin service. Does nothing if the role
- * is already registered.
- */
-public class SimpleRoleRegistration implements Runnable {
-       private final static CmsLog log = CmsLog.getLog(SimpleRoleRegistration.class);
-
-       private String role;
-       private List<String> roles = new ArrayList<String>();
-       private UserAdmin userAdmin;
-       private WorkTransaction userTransaction;
-
-       @Override
-       public void run() {
-               try {
-                       userTransaction.begin();
-                       if (role != null && !roleExists(role))
-                               newRole(toDn(role));
-
-                       for (String r : roles)
-                               if (!roleExists(r))
-                                       newRole(toDn(r));
-                       userTransaction.commit();
-               } catch (Exception e) {
-                       try {
-                               userTransaction.rollback();
-                       } catch (Exception e1) {
-                               log.error("Cannot rollback", e1);
-                       }
-                       throw new IllegalArgumentException("Cannot add roles", e);
-               }
-       }
-
-       private boolean roleExists(String role) {
-               return userAdmin.getRole(toDn(role).toString()) != null;
-       }
-
-       protected void newRole(LdapName r) {
-               userAdmin.createRole(r.toString(), Role.GROUP);
-               log.info("Added role " + r + " required by application.");
-       }
-
-       public void register(UserAdmin userAdminService, Map<?, ?> properties) {
-               this.userAdmin = userAdminService;
-               run();
-       }
-
-       protected LdapName toDn(String name) {
-               try {
-                       return new LdapName("cn=" + name + ",ou=roles,ou=node");
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Badly formatted role name " + name, e);
-               }
-       }
-
-       public void setRole(String role) {
-               this.role = role;
-       }
-
-       public void setRoles(List<String> roles) {
-               this.roles = roles;
-       }
-
-       public void setUserAdmin(UserAdmin userAdminService) {
-               this.userAdmin = userAdminService;
-       }
-
-       public void setUserTransaction(WorkTransaction userTransaction) {
-               this.userTransaction = userTransaction;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/BackupContentHandler.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/BackupContentHandler.java
deleted file mode 100644 (file)
index ef83c1f..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-package org.argeo.maintenance.backup;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Writer;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.jcr.Jcr;
-import org.argeo.jcr.JcrException;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/** XML handler serialising a JCR system view. */
-public class BackupContentHandler extends DefaultHandler {
-       final static int MAX_DEPTH = 1024;
-       final static String SV_NAMESPACE_URI = "http://www.jcp.org/jcr/sv/1.0";
-       final static String SV_PREFIX = "sv";
-       // elements
-       final static String NODE = "node";
-       final static String PROPERTY = "property";
-       final static String VALUE = "value";
-       // attributes
-       final static String NAME = "name";
-       final static String MULTIPLE = "multiple";
-       final static String TYPE = "type";
-
-       // values
-       final static String BINARY = "Binary";
-       final static String JCR_CONTENT = "jcr:content";
-
-       private Writer out;
-       private Session session;
-       private Set<String> contentPaths = new TreeSet<>();
-
-       boolean prettyPrint = true;
-
-       private final String parentPath;
-
-//     private boolean inSystem = false;
-
-       public BackupContentHandler(Writer out, Node node) {
-               super();
-               this.out = out;
-               this.session = Jcr.getSession(node);
-               parentPath = Jcr.getParentPath(node);
-       }
-
-       private int currentDepth = -1;
-       private String[] currentPath = new String[MAX_DEPTH];
-
-       private boolean currentPropertyIsMultiple = false;
-       private String currentEncoded = null;
-       private Base64.Encoder base64encore = Base64.getEncoder();
-
-       @Override
-       public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-               boolean isNode;
-               boolean isProperty;
-               switch (localName) {
-               case NODE:
-                       isNode = true;
-                       isProperty = false;
-                       break;
-               case PROPERTY:
-                       isNode = false;
-                       isProperty = true;
-                       break;
-               default:
-                       isNode = false;
-                       isProperty = false;
-               }
-
-               if (isNode) {
-                       String nodeName = attributes.getValue(SV_NAMESPACE_URI, NAME);
-                       currentDepth = currentDepth + 1;
-//                     if (currentDepth >= 0)
-                       currentPath[currentDepth] = nodeName;
-//                     System.out.println(getCurrentPath() + " , depth=" + currentDepth);
-//                     if ("jcr:system".equals(nodeName)) {
-//                             inSystem = true;
-//                     }
-               }
-//             if (inSystem)
-//                     return;
-
-               if (SV_NAMESPACE_URI.equals(uri))
-                       try {
-                               if (prettyPrint) {
-                                       if (isNode) {
-                                               out.write(spaces());
-                                               out.write("<!-- ");
-                                               out.write(getCurrentJcrPath());
-                                               out.write(" -->\n");
-                                               out.write(spaces());
-                                       } else if (isProperty)
-                                               out.write(spaces());
-                                       else if (currentPropertyIsMultiple)
-                                               out.write(spaces());
-                               }
-
-                               out.write("<");
-                               out.write(SV_PREFIX + ":" + localName);
-                               if (isProperty)
-                                       currentPropertyIsMultiple = false; // always reset
-                               for (int i = 0; i < attributes.getLength(); i++) {
-                                       String ns = attributes.getURI(i);
-                                       if (SV_NAMESPACE_URI.equals(ns)) {
-                                               String attrName = attributes.getLocalName(i);
-                                               String attrValue = attributes.getValue(i);
-                                               out.write(" ");
-                                               out.write(SV_PREFIX + ":" + attrName);
-                                               out.write("=");
-                                               out.write("\"");
-                                               out.write(attrValue);
-                                               out.write("\"");
-                                               if (isProperty) {
-                                                       if (MULTIPLE.equals(attrName))
-                                                               currentPropertyIsMultiple = Boolean.parseBoolean(attrValue);
-                                                       else if (TYPE.equals(attrName)) {
-                                                               if (BINARY.equals(attrValue)) {
-                                                                       if (JCR_CONTENT.equals(getCurrentName())) {
-                                                                               contentPaths.add(getCurrentJcrPath());
-                                                                       } else {
-                                                                               Binary binary = session.getNode(getCurrentJcrPath()).getProperty(attrName)
-                                                                                               .getBinary();
-                                                                               try (InputStream in = binary.getStream()) {
-                                                                                       currentEncoded = base64encore.encodeToString(IOUtils.toByteArray(in));
-                                                                               } finally {
-
-                                                                               }
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                               if (isNode && currentDepth == 0) {
-                                       // out.write(" xmlns=\"" + SV_NAMESPACE_URI + "\"");
-                                       out.write(" xmlns:" + SV_PREFIX + "=\"" + SV_NAMESPACE_URI + "\"");
-                               }
-                               out.write(">");
-
-                               if (prettyPrint)
-                                       if (isNode)
-                                               out.write("\n");
-                                       else if (isProperty && currentPropertyIsMultiple)
-                                               out.write("\n");
-                       } catch (IOException e) {
-                               throw new RuntimeException(e);
-                       } catch (RepositoryException e) {
-                               throw new JcrException(e);
-                       }
-       }
-
-       @Override
-       public void endElement(String uri, String localName, String qName) throws SAXException {
-               boolean isNode = localName.equals(NODE);
-               boolean isValue = localName.equals(VALUE);
-               if (prettyPrint)
-                       if (!isValue)
-                               try {
-                                       if (isNode || currentPropertyIsMultiple)
-                                               out.write(spaces());
-                               } catch (IOException e1) {
-                                       throw new RuntimeException(e1);
-                               }
-               if (isNode) {
-//                     System.out.println("endElement " + getCurrentPath() + " , depth=" + currentDepth);
-//                     if (currentDepth > 0)
-                       currentPath[currentDepth] = null;
-                       currentDepth = currentDepth - 1;
-//                     if (inSystem) {
-//                             // System.out.println("Skip " + getCurrentPath()+" ,
-//                             // currentDepth="+currentDepth);
-//                             if (currentDepth == 0) {
-//                                     inSystem = false;
-//                                     return;
-//                             }
-//                     }
-               }
-//             if (inSystem)
-//                     return;
-               if (SV_NAMESPACE_URI.equals(uri))
-                       try {
-                               if (isValue && currentEncoded != null) {
-                                       out.write(currentEncoded);
-                               }
-                               currentEncoded = null;
-                               out.write("</");
-                               out.write(SV_PREFIX + ":" + localName);
-                               out.write(">");
-                               if (prettyPrint)
-                                       if (!isValue)
-                                               out.write("\n");
-                                       else {
-                                               if (currentPropertyIsMultiple)
-                                                       out.write("\n");
-                                       }
-                               if (currentDepth == 0)
-                                       out.flush();
-                       } catch (IOException e) {
-                               throw new RuntimeException(e);
-                       }
-
-       }
-
-       private char[] spaces() {
-               char[] arr = new char[currentDepth];
-               Arrays.fill(arr, ' ');
-               return arr;
-       }
-
-       @Override
-       public void characters(char[] ch, int start, int length) throws SAXException {
-//             if (inSystem)
-//                     return;
-               try {
-                       out.write(ch, start, length);
-               } catch (IOException e) {
-                       throw new RuntimeException(e);
-               }
-       }
-
-       protected String getCurrentName() {
-               assert currentDepth >= 0;
-//             if (currentDepth == 0)
-//                     return "jcr:root";
-               return currentPath[currentDepth];
-       }
-
-       protected String getCurrentJcrPath() {
-//             if (currentDepth == 0)
-//                     return "/";
-               StringBuilder sb = new StringBuilder(parentPath.equals("/") ? "" : parentPath);
-               for (int i = 0; i <= currentDepth; i++) {
-//                     if (i != 0)
-                       sb.append('/');
-                       sb.append(currentPath[i]);
-               }
-               return sb.toString();
-       }
-
-       public Set<String> getContentPaths() {
-               return contentPaths;
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java
deleted file mode 100644 (file)
index 00d4be8..0000000
+++ /dev/null
@@ -1,448 +0,0 @@
-package org.argeo.maintenance.backup;
-
-import java.io.BufferedWriter;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.net.URI;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipOutputStream;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.JackrabbitValue;
-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;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-/**
- * Performs a backup of the data based only on programmatic interfaces. Useful
- * for migration or live backup. Physical backups of the underlying file
- * systems, databases, LDAP servers, etc. should be performed for disaster
- * recovery.
- */
-public class LogicalBackup implements Runnable {
-       private final static CmsLog log = CmsLog.getLog(LogicalBackup.class);
-
-       public final static String WORKSPACES_BASE = "workspaces/";
-       public final static String FILES_BASE = "files/";
-       public final static String OSGI_BASE = "share/osgi/";
-
-       public final static String JCR_SYSTEM = "jcr:system";
-       public final static String JCR_VERSION_STORAGE_PATH = "/jcr:system/jcr:versionStorage";
-
-       private final Repository repository;
-       private String defaultWorkspace;
-       private final BundleContext bundleContext;
-
-       private final ZipOutputStream zout;
-       private final Path basePath;
-
-       private ExecutorService executorService;
-
-       private boolean performSoftwareBackup = false;
-
-       private Map<String, String> checksums = new TreeMap<>();
-
-       private int threadCount = 5;
-
-       private boolean backupFailed = false;
-
-       public LogicalBackup(BundleContext bundleContext, Repository repository, Path basePath) {
-               this.repository = repository;
-               this.zout = null;
-               this.basePath = basePath;
-               this.bundleContext = bundleContext;
-       }
-
-       @Override
-       public void run() {
-               try {
-                       log.info("Start logical backup to " + basePath);
-                       perform();
-               } catch (Exception e) {
-                       log.error("Unexpected exception when performing logical backup", e);
-                       throw new IllegalStateException("Logical backup failed", e);
-               }
-
-       }
-
-       public void perform() throws RepositoryException, IOException {
-               if (executorService != null && !executorService.isTerminated())
-                       throw new IllegalStateException("Another backup is running");
-               executorService = Executors.newFixedThreadPool(threadCount);
-               long begin = System.currentTimeMillis();
-               // software backup
-               if (bundleContext != null && performSoftwareBackup)
-                       executorService.submit(() -> performSoftwareBackup(bundleContext));
-
-               // data backup
-               Session defaultSession = login(null);
-               defaultWorkspace = defaultSession.getWorkspace().getName();
-               try {
-                       String[] workspaceNames = defaultSession.getWorkspace().getAccessibleWorkspaceNames();
-                       workspaces: for (String workspaceName : workspaceNames) {
-                               if ("security".equals(workspaceName))
-                                       continue workspaces;
-                               performDataBackup(workspaceName);
-                       }
-               } finally {
-                       JcrUtils.logoutQuietly(defaultSession);
-                       executorService.shutdown();
-                       try {
-                               executorService.awaitTermination(24, TimeUnit.HOURS);
-                       } catch (InterruptedException e) {
-                               // silent
-                               throw new IllegalStateException("Backup was interrupted before completion", e);
-                       }
-               }
-               // versions
-               executorService = Executors.newFixedThreadPool(threadCount);
-               try {
-                       performVersionsBackup();
-               } finally {
-                       executorService.shutdown();
-                       try {
-                               executorService.awaitTermination(24, TimeUnit.HOURS);
-                       } catch (InterruptedException e) {
-                               // silent
-                               throw new IllegalStateException("Backup was interrupted before completion", e);
-                       }
-               }
-               long duration = System.currentTimeMillis() - begin;
-               if (isBackupFailed())
-                       log.info("System logical backup failed after " + (duration / 60000) + "min " + (duration / 1000) + "s");
-               else
-                       log.info("System logical backup completed in " + (duration / 60000) + "min " + (duration / 1000) + "s");
-       }
-
-       protected void performDataBackup(String workspaceName) throws RepositoryException, IOException {
-               Session session = login(workspaceName);
-               try {
-                       nodes: for (NodeIterator nit = session.getRootNode().getNodes(); nit.hasNext();) {
-                               if (isBackupFailed())
-                                       return;
-                               Node nodeToExport = nit.nextNode();
-                               if (JCR_SYSTEM.equals(nodeToExport.getName()))
-                                       continue nodes;
-                               String nodePath = nodeToExport.getPath();
-                               Future<Set<String>> contentPathsFuture = executorService
-                                               .submit(() -> performNodeBackup(workspaceName, nodePath));
-                               executorService.submit(() -> performFilesBackup(workspaceName, contentPathsFuture));
-                       }
-               } finally {
-                       Jcr.logout(session);
-               }
-       }
-
-       protected void performVersionsBackup() throws RepositoryException, IOException {
-               Session session = login(defaultWorkspace);
-               Node versionStorageNode = session.getNode(JCR_VERSION_STORAGE_PATH);
-               try {
-                       for (NodeIterator nit = versionStorageNode.getNodes(); nit.hasNext();) {
-                               Node nodeToExport = nit.nextNode();
-                               String nodePath = nodeToExport.getPath();
-                               if (isBackupFailed())
-                                       return;
-                               Future<Set<String>> contentPathsFuture = executorService
-                                               .submit(() -> performNodeBackup(defaultWorkspace, nodePath));
-                               executorService.submit(() -> performFilesBackup(defaultWorkspace, contentPathsFuture));
-                       }
-               } finally {
-                       Jcr.logout(session);
-               }
-
-       }
-
-       protected Set<String> performNodeBackup(String workspaceName, String nodePath) {
-               Session session = login(workspaceName);
-               try {
-                       Node nodeToExport = session.getNode(nodePath);
-//                     String nodeName = nodeToExport.getName();
-//             if (nodeName.startsWith("jcr:") || nodeName.startsWith("rep:"))
-//                     continue nodes;
-//             // TODO make it more robust / configurable
-//             if (nodeName.equals("user"))
-//                     continue nodes;
-                       String relativePath = WORKSPACES_BASE + workspaceName + nodePath + ".xml";
-                       OutputStream xmlOut = openOutputStream(relativePath);
-                       BackupContentHandler contentHandler;
-                       try (Writer writer = new BufferedWriter(new OutputStreamWriter(xmlOut, StandardCharsets.UTF_8))) {
-                               contentHandler = new BackupContentHandler(writer, nodeToExport);
-                               session.exportSystemView(nodeToExport.getPath(), contentHandler, true, false);
-                               if (log.isDebugEnabled())
-                                       log.debug(workspaceName + ":" + nodePath + " metadata exported to " + relativePath);
-                       }
-
-                       // Files
-                       Set<String> contentPaths = contentHandler.getContentPaths();
-                       return contentPaths;
-               } catch (Exception e) {
-                       markBackupFailed("Cannot backup node " + workspaceName + ":" + nodePath, e);
-                       throw new ThreadDeath();
-               } finally {
-                       Jcr.logout(session);
-               }
-       }
-
-       protected void performFilesBackup(String workspaceName, Future<Set<String>> contentPathsFuture) {
-               Set<String> contentPaths;
-               try {
-                       contentPaths = contentPathsFuture.get(24, TimeUnit.HOURS);
-               } catch (InterruptedException | ExecutionException | TimeoutException e1) {
-                       markBackupFailed("Cannot retrieve content paths for workspace " + workspaceName, e1);
-                       return;
-               }
-               if (contentPaths == null || contentPaths.size() == 0)
-                       return;
-               Session session = login(workspaceName);
-               try {
-                       String workspacesFilesBasePath = FILES_BASE + workspaceName;
-                       for (String path : contentPaths) {
-                               if (isBackupFailed())
-                                       return;
-                               Node contentNode = session.getNode(path);
-                               Binary binary = null;
-                               try {
-                                       binary = contentNode.getProperty(Property.JCR_DATA).getBinary();
-                                       String fileRelativePath = workspacesFilesBasePath + contentNode.getParent().getPath();
-
-                                       // checksum
-                                       boolean skip = false;
-                                       String checksum = null;
-                                       if (session instanceof JackrabbitSession) {
-                                               JackrabbitValue value = (JackrabbitValue) contentNode.getProperty(Property.JCR_DATA).getValue();
-//                                     ReferenceBinary referenceBinary = (ReferenceBinary) binary;
-                                               checksum = value.getContentIdentity();
-                                       }
-                                       if (checksum != null) {
-                                               if (!checksums.containsKey(checksum)) {
-                                                       checksums.put(checksum, fileRelativePath);
-                                               } else {
-                                                       skip = true;
-                                                       String sourcePath = checksums.get(checksum);
-                                                       if (log.isTraceEnabled())
-                                                               log.trace(fileRelativePath + " : already " + sourcePath + " with checksum " + checksum);
-                                                       createLink(sourcePath, fileRelativePath);
-                                                       try (Writer writerSum = new OutputStreamWriter(
-                                                                       openOutputStream(fileRelativePath + ".sha256"), StandardCharsets.UTF_8)) {
-                                                               writerSum.write(checksum);
-                                                       }
-                                               }
-                                       }
-
-                                       // copy file
-                                       if (!skip)
-                                               try (InputStream in = binary.getStream();
-                                                               OutputStream out = openOutputStream(fileRelativePath)) {
-                                                       IOUtils.copy(in, out);
-                                                       if (log.isTraceEnabled())
-                                                               log.trace("Workspace " + workspaceName + ": file content exported to "
-                                                                               + fileRelativePath);
-                                               }
-                               } finally {
-                                       JcrUtils.closeQuietly(binary);
-                               }
-                       }
-                       if (log.isDebugEnabled())
-                               log.debug(workspaceName + ":" + contentPaths.size() + " files exported to " + workspacesFilesBasePath);
-               } catch (Exception e) {
-                       markBackupFailed("Cannot backup files from " + workspaceName + ":", e);
-               } finally {
-                       Jcr.logout(session);
-               }
-       }
-
-       protected OutputStream openOutputStream(String relativePath) throws IOException {
-               if (zout != null) {
-                       ZipEntry entry = new ZipEntry(relativePath);
-                       zout.putNextEntry(entry);
-                       return zout;
-               } else if (basePath != null) {
-                       Path targetPath = basePath.resolve(Paths.get(relativePath));
-                       Files.createDirectories(targetPath.getParent());
-                       return Files.newOutputStream(targetPath);
-               } else {
-                       throw new UnsupportedOperationException();
-               }
-       }
-
-       protected void createLink(String source, String target) throws IOException {
-               if (zout != null) {
-                       // TODO implement for zip
-                       throw new UnsupportedOperationException();
-               } else if (basePath != null) {
-                       Path sourcePath = basePath.resolve(Paths.get(source));
-                       Path targetPath = basePath.resolve(Paths.get(target));
-                       Path relativeSource = targetPath.getParent().relativize(sourcePath);
-                       Files.createDirectories(targetPath.getParent());
-                       Files.createSymbolicLink(targetPath, relativeSource);
-               } else {
-                       throw new UnsupportedOperationException();
-               }
-       }
-
-       protected void closeOutputStream(String relativePath, OutputStream out) throws IOException {
-               if (zout != null) {
-                       zout.closeEntry();
-               } else if (basePath != null) {
-                       out.close();
-               } else {
-                       throw new UnsupportedOperationException();
-               }
-       }
-
-       protected Session login(String workspaceName) {
-               if (bundleContext != null) {// local
-                       return CmsJcrUtils.openDataAdminSession(repository, workspaceName);
-               } else {// remote
-                       try {
-                               return repository.login(workspaceName);
-                       } catch (RepositoryException e) {
-                               throw new JcrException(e);
-                       }
-               }
-       }
-
-       public final static void main(String[] args) throws Exception {
-               if (args.length == 0) {
-                       printUsage("No argument");
-                       System.exit(1);
-               }
-               URI uri = new URI(args[0]);
-               Repository repository = createRemoteRepository(uri);
-               Path basePath = args.length > 1 ? Paths.get(args[1]) : Paths.get(System.getProperty("user.dir"));
-               if (!Files.exists(basePath))
-                       Files.createDirectories(basePath);
-               LogicalBackup backup = new LogicalBackup(null, repository, basePath);
-               backup.run();
-       }
-
-       private static void printUsage(String errorMessage) {
-               if (errorMessage != null)
-                       System.err.println(errorMessage);
-               System.out.println("Usage: LogicalBackup <remote URL> [<target directory>]");
-
-       }
-
-       protected static Repository createRemoteRepository(URI uri) throws RepositoryException {
-               RepositoryFactory repositoryFactory = new ClientDavexRepositoryFactory();
-               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, CmsConstants.SYS_WORKSPACE);
-               return repositoryFactory.getRepository(params);
-       }
-
-       public void performSoftwareBackup(BundleContext bundleContext) {
-               String bootBasePath = OSGI_BASE + "boot";
-               Bundle[] bundles = bundleContext.getBundles();
-               for (Bundle bundle : bundles) {
-                       String relativePath = bootBasePath + "/" + bundle.getSymbolicName() + ".jar";
-                       Dictionary<String, String> headers = bundle.getHeaders();
-                       Manifest manifest = new Manifest();
-                       Enumeration<String> headerKeys = headers.keys();
-                       while (headerKeys.hasMoreElements()) {
-                               String headerKey = headerKeys.nextElement();
-                               String headerValue = headers.get(headerKey);
-                               manifest.getMainAttributes().putValue(headerKey, headerValue);
-                       }
-                       try (JarOutputStream jarOut = new JarOutputStream(openOutputStream(relativePath), manifest)) {
-                               Enumeration<URL> resourcePaths = bundle.findEntries("/", "*", true);
-                               resources: while (resourcePaths.hasMoreElements()) {
-                                       URL entryUrl = resourcePaths.nextElement();
-                                       String entryPath = entryUrl.getPath();
-                                       if (entryPath.equals(""))
-                                               continue resources;
-                                       if (entryPath.endsWith("/"))
-                                               continue resources;
-                                       String entryName = entryPath.substring(1);// remove first '/'
-                                       if (entryUrl.getPath().equals("/META-INF/"))
-                                               continue resources;
-                                       if (entryUrl.getPath().equals("/META-INF/MANIFEST.MF"))
-                                               continue resources;
-                                       // dev
-                                       if (entryUrl.getPath().startsWith("/target"))
-                                               continue resources;
-                                       if (entryUrl.getPath().startsWith("/src"))
-                                               continue resources;
-                                       if (entryUrl.getPath().startsWith("/ext"))
-                                               continue resources;
-
-                                       if (entryName.startsWith("bin/")) {// dev
-                                               entryName = entryName.substring("bin/".length());
-                                       }
-
-                                       ZipEntry entry = new ZipEntry(entryName);
-                                       try (InputStream in = entryUrl.openStream()) {
-                                               try {
-                                                       jarOut.putNextEntry(entry);
-                                               } catch (ZipException e) {// duplicate
-                                                       continue resources;
-                                               }
-                                               IOUtils.copy(in, jarOut);
-                                               jarOut.closeEntry();
-//                                             log.info(entryUrl);
-                                       } catch (FileNotFoundException e) {
-                                               log.warn(entryUrl + ": " + e.getMessage());
-                                       }
-                               }
-                       } catch (IOException e1) {
-                               throw new RuntimeException("Cannot export bundle " + bundle, e1);
-                       }
-               }
-               if (log.isDebugEnabled())
-                       log.debug(bundles.length + " OSGi bundles exported to " + bootBasePath);
-
-       }
-
-       protected synchronized void markBackupFailed(Object message, Exception e) {
-               log.error(message, e);
-               backupFailed = true;
-               notifyAll();
-               if (executorService != null)
-                       executorService.shutdownNow();
-       }
-
-       protected boolean isBackupFailed() {
-               return backupFailed;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java
deleted file mode 100644 (file)
index 122c967..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.argeo.maintenance.backup;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import javax.jcr.ImportUUIDBehavior;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-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;
-import org.argeo.jcr.JcrUtils;
-import org.osgi.framework.BundleContext;
-
-/** Restores a backup in the format defined by {@link LogicalBackup}. */
-public class LogicalRestore implements Runnable {
-       private final static CmsLog log = CmsLog.getLog(LogicalRestore.class);
-
-       private final Repository repository;
-       private final BundleContext bundleContext;
-       private final Path basePath;
-
-       public LogicalRestore(BundleContext bundleContext, Repository repository, Path basePath) {
-               this.repository = repository;
-               this.basePath = basePath;
-               this.bundleContext = bundleContext;
-       }
-
-       @Override
-       public void run() {
-               Path workspaces = basePath.resolve(LogicalBackup.WORKSPACES_BASE);
-               try {
-                       // import jcr:system first
-//                     Session defaultSession = NodeUtils.openDataAdminSession(repository, null);
-//                     try (DirectoryStream<Path> xmls = Files.newDirectoryStream(
-//                                     workspaces.resolve(NodeConstants.SYS_WORKSPACE + LogicalBackup.JCR_VERSION_STORAGE_PATH),
-//                                     "*.xml")) {
-//                             for (Path xml : xmls) {
-//                                     try (InputStream in = Files.newInputStream(xml)) {
-//                                             defaultSession.getWorkspace().importXML(LogicalBackup.JCR_VERSION_STORAGE_PATH, in,
-//                                                             ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
-//                                             if (log.isDebugEnabled())
-//                                                     log.debug("Restored " + xml + " to " + defaultSession.getWorkspace().getName() + ":");
-//                                     }
-//                             }
-//                     } finally {
-//                             Jcr.logout(defaultSession);
-//                     }
-
-                       // non-system content
-                       try (DirectoryStream<Path> workspaceDirs = Files.newDirectoryStream(workspaces)) {
-                               for (Path workspacePath : workspaceDirs) {
-                                       String workspaceName = workspacePath.getFileName().toString();
-                                       Session session = JcrUtils.loginOrCreateWorkspace(repository, workspaceName);
-                                       try (DirectoryStream<Path> xmls = Files.newDirectoryStream(workspacePath, "*.xml")) {
-                                               xmls: for (Path xml : xmls) {
-                                                       if (xml.getFileName().toString().startsWith("rep:"))
-                                                               continue xmls;
-                                                       try (InputStream in = Files.newInputStream(xml)) {
-                                                               session.getWorkspace().importXML("/", in,
-                                                                               ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
-                                                               if (log.isDebugEnabled())
-                                                                       log.debug("Restored " + xml + " to workspace " + workspaceName);
-                                                       }
-                                               }
-                                       } finally {
-                                               Jcr.logout(session);
-                                       }
-                               }
-                       }
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot restore backup from " + basePath, e);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot restore backup from " + basePath, e);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/package-info.java
deleted file mode 100644 (file)
index a61e19b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Argeo Node backup utilities. */
-package org.argeo.maintenance.backup;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/internal/Activator.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/internal/Activator.java
deleted file mode 100644 (file)
index ef40ab3..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.argeo.maintenance.internal;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import javax.jcr.Repository;
-
-import org.argeo.maintenance.backup.LogicalBackup;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class Activator implements BundleActivator {
-
-       @Override
-       public void start(BundleContext context) throws Exception {
-               // Start backup
-               Repository repository = context.getService(context.getServiceReference(Repository.class));
-               Path basePath = Paths.get(System.getProperty("user.dir"), "backup");
-               LogicalBackup backup = new LogicalBackup(context, repository, basePath);
-               backup.run();
-       }
-
-       @Override
-       public void stop(BundleContext context) throws Exception {
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/maintenance/package-info.java
deleted file mode 100644 (file)
index 1ce974c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Utilities for the maintenance of an Argeo Node. */
-package org.argeo.maintenance;
\ No newline at end of file
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAccessControlProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAccessControlProvider.java
deleted file mode 100644 (file)
index bffe531..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.argeo.security.jackrabbit;
-
-import java.security.Principal;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.jackrabbit.core.security.authorization.acl.ACLProvider;
-
-/** Argeo specific access control provider */
-public class ArgeoAccessControlProvider extends ACLProvider {
-
-       @SuppressWarnings({ "rawtypes", "unchecked" })
-       @Override
-       public void init(Session systemSession, Map configuration) throws RepositoryException {
-               if (!configuration.containsKey(PARAM_ALLOW_UNKNOWN_PRINCIPALS))
-                       configuration.put(PARAM_ALLOW_UNKNOWN_PRINCIPALS, "true");
-               if (!configuration.containsKey(PARAM_OMIT_DEFAULT_PERMISSIONS))
-                       configuration.put(PARAM_OMIT_DEFAULT_PERMISSIONS, "true");
-               super.init(systemSession, configuration);
-       }
-
-       @Override
-       public boolean canAccessRoot(Set<Principal> principals) throws RepositoryException {
-               return super.canAccessRoot(principals);
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAccessManager.java b/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAccessManager.java
deleted file mode 100644 (file)
index 7464078..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.argeo.security.jackrabbit;
-
-import javax.jcr.PathNotFoundException;
-import javax.jcr.RepositoryException;
-import javax.jcr.security.Privilege;
-
-import org.apache.jackrabbit.core.id.ItemId;
-import org.apache.jackrabbit.core.security.DefaultAccessManager;
-import org.apache.jackrabbit.spi.Path;
-
-/**
- * Intermediary class in order to have a consistent naming in config files. Does
- * nothing for the time being, but may in the future.
- */
-public class ArgeoAccessManager extends DefaultAccessManager {
-
-       @Override
-       public boolean canRead(Path itemPath, ItemId itemId)
-                       throws RepositoryException {
-               return super.canRead(itemPath, itemId);
-       }
-
-       @Override
-       public Privilege[] getPrivileges(String absPath)
-                       throws PathNotFoundException, RepositoryException {
-               return super.getPrivileges(absPath);
-       }
-
-       @Override
-       public boolean hasPrivileges(String absPath, Privilege[] privileges)
-                       throws PathNotFoundException, RepositoryException {
-               return super.hasPrivileges(absPath, privileges);
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAuthContext.java b/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoAuthContext.java
deleted file mode 100644 (file)
index d679c45..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.argeo.security.jackrabbit;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-import org.apache.jackrabbit.core.security.authentication.AuthContext;
-
-/** Wraps a regular {@link LoginContext}, using the proper class loader. */
-class ArgeoAuthContext implements AuthContext {
-       private LoginContext lc;
-
-       public ArgeoAuthContext(String appName, Subject subject, CallbackHandler callbackHandler) {
-               try {
-                       lc = new LoginContext(appName, subject, callbackHandler);
-               } catch (LoginException e) {
-                       throw new IllegalStateException("Cannot configure Jackrabbit login context", e);
-               }
-       }
-
-       @Override
-       public void login() throws LoginException {
-               lc.login();
-       }
-
-       @Override
-       public Subject getSubject() {
-               return lc.getSubject();
-       }
-
-       @Override
-       public void logout() throws LoginException {
-               lc.logout();
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java b/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
deleted file mode 100644 (file)
index 97acf66..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-package org.argeo.security.jackrabbit;
-
-import java.security.Principal;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.jcr.Credentials;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.x500.X500Principal;
-
-import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.core.DefaultSecurityManager;
-import org.apache.jackrabbit.core.security.AMContext;
-import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.core.security.SecurityConstants;
-import org.apache.jackrabbit.core.security.SystemPrincipal;
-import org.apache.jackrabbit.core.security.authentication.AuthContext;
-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.cms.AnonymousPrincipal;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.DataAdminPrincipal;
-
-/** Customises Jackrabbit security. */
-public class ArgeoSecurityManager extends DefaultSecurityManager {
-       private final static CmsLog log = CmsLog.getLog(ArgeoSecurityManager.class);
-
-//     private BundleContext cmsBundleContext = null;
-
-       public ArgeoSecurityManager() {
-//             if (FrameworkUtil.getBundle(CmsSession.class) != null) {
-//                     cmsBundleContext = FrameworkUtil.getBundle(CmsSession.class).getBundleContext();
-//             }
-       }
-
-       public AuthContext getAuthContext(Credentials creds, Subject subject, String workspaceName)
-                       throws RepositoryException {
-               checkInitialized();
-
-               CallbackHandler cbHandler = new CallbackHandlerImpl(creds, getSystemSession(), getPrincipalProviderRegistry(),
-                               adminId, anonymousId);
-               String appName = "Jackrabbit";
-               return new ArgeoAuthContext(appName, subject, cbHandler);
-       }
-
-       @Override
-       public AccessManager getAccessManager(Session session, AMContext amContext) throws RepositoryException {
-               synchronized (getSystemSession()) {
-                       return super.getAccessManager(session, amContext);
-               }
-       }
-
-       @Override
-       public UserManager getUserManager(Session session) throws RepositoryException {
-               synchronized (getSystemSession()) {
-                       return super.getUserManager(session);
-               }
-       }
-
-       @Override
-       protected PrincipalProvider createDefaultPrincipalProvider(Properties[] moduleConfig) throws RepositoryException {
-               return super.createDefaultPrincipalProvider(moduleConfig);
-       }
-
-       /** Called once when the session is created */
-       @Override
-       public String getUserID(Subject subject, String workspaceName) throws RepositoryException {
-               boolean isAnonymous = !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
-               boolean isDataAdmin = !subject.getPrincipals(DataAdminPrincipal.class).isEmpty();
-               boolean isJackrabbitSystem = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
-               Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
-               boolean isRegularUser = !userPrincipal.isEmpty();
-//             CmsSession cmsSession = null;
-//             if (cmsBundleContext != null) {
-//                     cmsSession = CmsOsgiUtils.getCmsSession(cmsBundleContext, subject);
-//                     if (log.isTraceEnabled())
-//                             log.trace("Opening JCR session for CMS session " + cmsSession);
-//             }
-
-               if (isAnonymous) {
-                       if (isDataAdmin || isJackrabbitSystem || isRegularUser)
-                               throw new IllegalStateException("Inconsistent " + subject);
-                       else
-                               return CmsConstants.ROLE_ANONYMOUS;
-               } else if (isRegularUser) {// must be before DataAdmin
-                       if (isAnonymous || isJackrabbitSystem)
-                               throw new IllegalStateException("Inconsistent " + subject);
-                       else {
-                               if (userPrincipal.size() > 1) {
-                                       StringBuilder buf = new StringBuilder();
-                                       for (X500Principal principal : userPrincipal)
-                                               buf.append(' ').append('\"').append(principal).append('\"');
-                                       throw new RuntimeException("Multiple user principals:" + buf);
-                               }
-                               return userPrincipal.iterator().next().getName();
-                       }
-               } else if (isDataAdmin) {
-                       if (isAnonymous || isJackrabbitSystem || isRegularUser)
-                               throw new IllegalStateException("Inconsistent " + subject);
-                       else {
-                               assert !subject.getPrincipals(AdminPrincipal.class).isEmpty();
-                               return CmsConstants.ROLE_DATA_ADMIN;
-                       }
-               } else if (isJackrabbitSystem) {
-                       if (isAnonymous || isDataAdmin || isRegularUser)
-                               throw new IllegalStateException("Inconsistent " + subject);
-                       else
-                               return super.getUserID(subject, workspaceName);
-               } else {
-                       throw new IllegalStateException("Unrecognized subject type: " + subject);
-               }
-       }
-
-       @Override
-       protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
-               WorkspaceAccessManager wam = super.createDefaultWorkspaceAccessManager();
-               ArgeoWorkspaceAccessManagerImpl workspaceAccessManager = new ArgeoWorkspaceAccessManagerImpl(wam);
-               if (log.isTraceEnabled())
-                       log.trace("Created workspace access manager");
-               return workspaceAccessManager;
-       }
-
-       private class ArgeoWorkspaceAccessManagerImpl implements SecurityConstants, WorkspaceAccessManager {
-               private final WorkspaceAccessManager wam;
-
-               public ArgeoWorkspaceAccessManagerImpl(WorkspaceAccessManager wam) {
-                       super();
-                       this.wam = wam;
-               }
-
-               public void init(Session systemSession) throws RepositoryException {
-                       wam.init(systemSession);
-                       Repository repository = systemSession.getRepository();
-                       if (log.isTraceEnabled())
-                               log.trace("Initialised workspace access manager on repository " + repository
-                                               + ", systemSession workspace: " + systemSession.getWorkspace().getName());
-               }
-
-               public void close() throws RepositoryException {
-               }
-
-               public boolean grants(Set<Principal> principals, String workspaceName) throws RepositoryException {
-                       // TODO: implements finer access to workspaces
-                       if (log.isTraceEnabled())
-                               log.trace("Grants " + new HashSet<>(principals) + " access to workspace '" + workspaceName + "'");
-                       return true;
-                       // return wam.grants(principals, workspaceName);
-               }
-       }
-
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java b/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java
deleted file mode 100644 (file)
index 0f63957..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.argeo.security.jackrabbit;
-
-import java.util.Map;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-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.cms.DataAdminPrincipal;
-
-/** JAAS login module used when initiating a new Jackrabbit session. */
-public class SystemJackrabbitLoginModule 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 {
-               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;
-               }
-
-               Set<DataAdminPrincipal> initPrincipal = subject.getPrincipals(DataAdminPrincipal.class);
-               if (!initPrincipal.isEmpty()) {
-                       subject.getPrincipals().add(new AdminPrincipal(SecurityConstants.ADMIN_ID));
-                       return true;
-               }
-
-               Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
-               if (userPrincipal.isEmpty())
-                       throw new LoginException("Subject must be pre-authenticated");
-               if (userPrincipal.size() > 1)
-                       throw new LoginException("Multiple user principals " + userPrincipal);
-
-               return true;
-       }
-
-       @Override
-       public boolean abort() throws LoginException {
-               return true;
-       }
-
-       @Override
-       public boolean logout() throws LoginException {
-               subject.getPrincipals().removeAll(subject.getPrincipals(AnonymousPrincipal.class));
-               subject.getPrincipals().removeAll(subject.getPrincipals(AdminPrincipal.class));
-               return true;
-       }
-}
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/package-info.java b/jcr/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/package-info.java
deleted file mode 100644 (file)
index 8529cc2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Integration of Jackrabbit with Argeo security model. */
-package org.argeo.security.jackrabbit;
\ No newline at end of file
index 10de625522398f26e8c4c4f7406e0ddfee15f3bf..7cf086181111f366b75ce0d9e844d125a27ec5ef 100644 (file)
@@ -9,12 +9,11 @@ org.eclipse.swt,\
 org.eclipse.swt.widgets;version="0.0.0",\
 org.eclipse.e4.ui.model.application.ui,\
 org.eclipse.e4.ui.model.application,\
-javax.jcr.nodetype,\
 org.argeo.cms,\
 org.eclipse.core.commands.common,\
 org.eclipse.jface.window,\
+org.eclipse.jface.dialogs,\
 org.argeo.cms.swt.auth,\
-org.apache.jackrabbit.*;version="[2,3)",\
 javax.servlet.*;version="[3,5)",\
 *
 
index 347cd66fdc3a05300c801359335006068f247370..f71b83e1fd2fbee20a29121ab9e25956f4826378 100644 (file)
@@ -9,9 +9,9 @@
         <tags>auth.cn=admin,ou=roles,ou=node</tags>
         <children xsi:type="basic:PartSashContainer" xmi:id="_1tQoEDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partsashcontainer.2" horizontal="true">
           <children xsi:type="basic:PartStack" xmi:id="_vtbKkDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partstack.4" containerData="4000" selectedElement="_9gukYDvOEeiF1foPJZSZkw">
-            <children xsi:type="basic:Part" xmi:id="_9gukYDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.users" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UsersView" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png">
-              <handlers xmi:id="_0mN68DvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.4" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.NewUser" command="_uL5i4DvjEeiF1foPJZSZkw"/>
-              <handlers xmi:id="_ODLdgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.5" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.DeleteUsers" command="_xkcMADvjEeiF1foPJZSZkw"/>
+            <children xsi:type="basic:Part" xmi:id="_9gukYDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.users" containerData="" contributionURI="bundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.userssers.UsersView" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png">
+              <handlers xmi:id="_0mN68DvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.4" contributionUbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.userse4.users.handlers.NewUser" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+              <handlers xmi:id="_ODLdgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.5" contributbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.userscms.e4.users.handlers.DeleteUsers" command="_xkcMADvjEeiF1foPJZSZkw"/>
               <toolbar xmi:id="_jLWmkDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.toolbar.1">
                 <children xsi:type="menu:HandledToolItem" xmi:id="_jy_OUDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.swt/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
                 <children xsi:type="menu:HandledToolItem" xmi:id="_9qszMDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
@@ -22,9 +22,9 @@
             <tags>usersEditorArea</tags>
           </children>
           <children xsi:type="basic:PartStack" xmi:id="_-mFn8DvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partstack.5" containerData="2000">
-            <children xsi:type="basic:Part" xmi:id="_6etk4DvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.groups" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupsView" label="Groups" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png">
-              <handlers xmi:id="_cmShoDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.6" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.NewGroup" command="_uL5i4DvjEeiF1foPJZSZkw"/>
-              <handlers xmi:id="_fbYfcDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.7" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.DeleteGroups" command="_xkcMADvjEeiF1foPJZSZkw"/>
+            <children xsi:type="basic:Part" xmi:id="_6etk4DvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.groups" containerData="" contrbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.usersgeo.cms.e4.users.GroupsView" label="Groups" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png">
+              <handlers xmi:id="_cmShoDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.6" cbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.usersg.argeo.cms.e4.users.handlers.NewGroup" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+              <handlers xmi:id="_fbYfcDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.bundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.users4/org.argeo.cms.e4.users.handlers.DeleteGroups" command="_xkcMADvjEeiF1foPJZSZkw"/>
               <toolbar xmi:id="_Us0rADvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.toolbar.2">
                 <children xsi:type="menu:HandledToolItem" xmi:id="_VQTLgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.swt/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
                 <children xsi:type="menu:HandledToolItem" xmi:id="_XfME8DvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
       </children>
     </trimBars>
   </children>
-  <handlers xmi:id="_Xp-P4CqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.0" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.AddFolderNode" command="_RgE5cCqREeidr6NYQH6GbQ"/>
-  <handlers xmi:id="_jbnNwCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.1" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.DeleteNodes" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
-  <handlers xmi:id="_loxB0CqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.2" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.Refresh" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
-  <handlers xmi:id="_omPfkCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.3" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.RenameNode" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
-  <handlers xmi:id="_dUg-cFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handler.9" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.AddRemoteRepository" command="_ZWpasFgQEeiknZQLx-vtnA"/>
+  <handlers xmi:id="_Xp-P4CqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.0" contributionURI="bundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.jcr.handlerslers.AddFolderNode" command="_RgE5cCqREeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_jbnNwCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.1" contributionUbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.jcr.handlershandlers.DeleteNodes" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_loxB0CqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.2" contributbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.jcr.handlersjcr.handlers.Refresh" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_omPfkCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.3" contrbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.jcr.handlers.e4.jcr.handlers.RenameNode" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_dUg-cFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handler.9" cbundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.jcr.handlers.cms.e4.jcr.handlers.AddRemoteRepository" command="_ZWpasFgQEeiknZQLx-vtnA"/>
   <handlers xmi:id="_RQyFAFhLEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handler.10" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.handlers.CloseWorkbench" command="_PsWd0FhLEeiknZQLx-vtnA"/>
   <descriptors xmi:id="_XzfoMCqlEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.partdescriptor.nodeEditor" label="Node Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/node.gif" allowMultiple="true" category="dataExplorer" closeable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrNodeEditor"/>
-  <descriptors xmi:id="_sAdNwDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.userEditor" label="User Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UserEditor"/>
-  <descriptors xmi:id="_5nK7EDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.groupEditor" label="Group Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupEditor"/>
+  <descriptors xmi:id="_sAdNwDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.userEditor" label="User Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable=bundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.userscr.e4/org.argeo.cms.e4.users.UserEditor"/>
+  <descriptors xmi:id="_5nK7EDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.groupEditor" label="Group Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyabundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.usersms.jcr.e4/org.argeo.cms.e4.users.GroupEditor"/>
   <commands xmi:id="_RgE5cCqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.addFolderNode" commandName="Add folder node" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
   <commands xmi:id="_ChJ-4CqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.deleteNodes" commandName="Delete nodes" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
   <commands xmi:id="_TOKHsCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.refreshNodes" commandName="Refresh nodes" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
index e84b18c0b164828251602d4c2e8ecc139e516d68..37f1c0233d27eb7b7ad93974cd2988e53d174ea6 100644 (file)
@@ -96,6 +96,8 @@ public class AuthAddon {
                } catch (Exception e) {
                        throw new CmsException("Cannot log out", e);
                }
+               
+               // FIXME make it more generic
                HttpServletRequest request = org.argeo.eclipse.ui.specific.UiContext.getHttpRequest();
                if (request != null)
                        request.getSession().setMaxInactiveInterval(0);
index 579d35d6a6e0a15beb8e9a4743c6ec1087842fbc..aabfbf5dd8e863136dc74d46482976ec7ddacc8f 100644 (file)
@@ -9,9 +9,6 @@ import java.nio.file.spi.FileSystemProvider;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.eclipse.ui.fs.AdvancedFsBrowser;
 import org.argeo.eclipse.ui.fs.SimpleFsBrowser;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
@@ -27,7 +24,7 @@ public class NodeFsBrowserView {
        @PostConstruct
        public void createPartControl(Composite parent) {
                try {
-                       //URI uri = new URI("node://root:demo@localhost:7070/");
+                       // URI uri = new URI("node://root:demo@localhost:7070/");
                        URI uri = new URI("node:///");
                        FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri);
                        if (fileSystem == null)
@@ -41,7 +38,7 @@ public class NodeFsBrowserView {
 //                     AdvancedFsBrowser browser = new AdvancedFsBrowser();
 //                     browser.createUi(parent, localPath);
                } catch (Exception e) {
-                       throw new CmsException("Cannot open file system browser", e);
+                       throw new RuntimeException("Cannot open file system browser", e);
                }
        }
 
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/EclipseJcrMonitor.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/EclipseJcrMonitor.java
deleted file mode 100644 (file)
index e10738e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.argeo.cms.e4.jcr;
-
-import org.argeo.jcr.JcrMonitor;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-/**
- * Wraps an Eclipse {@link IProgressMonitor} so that it can be passed to
- * framework agnostic Argeo routines.
- */
-public class EclipseJcrMonitor implements JcrMonitor {
-       private final IProgressMonitor progressMonitor;
-
-       public EclipseJcrMonitor(IProgressMonitor progressMonitor) {
-               this.progressMonitor = progressMonitor;
-       }
-
-       public void beginTask(String name, int totalWork) {
-               progressMonitor.beginTask(name, totalWork);
-       }
-
-       public void done() {
-               progressMonitor.done();
-       }
-
-       public boolean isCanceled() {
-               return progressMonitor.isCanceled();
-       }
-
-       public void setCanceled(boolean value) {
-               progressMonitor.setCanceled(value);
-       }
-
-       public void setTaskName(String name) {
-               progressMonitor.setTaskName(name);
-       }
-
-       public void subTask(String name) {
-               progressMonitor.subTask(name);
-       }
-
-       public void worked(int work) {
-               progressMonitor.worked(work);
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/GenericPropertyPage.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/GenericPropertyPage.java
deleted file mode 100644 (file)
index e17f17b..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-package org.argeo.cms.e4.jcr;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.ui.jcr.PropertyLabelProvider;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.jface.layout.TreeColumnLayout;
-import org.eclipse.jface.viewers.ColumnWeightData;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-
-/**
- * Generic editor property page. Lists all properties of current node as a
- * complex tree. TODO: enable editing
- */
-public class GenericPropertyPage {
-
-       // Main business Objects
-       private Node currentNode;
-
-       public GenericPropertyPage(Node currentNode) {
-               this.currentNode = currentNode;
-       }
-
-       protected void createFormContent(Composite parent) {
-               Composite innerBox = new Composite(parent, SWT.NONE);
-               // Composite innerBox = new Composite(body, SWT.NO_FOCUS);
-               FillLayout layout = new FillLayout();
-               layout.marginHeight = 5;
-               layout.marginWidth = 5;
-               innerBox.setLayout(layout);
-               createComplexTree(innerBox);
-               // TODO TreeColumnLayout triggers a scroll issue with the form:
-               // The inside body is always to big and a scroll bar is shown
-               // Composite tableCmp = new Composite(body, SWT.NO_FOCUS);
-               // createComplexTree(tableCmp);
-       }
-
-       private TreeViewer createComplexTree(Composite parent) {
-               int style = SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION;
-               Tree tree = new Tree(parent, style);
-               TreeColumnLayout tableColumnLayout = new TreeColumnLayout();
-
-               createColumn(tree, tableColumnLayout, "Property", SWT.LEFT, 200, 30);
-               createColumn(tree, tableColumnLayout, "Value(s)", SWT.LEFT, 300, 60);
-               createColumn(tree, tableColumnLayout, "Type", SWT.LEFT, 75, 10);
-               createColumn(tree, tableColumnLayout, "Attributes", SWT.LEFT, 75, 0);
-               // Do not apply the treeColumnLayout it does not work yet
-               // parent.setLayout(tableColumnLayout);
-
-               tree.setLinesVisible(true);
-               tree.setHeaderVisible(true);
-
-               TreeViewer treeViewer = new TreeViewer(tree);
-               treeViewer.setContentProvider(new TreeContentProvider());
-               treeViewer.setLabelProvider((IBaseLabelProvider) new PropertyLabelProvider());
-               treeViewer.setInput(currentNode);
-               treeViewer.expandAll();
-               return treeViewer;
-       }
-
-       private static TreeColumn createColumn(Tree parent, TreeColumnLayout tableColumnLayout, String name, int style,
-                       int width, int weight) {
-               TreeColumn column = new TreeColumn(parent, style);
-               column.setText(name);
-               column.setWidth(width);
-               column.setMoveable(true);
-               column.setResizable(true);
-               tableColumnLayout.setColumnData(column, new ColumnWeightData(weight, width, true));
-               return column;
-       }
-
-       private class TreeContentProvider implements ITreeContentProvider {
-               private static final long serialVersionUID = -6162736530019406214L;
-
-               public Object[] getElements(Object parent) {
-                       Object[] props = null;
-                       try {
-
-                               if (parent instanceof Node) {
-                                       Node node = (Node) parent;
-                                       PropertyIterator pi;
-                                       pi = node.getProperties();
-                                       List<Property> propList = new ArrayList<Property>();
-                                       while (pi.hasNext()) {
-                                               propList.add(pi.nextProperty());
-                                       }
-                                       props = propList.toArray();
-                               }
-                       } catch (RepositoryException e) {
-                               throw new EclipseUiException("Unexpected exception while listing node properties", e);
-                       }
-                       return props;
-               }
-
-               public Object getParent(Object child) {
-                       return null;
-               }
-
-               public Object[] getChildren(Object parent) {
-                       if (parent instanceof Property) {
-                               Property prop = (Property) parent;
-                               try {
-                                       if (prop.isMultiple())
-                                               return prop.getValues();
-                               } catch (RepositoryException e) {
-                                       throw new EclipseUiException("Cannot get multi-prop values on " + prop, e);
-                               }
-                       }
-                       return null;
-               }
-
-               public boolean hasChildren(Object parent) {
-                       try {
-                               return (parent instanceof Property && ((Property) parent).isMultiple());
-                       } catch (RepositoryException e) {
-                               throw new EclipseUiException("Cannot check if property is multiple for " + parent, e);
-                       }
-               }
-
-               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-               }
-
-               public void dispose() {
-               }
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java
deleted file mode 100644 (file)
index 0b77c07..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-package org.argeo.cms.e4.jcr;
-
-import java.util.List;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventListener;
-import javax.jcr.observation.ObservationManager;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.security.CryptoKeyring;
-import org.argeo.cms.security.Keyring;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.jcr.JcrBrowserUtils;
-import org.argeo.cms.ui.jcr.NodeContentProvider;
-import org.argeo.cms.ui.jcr.NodeLabelProvider;
-import org.argeo.cms.ui.jcr.OsgiRepositoryRegister;
-import org.argeo.cms.ui.jcr.PropertiesContentProvider;
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
-import org.argeo.eclipse.ui.jcr.util.NodeViewerComparer;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.e4.core.contexts.IEclipseContext;
-import org.eclipse.e4.core.di.annotations.Optional;
-import org.eclipse.e4.ui.services.EMenuService;
-import org.eclipse.e4.ui.workbench.modeling.EPartService;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * Basic View to display a sash form to browse a JCR compliant multiple
- * repository environment
- */
-public class JcrBrowserView {
-       final static String ID = "org.argeo.cms.e4.jcrbrowser";
-       final static String NODE_VIEWER_POPUP_MENU_ID = "org.argeo.cms.e4.popupmenu.nodeViewer";
-
-       private boolean sortChildNodes = true;
-
-       /* DEPENDENCY INJECTION */
-       @Inject
-       @Optional
-       private Keyring keyring;
-       @Inject
-       private RepositoryFactory repositoryFactory;
-       @Inject
-       private Repository nodeRepository;
-
-       // Current user session on the home repository default workspace
-       private Session userSession;
-
-       private OsgiRepositoryRegister repositoryRegister = new OsgiRepositoryRegister();
-
-       // This page widgets
-       private TreeViewer nodesViewer;
-       private NodeContentProvider nodeContentProvider;
-       private TableViewer propertiesViewer;
-       private EventListener resultsObserver;
-
-       @PostConstruct
-       public void createPartControl(Composite parent, IEclipseContext context, EPartService partService,
-                       ESelectionService selectionService, EMenuService menuService) {
-               repositoryRegister.init();
-
-               parent.setLayout(new FillLayout());
-               SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
-               // sashForm.setSashWidth(4);
-               // sashForm.setLayout(new FillLayout());
-
-               // Create the tree on top of the view
-               Composite top = new Composite(sashForm, SWT.NONE);
-               // GridLayout gl = new GridLayout(1, false);
-               top.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
-               try {
-                       this.userSession = this.nodeRepository.login(CmsConstants.HOME_WORKSPACE);
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot open user session", e);
-               }
-
-               nodeContentProvider = new NodeContentProvider(userSession, keyring, repositoryRegister, repositoryFactory,
-                               sortChildNodes);
-
-               // nodes viewer
-               nodesViewer = createNodeViewer(top, nodeContentProvider);
-
-               // context menu : it is completely defined in the plugin.xml file.
-               // MenuManager menuManager = new MenuManager();
-               // Menu menu = menuManager.createContextMenu(nodesViewer.getTree());
-
-               // nodesViewer.getTree().setMenu(menu);
-
-               nodesViewer.setInput("");
-
-               // Create the property viewer on the bottom
-               Composite bottom = new Composite(sashForm, SWT.NONE);
-               bottom.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               propertiesViewer = createPropertiesViewer(bottom);
-
-               sashForm.setWeights(getWeights());
-               nodesViewer.setComparer(new NodeViewerComparer());
-               nodesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-                       public void selectionChanged(SelectionChangedEvent event) {
-                               IStructuredSelection selection = (IStructuredSelection) event.getSelection();
-                               selectionService.setSelection(selection.toList());
-                       }
-               });
-               nodesViewer.addDoubleClickListener(new JcrE4DClickListener(nodesViewer, partService));
-               menuService.registerContextMenu(nodesViewer.getControl(), NODE_VIEWER_POPUP_MENU_ID);
-               // getSite().registerContextMenu(menuManager, nodesViewer);
-               // getSite().setSelectionProvider(nodesViewer);
-       }
-
-       @PreDestroy
-       public void dispose() {
-               JcrUtils.logoutQuietly(userSession);
-               repositoryRegister.destroy();
-       }
-
-       public void refresh(Object obj) {
-               // Enable full refresh from a command when no element of the tree is
-               // selected
-               if (obj == null) {
-                       Object[] elements = nodeContentProvider.getElements(null);
-                       for (Object el : elements) {
-                               if (el instanceof TreeParent)
-                                       JcrBrowserUtils.forceRefreshIfNeeded((TreeParent) el);
-                               getNodeViewer().refresh(el);
-                       }
-               } else
-                       getNodeViewer().refresh(obj);
-       }
-
-       /**
-        * To be overridden to adapt size of form and result frames.
-        */
-       protected int[] getWeights() {
-               return new int[] { 70, 30 };
-       }
-
-       protected TreeViewer createNodeViewer(Composite parent, final ITreeContentProvider nodeContentProvider) {
-
-               final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
-
-               tmpNodeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
-               tmpNodeViewer.setContentProvider(nodeContentProvider);
-               tmpNodeViewer.setLabelProvider((IBaseLabelProvider) new NodeLabelProvider());
-               tmpNodeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-                       public void selectionChanged(SelectionChangedEvent event) {
-                               if (!event.getSelection().isEmpty()) {
-                                       IStructuredSelection sel = (IStructuredSelection) event.getSelection();
-                                       Object firstItem = sel.getFirstElement();
-                                       if (firstItem instanceof SingleJcrNodeElem)
-                                               propertiesViewer.setInput(((SingleJcrNodeElem) firstItem).getNode());
-                               } else {
-                                       propertiesViewer.setInput("");
-                               }
-                       }
-               });
-
-               resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay());
-               if (keyring != null)
-                       try {
-                               ObservationManager observationManager = userSession.getWorkspace().getObservationManager();
-                               observationManager.addEventListener(resultsObserver, Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/",
-                                               true, null, null, false);
-                       } catch (RepositoryException e) {
-                               throw new EclipseUiException("Cannot register listeners", e);
-                       }
-
-               // tmpNodeViewer.addDoubleClickListener(new JcrDClickListener(tmpNodeViewer));
-               return tmpNodeViewer;
-       }
-
-       protected TableViewer createPropertiesViewer(Composite parent) {
-               propertiesViewer = new TableViewer(parent, SWT.NONE);
-               propertiesViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               propertiesViewer.getTable().setHeaderVisible(true);
-               propertiesViewer.setContentProvider(new PropertiesContentProvider());
-               TableViewerColumn col = new TableViewerColumn(propertiesViewer, SWT.NONE);
-               col.getColumn().setText("Name");
-               col.getColumn().setWidth(200);
-               col.setLabelProvider(new ColumnLabelProvider() {
-                       private static final long serialVersionUID = -6684361063107478595L;
-
-                       public String getText(Object element) {
-                               try {
-                                       return ((Property) element).getName();
-                               } catch (RepositoryException e) {
-                                       throw new EclipseUiException("Unexpected exception in label provider", e);
-                               }
-                       }
-               });
-               col = new TableViewerColumn(propertiesViewer, SWT.NONE);
-               col.getColumn().setText("Value");
-               col.getColumn().setWidth(400);
-               col.setLabelProvider(new ColumnLabelProvider() {
-                       private static final long serialVersionUID = -8201994187693336657L;
-
-                       public String getText(Object element) {
-                               try {
-                                       Property property = (Property) element;
-                                       if (property.getType() == PropertyType.BINARY)
-                                               return "<binary>";
-                                       else if (property.isMultiple()) {
-                                               StringBuffer buf = new StringBuffer("[");
-                                               Value[] values = property.getValues();
-                                               for (int i = 0; i < values.length; i++) {
-                                                       if (i != 0)
-                                                               buf.append(", ");
-                                                       buf.append(values[i].getString());
-                                               }
-                                               buf.append(']');
-                                               return buf.toString();
-                                       } else
-                                               return property.getValue().getString();
-                               } catch (RepositoryException e) {
-                                       throw new EclipseUiException("Unexpected exception in label provider", e);
-                               }
-                       }
-               });
-               col = new TableViewerColumn(propertiesViewer, SWT.NONE);
-               col.getColumn().setText("Type");
-               col.getColumn().setWidth(200);
-               col.setLabelProvider(new ColumnLabelProvider() {
-                       private static final long serialVersionUID = -6009599998150286070L;
-
-                       public String getText(Object element) {
-                               return JcrBrowserUtils.getPropertyTypeAsString((Property) element);
-                       }
-               });
-               propertiesViewer.setInput("");
-               return propertiesViewer;
-       }
-
-       protected TreeViewer getNodeViewer() {
-               return nodesViewer;
-       }
-
-       /**
-        * Resets the tree content provider
-        * 
-        * @param sortChildNodes if true the content provider will use a comparer to
-        *                       sort nodes that might slow down the display
-        */
-       public void setSortChildNodes(boolean sortChildNodes) {
-               this.sortChildNodes = sortChildNodes;
-               ((NodeContentProvider) nodesViewer.getContentProvider()).setSortChildren(sortChildNodes);
-               nodesViewer.setInput("");
-       }
-
-       /** Notifies the current view that a node has been added */
-       public void nodeAdded(TreeParent parentNode) {
-               // insure that Ui objects have been correctly created:
-               JcrBrowserUtils.forceRefreshIfNeeded(parentNode);
-               getNodeViewer().refresh(parentNode);
-               getNodeViewer().expandToLevel(parentNode, 1);
-       }
-
-       /** Notifies the current view that a node has been removed */
-       public void nodeRemoved(TreeParent parentNode) {
-               IStructuredSelection newSel = new StructuredSelection(parentNode);
-               getNodeViewer().setSelection(newSel, true);
-               // Force refresh
-               IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer().getSelection();
-               getNodeViewer().refresh(tmpSel.getFirstElement());
-       }
-
-       class TreeObserver extends AsyncUiEventListener {
-
-               public TreeObserver(Display display) {
-                       super(display);
-               }
-
-               @Override
-               protected Boolean willProcessInUiThread(List<Event> events) throws RepositoryException {
-                       for (Event event : events) {
-                               if (getLog().isTraceEnabled())
-                                       getLog().debug("Received event " + event);
-                               String path = event.getPath();
-                               int index = path.lastIndexOf('/');
-                               String propertyName = path.substring(index + 1);
-                               if (getLog().isTraceEnabled())
-                                       getLog().debug("Concerned property " + propertyName);
-                       }
-                       return false;
-               }
-
-               protected void onEventInUiThread(List<Event> events) throws RepositoryException {
-                       if (getLog().isTraceEnabled())
-                               getLog().trace("Refresh result list");
-                       nodesViewer.refresh();
-               }
-
-       }
-
-       public boolean getSortChildNodes() {
-               return sortChildNodes;
-       }
-
-       public void setFocus() {
-               getNodeViewer().getTree().setFocus();
-       }
-
-       /* DEPENDENCY INJECTION */
-       // public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
-       // this.repositoryRegister = repositoryRegister;
-       // }
-
-       public void setKeyring(CryptoKeyring keyring) {
-               this.keyring = keyring;
-       }
-
-       public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
-               this.repositoryFactory = repositoryFactory;
-       }
-
-       public void setNodeRepository(Repository nodeRepository) {
-               this.nodeRepository = nodeRepository;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrE4DClickListener.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrE4DClickListener.java
deleted file mode 100644 (file)
index f4ee2e8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.argeo.cms.e4.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.ui.jcr.JcrDClickListener;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.workbench.modeling.EPartService;
-import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
-import org.eclipse.jface.viewers.TreeViewer;
-
-public class JcrE4DClickListener extends JcrDClickListener {
-       EPartService partService;
-
-       public JcrE4DClickListener(TreeViewer nodeViewer, EPartService partService) {
-               super(nodeViewer);
-               this.partService = partService;
-       }
-
-       @Override
-       protected void openNode(Node node) {
-               MPart part = partService.createPart(JcrNodeEditor.DESCRIPTOR_ID);
-               try {
-                       part.setLabel(node.getName());
-                       part.getPersistedState().put("nodeWorkspace", node.getSession().getWorkspace().getName());
-                       part.getPersistedState().put("nodePath", node.getPath());
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot open " + node, e);
-               }
-
-               // the provided part is be shown
-               partService.showPart(part, PartState.ACTIVATE);
-       }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrNodeEditor.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrNodeEditor.java
deleted file mode 100644 (file)
index ae2b325..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.argeo.cms.e4.jcr;
-
-import java.util.List;
-
-import javax.annotation.PostConstruct;
-import javax.jcr.Node;
-
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-
-public class JcrNodeEditor {
-       final static String DESCRIPTOR_ID = "org.argeo.cms.e4.partdescriptor.nodeEditor";
-
-       @PostConstruct
-       public void createUi(Composite parent, MPart part, ESelectionService selectionService) {
-               parent.setLayout(new FillLayout());
-               List<?> selection = (List<?>) selectionService.getSelection();
-               Node node = ((SingleJcrNodeElem) selection.get(0)).getNode();
-               GenericPropertyPage propertyPage = new GenericPropertyPage(node);
-               propertyPage.createFormContent(parent);
-       }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/SimplePart.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/SimplePart.java
deleted file mode 100644 (file)
index 17d8d2a..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.argeo.cms.e4.jcr;
-
-import javax.annotation.PostConstruct;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-public class SimplePart {
-
-       @PostConstruct
-       void init(Composite parent) {
-               parent.setLayout(new GridLayout());
-               Label label = new Label(parent, SWT.NONE);
-               label.setText("Hello e4 World");
-       }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddFolderNode.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddFolderNode.java
deleted file mode 100644 (file)
index 09fa760..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.argeo.cms.e4.jcr.handlers;
-
-import java.util.List;
-
-import javax.inject.Named;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.cms.e4.jcr.JcrBrowserView;
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.cms.ui.jcr.model.WorkspaceElem;
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.argeo.eclipse.ui.dialogs.SingleValue;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-
-/**
- * Adds a node of type nt:folder, only on {@link SingleJcrNodeElem} and
- * {@link WorkspaceElem} TreeObject types.
- * 
- * This handler assumes that a selection provider is available and picks only
- * first selected item. It is UI's job to enable the command only when the
- * selection contains one and only one element. Thus no parameter is passed
- * through the command.
- */
-public class AddFolderNode {
-       @Execute
-       public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) {
-               List<?> selection = (List<?>) selectionService.getSelection();
-               JcrBrowserView view = (JcrBrowserView) part.getObject();
-
-               if (selection != null && selection.size() == 1) {
-                       TreeParent treeParentNode = null;
-                       Node jcrParentNode = null;
-                       Object obj = selection.get(0);
-
-                       if (obj instanceof SingleJcrNodeElem) {
-                               treeParentNode = (TreeParent) obj;
-                               jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode();
-                       } else if (obj instanceof WorkspaceElem) {
-                               treeParentNode = (TreeParent) obj;
-                               jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode();
-                       } else
-                               return;
-
-                       String folderName = SingleValue.ask("Folder name", "Enter folder name");
-                       if (folderName != null) {
-                               try {
-                                       jcrParentNode.addNode(folderName, NodeType.NT_FOLDER);
-                                       jcrParentNode.getSession().save();
-                                       view.nodeAdded(treeParentNode);
-                               } catch (RepositoryException e) {
-                                       ErrorFeedback.show("Cannot create folder " + folderName + " under " + treeParentNode, e);
-                               }
-                       }
-               } else {
-                       // ErrorFeedback.show(WorkbenchUiPlugin
-                       // .getMessage("errorUnvalidNtFolderNodeType"));
-                       ErrorFeedback.show("Invalid NT folder node type");
-               }
-       }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java
deleted file mode 100644 (file)
index dc47f6e..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-package org.argeo.cms.e4.jcr.handlers;
-
-import java.net.URI;
-import java.util.Hashtable;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-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;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.core.di.annotations.Optional;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Connect to a remote repository and, if successful publish it as an OSGi
- * service.
- */
-public class AddRemoteRepository {
-
-       @Inject
-       private RepositoryFactory repositoryFactory;
-       @Inject
-       private Repository nodeRepository;
-       @Inject
-       @Optional
-       private Keyring keyring;
-
-       @Execute
-       public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part) {
-               JcrBrowserView view = (JcrBrowserView) part.getObject();
-               RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(Display.getDefault().getActiveShell());
-               if (dlg.open() == Dialog.OK) {
-                       view.refresh(null);
-               }
-       }
-
-       // public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
-       // this.repositoryFactory = repositoryFactory;
-       // }
-       //
-       // public void setKeyring(Keyring keyring) {
-       // this.keyring = keyring;
-       // }
-       //
-       // public void setNodeRepository(Repository nodeRepository) {
-       // this.nodeRepository = nodeRepository;
-       // }
-
-       class RemoteRepositoryLoginDialog extends TitleAreaDialog {
-               private static final long serialVersionUID = 2234006887750103399L;
-               private Text name;
-               private Text uri;
-               private Text username;
-               private Text password;
-               private Button saveInKeyring;
-
-               public RemoteRepositoryLoginDialog(Shell parentShell) {
-                       super(parentShell);
-               }
-
-               protected Point getInitialSize() {
-                       return new Point(600, 400);
-               }
-
-               protected Control createDialogArea(Composite parent) {
-                       Composite dialogarea = (Composite) super.createDialogArea(parent);
-                       dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-                       Composite composite = new Composite(dialogarea, SWT.NONE);
-                       composite.setLayout(new GridLayout(2, false));
-                       composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-                       setMessage("Login to remote repository", IMessageProvider.NONE);
-                       name = createLT(composite, "Name", "remoteRepository");
-                       uri = createLT(composite, "URI", "http://localhost:7070/jcr/node");
-                       username = createLT(composite, "User", "");
-                       password = createLP(composite, "Password");
-
-                       saveInKeyring = createLC(composite, "Remember password", false);
-                       parent.pack();
-                       return composite;
-               }
-
-               @Override
-               protected void createButtonsForButtonBar(Composite parent) {
-                       super.createButtonsForButtonBar(parent);
-                       Button test = createButton(parent, 2, "Test", false);
-                       test.addSelectionListener(new SelectionAdapter() {
-                               private static final long serialVersionUID = -1829962269440419560L;
-
-                               public void widgetSelected(SelectionEvent arg0) {
-                                       testConnection();
-                               }
-                       });
-               }
-
-               void testConnection() {
-                       Session session = null;
-                       try {
-                               URI checkedUri = new URI(uri.getText());
-                               String checkedUriStr = checkedUri.toString();
-
-                               Hashtable<String, String> params = new Hashtable<String, String>();
-                               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(CmsConstants.SYS_WORKSPACE);
-                               } else {
-                                       // FIXME use getTextChars() when upgrading to 3.7
-                                       // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412
-                                       char[] pwd = password.getText().toCharArray();
-                                       SimpleCredentials sc = new SimpleCredentials(username.getText(), pwd);
-                                       session = repository.login(sc, "main");
-                                       MessageDialog.openInformation(getParentShell(), "Success",
-                                                       "Connection to '" + uri.getText() + "' successful");
-                               }
-                       } catch (Exception e) {
-                               ErrorFeedback.show("Connection test failed for " + uri.getText(), e);
-                       } finally {
-                               JcrUtils.logoutQuietly(session);
-                       }
-               }
-
-               @Override
-               protected void okPressed() {
-                       Session nodeSession = null;
-                       try {
-                               nodeSession = nodeRepository.login();
-                               Node home = CmsJcrUtils.getUserHome(nodeSession);
-
-                               Node remote = home.hasNode(ArgeoNames.ARGEO_REMOTE) ? home.getNode(ArgeoNames.ARGEO_REMOTE)
-                                               : home.addNode(ArgeoNames.ARGEO_REMOTE);
-                               if (remote.hasNode(name.getText()))
-                                       throw new EclipseUiException("There is already a remote repository named " + name.getText());
-                               Node remoteRepository = remote.addNode(name.getText(), ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
-                               remoteRepository.setProperty(ArgeoNames.ARGEO_URI, uri.getText());
-                               remoteRepository.setProperty(ArgeoNames.ARGEO_USER_ID, username.getText());
-                               nodeSession.save();
-                               if (saveInKeyring.getSelection()) {
-                                       String pwdPath = remoteRepository.getPath() + '/' + ArgeoNames.ARGEO_PASSWORD;
-                                       keyring.set(pwdPath, password.getText().toCharArray());
-                               }
-                               nodeSession.save();
-                               MessageDialog.openInformation(getParentShell(), "Repository Added",
-                                               "Remote repository '" + username.getText() + "@" + uri.getText() + "' added");
-
-                               super.okPressed();
-                       } catch (Exception e) {
-                               ErrorFeedback.show("Cannot add remote repository", e);
-                       } finally {
-                               JcrUtils.logoutQuietly(nodeSession);
-                       }
-               }
-
-               /** Creates label and text. */
-               protected Text createLT(Composite parent, String label, String initial) {
-                       new Label(parent, SWT.NONE).setText(label);
-                       Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
-                       text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-                       text.setText(initial);
-                       return text;
-               }
-
-               /** Creates label and check. */
-               protected Button createLC(Composite parent, String label, Boolean initial) {
-                       new Label(parent, SWT.NONE).setText(label);
-                       Button check = new Button(parent, SWT.CHECK);
-                       check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-                       check.setSelection(initial);
-                       return check;
-               }
-
-               protected Text createLP(Composite parent, String label) {
-                       new Label(parent, SWT.NONE).setText(label);
-                       Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER | SWT.PASSWORD);
-                       text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-                       return text;
-               }
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/DeleteNodes.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/DeleteNodes.java
deleted file mode 100644 (file)
index b8de06b..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.argeo.cms.e4.jcr.handlers;
-
-import java.util.List;
-
-import javax.inject.Named;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.e4.jcr.JcrBrowserView;
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.cms.ui.jcr.model.WorkspaceElem;
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * Delete the selected nodes: both in the JCR repository and in the UI view.
- * Warning no check is done, except implementation dependent native checks,
- * handle with care.
- * 
- * This handler is still 'hard linked' to a GenericJcrBrowser view to enable
- * correct tree refresh when a node is added. This must be corrected in future
- * versions.
- */
-public class DeleteNodes {
-       @Execute
-       public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) {
-               List<?> selection = (List<?>) selectionService.getSelection();
-               if (selection == null)
-                       return;
-
-               JcrBrowserView view = (JcrBrowserView) part.getObject();
-
-               // confirmation
-               StringBuffer buf = new StringBuffer("");
-               for (Object o : selection) {
-                       SingleJcrNodeElem sjn = (SingleJcrNodeElem) o;
-                       buf.append(sjn.getName()).append(' ');
-               }
-               Boolean doRemove = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Confirm deletion",
-                               "Do you want to delete " + buf + "?");
-
-               // operation
-               if (doRemove) {
-                       SingleJcrNodeElem ancestor = null;
-                       WorkspaceElem rootAncestor = null;
-                       try {
-                               for (Object obj : selection) {
-                                       if (obj instanceof SingleJcrNodeElem) {
-                                               // Cache objects
-                                               SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj;
-                                               TreeParent tp = (TreeParent) sjn.getParent();
-                                               Node node = sjn.getNode();
-
-                                               // Jcr Remove
-                                               node.remove();
-                                               node.getSession().save();
-                                               // UI remove
-                                               tp.removeChild(sjn);
-
-                                               // Check if the parent is the root node
-                                               if (tp instanceof WorkspaceElem)
-                                                       rootAncestor = (WorkspaceElem) tp;
-                                               else
-                                                       ancestor = getOlder(ancestor, (SingleJcrNodeElem) tp);
-                                       }
-                               }
-                               if (rootAncestor != null)
-                                       view.nodeRemoved(rootAncestor);
-                               else if (ancestor != null)
-                                       view.nodeRemoved(ancestor);
-                       } catch (Exception e) {
-                               ErrorFeedback.show("Cannot delete selected node ", e);
-                       }
-               }
-       }
-
-       private SingleJcrNodeElem getOlder(SingleJcrNodeElem A, SingleJcrNodeElem B) {
-               try {
-                       if (A == null)
-                               return B == null ? null : B;
-                       // Todo enhanced this method
-                       else
-                               return A.getNode().getDepth() <= B.getNode().getDepth() ? A : B;
-               } catch (RepositoryException re) {
-                       throw new EclipseUiException("Cannot find ancestor", re);
-               }
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/Refresh.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/Refresh.java
deleted file mode 100644 (file)
index 036e70a..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.argeo.cms.e4.jcr.handlers;
-
-import java.util.List;
-
-import javax.inject.Named;
-
-import org.argeo.cms.e4.jcr.JcrBrowserView;
-import org.argeo.cms.ui.jcr.JcrBrowserUtils;
-import org.argeo.cms.ux.widgets.TreeParent;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.e4.ui.workbench.modeling.EPartService;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-
-/**
- * Force the selected objects of the active view to be refreshed doing the
- * following:
- * <ol>
- * <li>The model objects are recomputed</li>
- * <li>the view is refreshed</li>
- * </ol>
- */
-public class Refresh {
-
-       @Execute
-       public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, EPartService partService,
-                       ESelectionService selectionService) {
-
-               JcrBrowserView view = (JcrBrowserView) part.getObject();
-               List<?> selection = (List<?>) selectionService.getSelection();
-
-               if (selection != null && !selection.isEmpty()) {
-                       for (Object obj : selection)
-                               if (obj instanceof TreeParent) {
-                                       TreeParent tp = (TreeParent) obj;
-                                       JcrBrowserUtils.forceRefreshIfNeeded(tp);
-                                       view.refresh(obj);
-                               }
-               } else if (view instanceof JcrBrowserView)
-                       view.refresh(null); // force full refresh
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/RenameNode.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/RenameNode.java
deleted file mode 100644 (file)
index 97674ab..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.argeo.cms.e4.jcr.handlers;
-
-import java.util.List;
-
-import javax.inject.Named;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.cms.e4.jcr.JcrBrowserView;
-import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.dialogs.SingleValue;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.e4.ui.workbench.modeling.EPartService;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-
-/**
- * Canonically call JCR Session#move(String, String) on the first element
- * returned by HandlerUtil#getActiveWorkbenchWindow()
- * (...getActivePage().getSelection()), if it is a {@link SingleJcrNodeElem}.
- * The user must then fill a new name in and confirm
- */
-public class RenameNode {
-       @Execute
-       public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, EPartService partService,
-                       ESelectionService selectionService) {
-               List<?> selection = (List<?>) selectionService.getSelection();
-               if (selection == null || selection.size() != 1)
-                       return;
-               JcrBrowserView view = (JcrBrowserView) part.getObject();
-
-               Object element = selection.get(0);
-               if (element instanceof SingleJcrNodeElem) {
-                       SingleJcrNodeElem sjn = (SingleJcrNodeElem) element;
-                       Node node = sjn.getNode();
-                       Session session = null;
-                       String newName = null;
-                       String oldPath = null;
-                       try {
-                               newName = SingleValue.ask("New node name", "Please provide a new name for [" + node.getName() + "]");
-                               // TODO sanity check and user feedback
-                               newName = JcrUtils.replaceInvalidChars(newName);
-                               oldPath = node.getPath();
-                               session = node.getSession();
-                               session.move(oldPath, JcrUtils.parentPath(oldPath) + "/" + newName);
-                               session.save();
-
-                               // Manually refresh the browser view. Must be enhanced
-                               view.refresh(sjn);
-                       } catch (RepositoryException e) {
-                               throw new EclipseUiException("Unable to rename " + node + " to " + newName, e);
-                       }
-               }
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/package-info.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/package-info.java
deleted file mode 100644 (file)
index 4e075e2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** JCR browser handlers. */
-package org.argeo.cms.e4.jcr.handlers;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/package-info.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/package-info.java
deleted file mode 100644 (file)
index 3e92fb0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** JCR browser perspective. */
-package org.argeo.cms.e4.jcr;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java
deleted file mode 100644 (file)
index 4fd1d68..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import java.util.Collection;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-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 CmsLog log = CmsLog.getLog(getClass());
-
-       public AbstractOsgiComposite(Composite parent, int style) {
-               super(parent, style);
-               parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               setLayout(CmsSwtUtils.noSpaceGridLayout());
-               setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-               initUi(style);
-       }
-
-       protected abstract void initUi(int style);
-
-       protected <T> T getService(Class<? extends T> clazz) {
-               return bc.getService(bc.getServiceReference(clazz));
-       }
-
-       protected <T> Collection<ServiceReference<T>> getServiceReferences(Class<T> clazz, String filter) {
-               try {
-                       return bc.getServiceReferences(clazz, filter);
-               } catch (InvalidSyntaxException e) {
-                       throw new IllegalArgumentException("Filter " + filter + " is invalid", e);
-               }
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/Browse.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/Browse.java
deleted file mode 100644 (file)
index a536da0..0000000
+++ /dev/null
@@ -1,576 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import static org.eclipse.swt.SWT.RIGHT;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.LinkedHashMap;
-
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.util.CmsLink;
-import org.argeo.cms.ui.widgets.EditableImage;
-import org.argeo.cms.ui.widgets.Img;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ILazyContentProvider;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-
-public class Browse implements CmsUiProvider {
-
-       // Some local constants to experiment. should be cleaned
-       private final static String BROWSE_PREFIX = "browse#";
-       private final static int THUMBNAIL_WIDTH = 400;
-       private final static int COLUMN_WIDTH = 160;
-       private DateFormat timeFormatter = new SimpleDateFormat("dd-MM-yyyy', 'HH:mm");
-
-       // keep a cache of the opened nodes
-       // Key is the path
-       private LinkedHashMap<String, FilterEntitiesVirtualTable> browserCols = new LinkedHashMap<String, Browse.FilterEntitiesVirtualTable>();
-       private Composite nodeDisplayParent;
-       private Composite colViewer;
-       private ScrolledComposite scrolledCmp;
-       private Text parentPathTxt;
-       private Text filterTxt;
-       private Node currEdited;
-
-       private String initialPath;
-
-       @Override
-       public Control createUi(Composite parent, Node context) throws RepositoryException {
-               if (context == null)
-                       // return null;
-                       throw new CmsException("Context cannot be null");
-               GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
-               layout.numColumns = 2;
-               parent.setLayout(layout);
-
-               // Left
-               Composite leftCmp = new Composite(parent, SWT.NO_FOCUS);
-               leftCmp.setLayoutData(CmsSwtUtils.fillAll());
-               createBrowserPart(leftCmp, context);
-
-               // Right
-               nodeDisplayParent = new Composite(parent, SWT.NO_FOCUS | SWT.BORDER);
-               GridData gd = new GridData(SWT.RIGHT, SWT.FILL, false, true);
-               gd.widthHint = THUMBNAIL_WIDTH;
-               nodeDisplayParent.setLayoutData(gd);
-               createNodeView(nodeDisplayParent, context);
-
-               // INIT
-               setEdited(context);
-               initialPath = context.getPath();
-
-               // Workaround we don't yet manage the delete to display parent of the
-               // initial context node
-
-               return null;
-       }
-
-       private void createBrowserPart(Composite parent, Node context) throws RepositoryException {
-               GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
-               parent.setLayout(layout);
-               Composite filterCmp = new Composite(parent, SWT.NO_FOCUS);
-               filterCmp.setLayoutData(CmsSwtUtils.fillWidth());
-
-               // top filter
-               addFilterPanel(filterCmp);
-
-               // scrolled composite
-               scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER | SWT.NO_FOCUS);
-               scrolledCmp.setLayoutData(CmsSwtUtils.fillAll());
-               scrolledCmp.setExpandVertical(true);
-               scrolledCmp.setExpandHorizontal(true);
-               scrolledCmp.setShowFocusedControl(true);
-
-               colViewer = new Composite(scrolledCmp, SWT.NO_FOCUS);
-               scrolledCmp.setContent(colViewer);
-               scrolledCmp.addControlListener(new ControlAdapter() {
-                       private static final long serialVersionUID = 6589392045145698201L;
-
-                       @Override
-                       public void controlResized(ControlEvent e) {
-                               Rectangle r = scrolledCmp.getClientArea();
-                               scrolledCmp.setMinSize(colViewer.computeSize(SWT.DEFAULT, r.height));
-                       }
-               });
-               initExplorer(colViewer, context);
-       }
-
-       private Control initExplorer(Composite parent, Node context) throws RepositoryException {
-               parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               createBrowserColumn(parent, context);
-               return null;
-       }
-
-       private Control createBrowserColumn(Composite parent, Node context) throws RepositoryException {
-               // TODO style is not correctly managed.
-               FilterEntitiesVirtualTable table = new FilterEntitiesVirtualTable(parent, SWT.BORDER | SWT.NO_FOCUS, context);
-               // CmsUiUtils.style(table, ArgeoOrgStyle.browserColumn.style());
-               table.filterList("*");
-               table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
-               browserCols.put(context.getPath(), table);
-               return null;
-       }
-
-       public void addFilterPanel(Composite parent) {
-
-               parent.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
-
-               // Text Area for the filter
-               parentPathTxt = new Text(parent, SWT.NO_FOCUS);
-               parentPathTxt.setEditable(false);
-               filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL);
-               filterTxt.setMessage("Filter current list");
-               filterTxt.setLayoutData(CmsSwtUtils.fillWidth());
-               filterTxt.addModifyListener(new ModifyListener() {
-                       private static final long serialVersionUID = 7709303319740056286L;
-
-                       public void modifyText(ModifyEvent event) {
-                               modifyFilter(false);
-                       }
-               });
-
-               filterTxt.addKeyListener(new KeyListener() {
-                       private static final long serialVersionUID = -4523394262771183968L;
-
-                       @Override
-                       public void keyReleased(KeyEvent e) {
-                       }
-
-                       @Override
-                       public void keyPressed(KeyEvent e) {
-                               boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
-                               // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
-                               FilterEntitiesVirtualTable currTable = null;
-                               if (currEdited != null) {
-                                       FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited));
-                                       if (table != null && !table.isDisposed())
-                                               currTable = table;
-                               }
-
-                               try {
-                                       if (e.keyCode == SWT.ARROW_DOWN)
-                                               currTable.setFocus();
-                                       else if (e.keyCode == SWT.BS) {
-                                               if (filterTxt.getText().equals("")
-                                                               && !(getPath(currEdited).equals("/") || getPath(currEdited).equals(initialPath))) {
-                                                       setEdited(currEdited.getParent());
-                                                       e.doit = false;
-                                                       filterTxt.setFocus();
-                                               }
-                                       } else if (e.keyCode == SWT.TAB && !shiftPressed) {
-                                               if (currEdited.getNodes(filterTxt.getText() + "*").getSize() == 1) {
-                                                       setEdited(currEdited.getNodes(filterTxt.getText() + "*").nextNode());
-                                               }
-                                               filterTxt.setFocus();
-                                               e.doit = false;
-                                       }
-                               } catch (RepositoryException e1) {
-                                       throw new CmsException("Unexpected error in key management for " + currEdited + "with filter "
-                                                       + filterTxt.getText(), e1);
-                               }
-
-                       }
-               });
-       }
-
-       private void setEdited(Node node) {
-               try {
-                       currEdited = node;
-                       CmsSwtUtils.clear(nodeDisplayParent);
-                       createNodeView(nodeDisplayParent, currEdited);
-                       nodeDisplayParent.layout();
-                       refreshFilters(node);
-                       refreshBrowser(node);
-               } catch (RepositoryException re) {
-                       throw new CmsException("Unable to update browser for " + node, re);
-               }
-       }
-
-       private void refreshFilters(Node node) throws RepositoryException {
-               String currNodePath = node.getPath();
-               parentPathTxt.setText(currNodePath);
-               filterTxt.setText("");
-               filterTxt.getParent().layout();
-       }
-
-       private void refreshBrowser(Node node) throws RepositoryException {
-
-               // Retrieve
-               String currNodePath = node.getPath();
-               String currParPath = "";
-               if (!"/".equals(currNodePath))
-                       currParPath = JcrUtils.parentPath(currNodePath);
-               if ("".equals(currParPath))
-                       currParPath = "/";
-
-               Object[][] colMatrix = new Object[browserCols.size()][2];
-
-               int i = 0, j = -1, k = -1;
-               for (String path : browserCols.keySet()) {
-                       colMatrix[i][0] = path;
-                       colMatrix[i][1] = browserCols.get(path);
-                       if (j >= 0 && k < 0 && !currNodePath.equals("/")) {
-                               boolean leaveOpened = path.startsWith(currNodePath);
-
-                               // workaround for same name siblings
-                               // fix me weird side effect when we go left or click on anb
-                               // already selected, unfocused node
-                               if (leaveOpened && (path.lastIndexOf("/") == 0 && currNodePath.lastIndexOf("/") == 0
-                                               || JcrUtils.parentPath(path).equals(JcrUtils.parentPath(currNodePath))))
-                                       leaveOpened = JcrUtils.lastPathElement(path).equals(JcrUtils.lastPathElement(currNodePath));
-
-                               if (!leaveOpened)
-                                       k = i;
-                       }
-                       if (currParPath.equals(path))
-                               j = i;
-                       i++;
-               }
-
-               if (j >= 0 && k >= 0)
-                       // remove useless cols
-                       for (int l = i - 1; l >= k; l--) {
-                               browserCols.remove(colMatrix[l][0]);
-                               ((FilterEntitiesVirtualTable) colMatrix[l][1]).dispose();
-                       }
-
-               // Remove disposed columns
-               // TODO investigate and fix the mechanism that leave them there after
-               // disposal
-               if (browserCols.containsKey(currNodePath)) {
-                       FilterEntitiesVirtualTable currCol = browserCols.get(currNodePath);
-                       if (currCol.isDisposed())
-                               browserCols.remove(currNodePath);
-               }
-
-               if (!browserCols.containsKey(currNodePath))
-                       createBrowserColumn(colViewer, node);
-
-               colViewer.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false)));
-               // colViewer.pack();
-               colViewer.layout();
-               // also resize the scrolled composite
-               scrolledCmp.layout();
-               scrolledCmp.getShowFocusedControl();
-               // colViewer.getParent().layout();
-               // if (JcrUtils.parentPath(currNodePath).equals(currBrowserKey)) {
-               // } else {
-               // }
-       }
-
-       private void modifyFilter(boolean fromOutside) {
-               if (!fromOutside)
-                       if (currEdited != null) {
-                               String filter = filterTxt.getText() + "*";
-                               FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited));
-                               if (table != null && !table.isDisposed())
-                                       table.filterList(filter);
-                       }
-
-       }
-
-       private String getPath(Node node) {
-               try {
-                       return node.getPath();
-               } catch (RepositoryException e) {
-                       throw new CmsException("Unable to get path for node " + node, e);
-               }
-       }
-
-       private Cms2DSize imageWidth = new Cms2DSize(250, 0);
-
-       /**
-        * Recreates the content of the box that displays information about the current
-        * selected node.
-        */
-       private Control createNodeView(Composite parent, Node context) throws RepositoryException {
-
-               parent.setLayout(new GridLayout(2, false));
-
-               if (isImg(context)) {
-                       EditableImage image = new Img(parent, RIGHT, context, imageWidth);
-                       image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 2, 1));
-               }
-
-               // Name and primary type
-               Label contextL = new Label(parent, SWT.NONE);
-               CmsSwtUtils.markup(contextL);
-               contextL.setText("<b>" + context.getName() + "</b>");
-               new Label(parent, SWT.NONE).setText(context.getPrimaryNodeType().getName());
-
-               // Children
-               for (NodeIterator nIt = context.getNodes(); nIt.hasNext();) {
-                       Node child = nIt.nextNode();
-                       new CmsLink(child.getName(), BROWSE_PREFIX + child.getPath()).createUi(parent, context);
-                       new Label(parent, SWT.NONE).setText(child.getPrimaryNodeType().getName());
-               }
-
-               // Properties
-               for (PropertyIterator pIt = context.getProperties(); pIt.hasNext();) {
-                       Property property = pIt.nextProperty();
-                       Label label = new Label(parent, SWT.NONE);
-                       label.setText(property.getName());
-                       label.setToolTipText(JcrUtils.getPropertyDefinitionAsString(property));
-                       new Label(parent, SWT.NONE).setText(getPropAsString(property));
-               }
-
-               return null;
-       }
-
-       private boolean isImg(Node node) throws RepositoryException {
-               // TODO support images
-               return false;
-//             return node.hasNode(JCR_CONTENT) && node.isNodeType(CmsTypes.CMS_IMAGE);
-       }
-
-       private String getPropAsString(Property property) throws RepositoryException {
-               String result = "";
-               if (property.isMultiple()) {
-                       result = getMultiAsString(property, ", ");
-               } else {
-                       Value value = property.getValue();
-                       if (value.getType() == PropertyType.BINARY)
-                               result = "<binary>";
-                       else if (value.getType() == PropertyType.DATE)
-                               result = timeFormatter.format(value.getDate().getTime());
-                       else
-                               result = value.getString();
-               }
-               return result;
-       }
-
-       private String getMultiAsString(Property property, String separator) throws RepositoryException {
-               if (separator == null)
-                       separator = "; ";
-               Value[] values = property.getValues();
-               StringBuilder builder = new StringBuilder();
-               for (Value val : values) {
-                       String currStr = val.getString();
-                       if (!"".equals(currStr.trim()))
-                               builder.append(currStr).append(separator);
-               }
-               if (builder.lastIndexOf(separator) >= 0)
-                       return builder.substring(0, builder.length() - separator.length());
-               else
-                       return builder.toString();
-       }
-
-       /** Almost canonical implementation of a table that display entities */
-       private class FilterEntitiesVirtualTable extends Composite {
-               private static final long serialVersionUID = 8798147431706283824L;
-
-               // Context
-               private Node context;
-
-               // UI Objects
-               private TableViewer entityViewer;
-
-               // enable management of multiple columns
-               Node getNode() {
-                       return context;
-               }
-
-               @Override
-               public boolean setFocus() {
-                       if (entityViewer.getTable().isDisposed())
-                               return false;
-                       if (entityViewer.getSelection().isEmpty()) {
-                               Object first = entityViewer.getElementAt(0);
-                               if (first != null) {
-                                       entityViewer.setSelection(new StructuredSelection(first), true);
-                               }
-                       }
-                       return entityViewer.getTable().setFocus();
-               }
-
-               void filterList(String filter) {
-                       try {
-                               NodeIterator nit = context.getNodes(filter);
-                               refreshFilteredList(nit);
-                       } catch (RepositoryException e) {
-                               throw new CmsException("Unable to filter " + getNode() + " children with filter " + filter, e);
-                       }
-
-               }
-
-               public FilterEntitiesVirtualTable(Composite parent, int style, Node context) {
-                       super(parent, SWT.NO_FOCUS);
-                       this.context = context;
-                       populate();
-               }
-
-               protected void populate() {
-                       Composite parent = this;
-                       GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
-
-                       this.setLayout(layout);
-                       createTableViewer(parent);
-               }
-
-               private void createTableViewer(final Composite parent) {
-                       // the list
-                       // We must limit the size of the table otherwise the full list is
-                       // loaded
-                       // before the layout happens
-                       Composite listCmp = new Composite(parent, SWT.NO_FOCUS);
-                       GridData gd = new GridData(SWT.LEFT, SWT.FILL, false, true);
-                       gd.widthHint = COLUMN_WIDTH;
-                       listCmp.setLayoutData(gd);
-                       listCmp.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
-                       entityViewer = new TableViewer(listCmp, SWT.VIRTUAL | SWT.SINGLE);
-                       Table table = entityViewer.getTable();
-
-                       table.setLayoutData(CmsSwtUtils.fillAll());
-                       table.setLinesVisible(true);
-                       table.setHeaderVisible(false);
-                       CmsSwtUtils.markup(table);
-
-                       CmsSwtUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
-
-                       // first column
-                       TableViewerColumn column = new TableViewerColumn(entityViewer, SWT.NONE);
-                       TableColumn tcol = column.getColumn();
-                       tcol.setWidth(COLUMN_WIDTH);
-                       tcol.setResizable(true);
-                       column.setLabelProvider(new SimpleNameLP());
-
-                       entityViewer.setContentProvider(new MyLazyCP(entityViewer));
-                       entityViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
-                               @Override
-                               public void selectionChanged(SelectionChangedEvent event) {
-                                       IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection();
-                                       if (selection.isEmpty())
-                                               return;
-                                       else
-                                               setEdited((Node) selection.getFirstElement());
-
-                               }
-                       });
-
-                       table.addKeyListener(new KeyListener() {
-                               private static final long serialVersionUID = -330694313896036230L;
-
-                               @Override
-                               public void keyReleased(KeyEvent e) {
-                               }
-
-                               @Override
-                               public void keyPressed(KeyEvent e) {
-
-                                       IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection();
-                                       Node selected = null;
-                                       if (!selection.isEmpty())
-                                               selected = ((Node) selection.getFirstElement());
-                                       try {
-                                               if (e.keyCode == SWT.ARROW_RIGHT) {
-                                                       if (selected != null) {
-                                                               setEdited(selected);
-                                                               browserCols.get(selected.getPath()).setFocus();
-                                                       }
-                                               } else if (e.keyCode == SWT.ARROW_LEFT) {
-                                                       try {
-                                                               selected = getNode().getParent();
-                                                               String newPath = selected.getPath(); // getNode().getParent()
-                                                               setEdited(selected);
-                                                               if (browserCols.containsKey(newPath))
-                                                                       browserCols.get(newPath).setFocus();
-                                                       } catch (ItemNotFoundException ie) {
-                                                               // root silent
-                                                       }
-                                               }
-                                       } catch (RepositoryException ie) {
-                                               throw new CmsException("Error while managing arrow " + "events in the browser for " + selected,
-                                                               ie);
-                                       }
-                               }
-                       });
-               }
-
-               private class MyLazyCP implements ILazyContentProvider {
-                       private static final long serialVersionUID = 1L;
-                       private TableViewer viewer;
-                       private Object[] elements;
-
-                       public MyLazyCP(TableViewer viewer) {
-                               this.viewer = viewer;
-                       }
-
-                       public void dispose() {
-                       }
-
-                       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-                               // IMPORTANT: don't forget this: an exception will be thrown if
-                               // a selected object is not part of the results anymore.
-                               viewer.setSelection(null);
-                               this.elements = (Object[]) newInput;
-                       }
-
-                       public void updateElement(int index) {
-                               viewer.replace(elements[index], index);
-                       }
-               }
-
-               protected void refreshFilteredList(NodeIterator children) {
-                       Object[] rows = JcrUtils.nodeIteratorToList(children).toArray();
-                       entityViewer.setInput(rows);
-                       entityViewer.setItemCount(rows.length);
-                       entityViewer.refresh();
-               }
-
-               public class SimpleNameLP extends ColumnLabelProvider {
-                       private static final long serialVersionUID = 2465059387875338553L;
-
-                       @Override
-                       public String getText(Object element) {
-                               if (element instanceof Node) {
-                                       Node curr = ((Node) element);
-                                       try {
-                                               return curr.getName();
-                                       } catch (RepositoryException e) {
-                                               throw new CmsException("Unable to get name for" + curr);
-                                       }
-                               }
-                               return super.getText(element);
-                       }
-               }
-       }
-}
\ No newline at end of file
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/ConnectivityDeploymentUi.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/ConnectivityDeploymentUi.java
deleted file mode 100644 (file)
index 97f3e67..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.http.HttpService;
-import org.osgi.service.useradmin.UserAdmin;
-
-class ConnectivityDeploymentUi extends AbstractOsgiComposite {
-       private static final long serialVersionUID = 590221539553514693L;
-
-       public ConnectivityDeploymentUi(Composite parent, int style) {
-               super(parent, style);
-       }
-
-       @Override
-       protected void initUi(int style) {
-               StringBuffer text = new StringBuffer();
-               text.append("<span style='font-variant: small-caps;'>Provided Servers</span><br/>");
-
-               ServiceReference<HttpService> userAdminRef = bc.getServiceReference(HttpService.class);
-               if (userAdminRef != null) {
-                       // FIXME use constants
-                       Object httpPort = userAdminRef.getProperty("http.port");
-                       Object httpsPort = userAdminRef.getProperty("https.port");
-                       if (httpPort != null)
-                               text.append("<b>http</b> ").append(httpPort).append("<br/>");
-                       if (httpsPort != null)
-                               text.append("<b>https</b> ").append(httpsPort).append("<br/>");
-
-               }
-
-               text.append("<br/>");
-               text.append("<span style='font-variant: small-caps;'>Referenced Servers</span><br/>");
-
-               Label label = new Label(this, SWT.NONE);
-               label.setData(new GridData(SWT.FILL, SWT.FILL, false, false));
-               CmsSwtUtils.markup(label);
-               label.setText(text.toString());
-       }
-
-       protected boolean isDeployed() {
-               return bc.getServiceReference(UserAdmin.class) != null;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java
deleted file mode 100644 (file)
index ef95bde..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileStore;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collection;
-
-import org.apache.jackrabbit.core.RepositoryContext;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.osgi.framework.ServiceReference;
-
-class DataDeploymentUi extends AbstractOsgiComposite {
-       private static final long serialVersionUID = 590221539553514693L;
-
-       public DataDeploymentUi(Composite parent, int style) {
-               super(parent, style);
-       }
-
-       @Override
-       protected void initUi(int style) {
-               if (isDeployed()) {
-                       initCurrentUi(this);
-               } else {
-                       initNewUi(this);
-               }
-       }
-
-       private void initNewUi(Composite parent) {
-//             try {
-//                     ConfigurationAdmin confAdmin = bc.getService(bc.getServiceReference(ConfigurationAdmin.class));
-//                     Configuration[] confs = confAdmin.listConfigurations(
-//                                     "(" + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + NodeConstants.NODE_REPOS_FACTORY_PID + ")");
-//                     if (confs == null || confs.length == 0) {
-//                             Group buttonGroup = new Group(parent, SWT.NONE);
-//                             buttonGroup.setText("Repository Type");
-//                             buttonGroup.setLayout(new GridLayout(2, true));
-//                             buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-//
-//                             SelectionListener selectionListener = new SelectionAdapter() {
-//                                     private static final long serialVersionUID = 6247064348421088092L;
-//
-//                                     public void widgetSelected(SelectionEvent event) {
-//                                             Button radio = (Button) event.widget;
-//                                             if (!radio.getSelection())
-//                                                     return;
-//                                             log.debug(event);
-//                                             JackrabbitType nodeType = (JackrabbitType) radio.getData();
-//                                             if (log.isDebugEnabled())
-//                                                     log.debug(" selected = " + nodeType.name());
-//                                     };
-//                             };
-//
-//                             for (JackrabbitType nodeType : JackrabbitType.values()) {
-//                                     Button radio = new Button(buttonGroup, SWT.RADIO);
-//                                     radio.setText(nodeType.name());
-//                                     radio.setData(nodeType);
-//                                     if (nodeType.equals(JackrabbitType.localfs))
-//                                             radio.setSelection(true);
-//                                     radio.addSelectionListener(selectionListener);
-//                             }
-//
-//                     } else if (confs.length == 1) {
-//
-//                     } else {
-//                             throw new CmsException("Multiple repos not yet supported");
-//                     }
-//             } catch (Exception e) {
-//                     throw new CmsException("Cannot initialize UI", e);
-//             }
-
-       }
-
-       private void initCurrentUi(Composite parent) {
-               parent.setLayout(new GridLayout());
-               Collection<ServiceReference<RepositoryContext>> contexts = getServiceReferences(RepositoryContext.class,
-                               "(" + 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(CmsConstants.CN).toString();
-                       String rootNodeId = repositoryContext.getRootNodeId().toString();
-                       RepositoryConfig repositoryConfig = repositoryContext.getRepositoryConfig();
-                       Path repoHomePath = new File(repositoryConfig.getHomeDir()).toPath().toAbsolutePath();
-                       // TODO check data store
-
-                       text.append("<b>" + alias + "</b><br/>");
-                       text.append("rootNodeId: " + rootNodeId + "<br/>");
-                       try {
-                               FileStore fileStore = Files.getFileStore(repoHomePath);
-                               text.append("partition: " + fileStore.toString() + "<br/>");
-                               text.append(
-                                               percentUsed(fileStore) + " used (" + humanReadable(fileStore.getUsableSpace()) + " free)<br/>");
-                       } catch (IOException e) {
-                               log.error("Cannot check fileStore for " + repoHomePath, e);
-                       }
-               }
-               Label label = new Label(parent, SWT.NONE);
-               label.setData(new GridData(SWT.FILL, SWT.FILL, false, false));
-               CmsSwtUtils.markup(label);
-               label.setText("<span style=''>" + text.toString() + "</span>");
-       }
-
-       private String humanReadable(long bytes) {
-               long mb = bytes / (1024 * 1024);
-               return mb >= 2048 ? Long.toString(mb / 1024) + " GB" : Long.toString(mb) + " MB";
-       }
-
-       private String percentUsed(FileStore fs) throws IOException {
-               long used = fs.getTotalSpace() - fs.getUnallocatedSpace();
-               long percent = used * 100 / fs.getTotalSpace();
-               if (log.isTraceEnabled()) {
-                       // output identical to `df -B 1`)
-                       log.trace(fs.getTotalSpace() + "," + used + "," + fs.getUsableSpace());
-               }
-               String span;
-               if (percent < 80)
-                       span = "<span style='color:green;font-weight:bold'>";
-               else if (percent < 95)
-                       span = "<span style='color:orange;font-weight:bold'>";
-               else
-                       span = "<span style='color:red;font-weight:bold'>";
-               return span + percent + "%</span>";
-       }
-
-       protected boolean isDeployed() {
-               return bc.getServiceReference(RepositoryContext.class) != null;
-       }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java
deleted file mode 100644 (file)
index 0a28dc5..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import java.util.GregorianCalendar;
-import java.util.TimeZone;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsContext;
-import org.argeo.api.cms.CmsDeployment;
-import org.argeo.api.cms.CmsState;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-
-class DeploymentEntryPoint {
-       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-       protected void createContents(Composite parent) {
-               // FIXME manage authentication if needed
-               // if (!CurrentUser.roles().contains(AuthConstants.ROLE_ADMIN))
-               // return;
-
-               // parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               if (isDesktop()) {
-                       parent.setLayout(new GridLayout(2, true));
-               } else {
-                       // TODO add scrolling
-                       parent.setLayout(new GridLayout(1, true));
-               }
-
-               initHighLevelSummary(parent);
-
-               Group securityGroup = createHighLevelGroup(parent, "Security");
-               securityGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-               new SecurityDeploymentUi(securityGroup, SWT.NONE);
-
-               Group dataGroup = createHighLevelGroup(parent, "Data");
-               dataGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-               new DataDeploymentUi(dataGroup, SWT.NONE);
-
-               Group logGroup = createHighLevelGroup(parent, "Notifications");
-               logGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
-               new LogDeploymentUi(logGroup, SWT.NONE);
-
-               Group connectivityGroup = createHighLevelGroup(parent, "Connectivity");
-               new ConnectivityDeploymentUi(connectivityGroup, SWT.NONE);
-               connectivityGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
-
-       }
-
-       private void initHighLevelSummary(Composite parent) {
-               Composite composite = new Composite(parent, SWT.NONE);
-               GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
-               if (isDesktop())
-                       gridData.horizontalSpan = 3;
-               composite.setLayoutData(gridData);
-               composite.setLayout(new FillLayout());
-
-               ServiceReference<CmsState> nodeStateRef = bc.getServiceReference(CmsState.class);
-               if (nodeStateRef == null)
-                       throw new IllegalStateException("No CMS state available");
-               CmsState nodeState = bc.getService(nodeStateRef);
-               ServiceReference<CmsContext> nodeDeploymentRef = bc.getServiceReference(CmsContext.class);
-               Label label = new Label(composite, SWT.WRAP);
-               CmsSwtUtils.markup(label);
-               if (nodeDeploymentRef == null) {
-                       label.setText("Not yet deployed on, please configure below.");
-               } else {
-                       Object stateUuid = nodeStateRef.getProperty(CmsConstants.CN);
-                       CmsContext nodeDeployment = bc.getService(nodeDeploymentRef);
-                       GregorianCalendar calendar = new GregorianCalendar();
-                       calendar.setTimeInMillis(nodeDeployment.getAvailableSince());
-                       calendar.setTimeZone(TimeZone.getDefault());
-                       label.setText("Deployment state " + stateUuid + ", available since <b>" + calendar.getTime() + "</b>");
-               }
-       }
-
-       private static Group createHighLevelGroup(Composite parent, String text) {
-               Group group = new Group(parent, SWT.NONE);
-               group.setText(text);
-               CmsSwtUtils.markup(group);
-               return group;
-       }
-
-       private boolean isDesktop() {
-               return true;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/LogDeploymentUi.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/LogDeploymentUi.java
deleted file mode 100644 (file)
index fa5d3da..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Enumeration;
-import java.util.GregorianCalendar;
-import java.util.TimeZone;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Text;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogListener;
-import org.osgi.service.log.LogReaderService;
-
-class LogDeploymentUi extends AbstractOsgiComposite implements LogListener {
-       private static final long serialVersionUID = 590221539553514693L;
-
-       private DateFormat dateFormat = new SimpleDateFormat("MMdd HH:mm");
-
-       private Display display;
-       private Text logDisplay;
-
-       public LogDeploymentUi(Composite parent, int style) {
-               super(parent, style);
-       }
-
-       @Override
-       protected void initUi(int style) {
-               LogReaderService logReader = getService(LogReaderService.class);
-               // FIXME use server push
-               // logReader.addLogListener(this);
-               this.display = getDisplay();
-               this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               logDisplay = new Text(this, SWT.WRAP | SWT.MULTI | SWT.READ_ONLY);
-               logDisplay.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               CmsSwtUtils.markup(logDisplay);
-               Enumeration<LogEntry> logEntries = (Enumeration<LogEntry>) logReader.getLog();
-               while (logEntries.hasMoreElements())
-                       logDisplay.append(printEntry(logEntries.nextElement()));
-       }
-
-       private String printEntry(LogEntry entry) {
-               StringBuilder sb = new StringBuilder();
-               GregorianCalendar calendar = new GregorianCalendar(TimeZone.getDefault());
-               calendar.setTimeInMillis(entry.getTime());
-               sb.append(dateFormat.format(calendar.getTime())).append(' ');
-               sb.append(entry.getMessage());
-               sb.append('\n');
-               return sb.toString();
-       }
-
-       @Override
-       public void logged(LogEntry entry) {
-               if (display.isDisposed())
-                       return;
-               display.asyncExec(() -> {
-                       if (logDisplay.isDisposed())
-                               return;
-                       logDisplay.append(printEntry(entry));
-               });
-               display.wake();
-       }
-
-       // @Override
-       // public void dispose() {
-       // super.dispose();
-       // getService(LogReaderService.class).removeLogListener(this);
-       // }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/MaintenanceStyles.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/MaintenanceStyles.java
deleted file mode 100644 (file)
index df1be51..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-/** Specific styles used by the various maintenance pages . */
-public interface MaintenanceStyles {
-       // General
-       public final static String PREFIX = "maintenance_";
-
-       // Browser
-       public final static String BROWSER_COLUMN = "browser_column";
-       }
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/NonAdminPage.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/NonAdminPage.java
deleted file mode 100644 (file)
index cb38ce8..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-
-public class NonAdminPage implements CmsUiProvider{
-
-       @Override
-       public Control createUi(Composite parent, Node context)
-                       throws RepositoryException {
-               Composite body = new Composite(parent, SWT.NO_FOCUS);
-               body.setLayoutData(CmsSwtUtils.fillAll());
-               body.setLayout(new GridLayout());
-               Label label = new Label(body, SWT.NONE);
-               label.setText("You should be an admin to perform maintenance operations. "
-                               + "Are you sure you are logged in?");
-               label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
-               return null;
-       }
-       
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/SecurityDeploymentUi.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/SecurityDeploymentUi.java
deleted file mode 100644 (file)
index 3492c54..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.argeo.cms.e4.maintenance;
-
-import java.net.URI;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.UserAdmin;
-
-class SecurityDeploymentUi extends AbstractOsgiComposite {
-       private static final long serialVersionUID = 590221539553514693L;
-
-       public SecurityDeploymentUi(Composite parent, int style) {
-               super(parent, style);
-       }
-
-       @Override
-       protected void initUi(int style) {
-               if (isDeployed()) {
-                       initCurrentUi(this);
-               } else {
-                       initNewUi(this);
-               }
-       }
-
-       private void initNewUi(Composite parent) {
-               new Label(parent, SWT.NONE).setText("Security is not configured");
-       }
-
-       private void initCurrentUi(Composite parent) {
-               ServiceReference<UserAdmin> userAdminRef = bc.getServiceReference(UserAdmin.class);
-               UserAdmin userAdmin = bc.getService(userAdminRef);
-               StringBuffer text = new StringBuffer();
-               text.append("<span style='font-variant: small-caps;'>Domains</span><br/>");
-               domains: for (String key : userAdminRef.getPropertyKeys()) {
-                       if (!key.startsWith("/"))
-                               continue domains;
-                       URI uri;
-                       try {
-                               uri = new URI(key);
-                       } catch (Exception e) {
-                               // ignore non URI keys
-                               continue domains;
-                       }
-
-                       String rootDn = uri.getPath().substring(1, uri.getPath().length());
-                       // FIXME make reading query options more robust, using utils
-                       boolean readOnly = uri.getQuery().equals("readOnly=true");
-                       if (readOnly)
-                               text.append("<span style='font-weight:bold;font-style: italic'>");
-                       else
-                               text.append("<span style='font-weight:bold'>");
-
-                       text.append(rootDn);
-                       text.append("</span><br/>");
-                       try {
-                               Role[] roles = userAdmin.getRoles("(dn=*," + rootDn + ")");
-                               long userCount = 0;
-                               long groupCount = 0;
-                               for (Role role : roles) {
-                                       if (role.getType() == Role.USER)
-                                               userCount++;
-                                       else
-                                               groupCount++;
-                               }
-                               text.append(" " + userCount + " users, " + groupCount +" groups.<br/>");
-                       } catch (InvalidSyntaxException e) {
-                               log.error("Invalid syntax", e);
-                       }
-               }
-               Label label = new Label(parent, SWT.NONE);
-               label.setData(new GridData(SWT.FILL, SWT.FILL, false, false));
-               CmsSwtUtils.markup(label);
-               label.setText(text.toString());
-       }
-
-       protected boolean isDeployed() {
-               return bc.getServiceReference(UserAdmin.class) != null;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/package-info.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/package-info.java
deleted file mode 100644 (file)
index e4d2ad4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Maintenance perspective. */
-package org.argeo.cms.e4.maintenance;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java
deleted file mode 100644 (file)
index 137f762..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-
-import org.argeo.cms.auth.UserAdminUtils;
-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.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;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.osgi.service.useradmin.Authorization;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Editor for a user, might be a user or a group. */
-public abstract class AbstractRoleEditor {
-
-       // public final static String USER_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID +
-       // ".userEditor";
-       // public final static String GROUP_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID +
-       // ".groupEditor";
-
-       /* DEPENDENCY INJECTION */
-       @Inject
-       protected UserAdminWrapper userAdminWrapper;
-
-       @Inject
-       private MPart mPart;
-
-       // @Inject
-       // Composite parent;
-
-       private UserAdmin userAdmin;
-
-       // Context
-       private User user;
-       private String username;
-
-       private NameChangeListener listener;
-
-       private ManagedForm managedForm;
-
-       // public void init(IEditorSite site, IEditorInput input) throws
-       // PartInitException {
-       @PostConstruct
-       public void init(Composite parent) {
-               this.userAdmin = userAdminWrapper.getUserAdmin();
-               username = mPart.getPersistedState().get(LdapAttrs.uid.name());
-               user = (User) userAdmin.getRole(username);
-
-               listener = new NameChangeListener(Display.getCurrent());
-               userAdminWrapper.addListener(listener);
-               updateEditorTitle(null);
-
-               managedForm = new ManagedForm(parent) {
-
-                       @Override
-                       public void staleStateChanged() {
-                               refresh();
-                       }
-               };
-               ScrolledComposite scrolled = managedForm.getForm();
-               Composite body = new Composite(scrolled, SWT.NONE);
-               scrolled.setContent(body);
-               createUi(body);
-               managedForm.refresh();
-       }
-
-       abstract void createUi(Composite parent);
-
-       /**
-        * returns the list of all authorizations for the given user or of the current
-        * displayed user if parameter is null
-        */
-       protected List<User> getFlatGroups(User aUser) {
-               Authorization currAuth;
-               if (aUser == null)
-                       currAuth = userAdmin.getAuthorization(this.user);
-               else
-                       currAuth = userAdmin.getAuthorization(aUser);
-
-               String[] roles = currAuth.getRoles();
-
-               List<User> groups = new ArrayList<User>();
-               for (String roleStr : roles) {
-                       User currRole = (User) userAdmin.getRole(roleStr);
-                       if (currRole != null && !groups.contains(currRole))
-                               groups.add(currRole);
-               }
-               return groups;
-       }
-
-       protected IManagedForm getManagedForm() {
-               return managedForm;
-       }
-
-       /** Exposes the user (or group) that is displayed by the current editor */
-       protected User getDisplayedUser() {
-               return user;
-       }
-
-       private void setDisplayedUser(User user) {
-               this.user = user;
-       }
-
-       void updateEditorTitle(String title) {
-               if (title == null) {
-                       String commonName = UserAdminUtils.getProperty(user, LdapAttrs.cn.name());
-                       title = "".equals(commonName) ? user.getName() : commonName;
-               }
-               setPartName(title);
-       }
-
-       protected void setPartName(String name) {
-               mPart.setLabel(name);
-       }
-
-       // protected void addPages() {
-       // try {
-       // if (user.getType() == Role.GROUP)
-       // addPage(new GroupMainPage(this, userAdminWrapper, repository, nodeInstance));
-       // else
-       // addPage(new UserMainPage(this, userAdminWrapper));
-       // } catch (Exception e) {
-       // throw new CmsException("Cannot add pages", e);
-       // }
-       // }
-
-       @Persist
-       public void doSave(IProgressMonitor monitor) {
-               userAdminWrapper.beginTransactionIfNeeded();
-               commitPages(true);
-               userAdminWrapper.commitOrNotifyTransactionStateChange();
-               // firePropertyChange(PROP_DIRTY);
-               userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, user));
-       }
-
-       protected void commitPages(boolean b) {
-               managedForm.commit(b);
-       }
-
-       @PreDestroy
-       public void dispose() {
-               userAdminWrapper.removeListener(listener);
-               managedForm.dispose();
-       }
-
-       // CONTROLERS FOR THIS EDITOR AND ITS PAGES
-
-       class NameChangeListener extends UiUserAdminListener {
-               public NameChangeListener(Display display) {
-                       super(display);
-               }
-
-               @Override
-               public void roleChangedToUiThread(UserAdminEvent event) {
-                       Role changedRole = event.getRole();
-                       if (changedRole == null || changedRole.equals(user)) {
-                               updateEditorTitle(null);
-                               User reloadedUser = (User) userAdminWrapper.getUserAdmin().getRole(user.getName());
-                               setDisplayedUser(reloadedUser);
-                       }
-               }
-       }
-
-       class MainInfoListener extends UiUserAdminListener {
-               private final AbstractFormPart part;
-
-               public MainInfoListener(Display display, AbstractFormPart part) {
-                       super(display);
-                       this.part = part;
-               }
-
-               @Override
-               public void roleChangedToUiThread(UserAdminEvent event) {
-                       // Rollback
-                       if (event.getRole() == null)
-                               part.markStale();
-               }
-       }
-
-       class GroupChangeListener extends UiUserAdminListener {
-               private final AbstractFormPart part;
-
-               public GroupChangeListener(Display display, AbstractFormPart part) {
-                       super(display);
-                       this.part = part;
-               }
-
-               @Override
-               public void roleChangedToUiThread(UserAdminEvent event) {
-                       // always mark as stale
-                       part.markStale();
-               }
-       }
-
-       /** Registers a listener that will notify this part */
-       class FormPartML implements ModifyListener {
-               private static final long serialVersionUID = 6299808129505381333L;
-               private AbstractFormPart formPart;
-
-               public FormPartML(AbstractFormPart generalPart) {
-                       this.formPart = generalPart;
-               }
-
-               public void modifyText(ModifyEvent e) {
-                       // Discard event when the control does not have the focus, typically
-                       // to avoid all editors being marked as dirty during a Rollback
-                       if (((Control) e.widget).isFocusControl())
-                               formPart.markDirty();
-               }
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
-               this.userAdminWrapper = userAdminWrapper;
-       }
-
-       /** Creates label and multiline text. */
-       Text createLMT(Composite parent, String label, String value) {
-               Label lbl = new Label(parent, SWT.NONE);
-               lbl.setText(label);
-               lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
-               Text text = new Text(parent, SWT.NONE);
-               text.setText(value);
-               text.setLayoutData(new GridData(SWT.LEAD, SWT.FILL, true, true));
-               return text;
-       }
-
-       /** Creates label and password. */
-       Text createLP(Composite parent, String label, String value) {
-               Label lbl = new Label(parent, SWT.NONE);
-               lbl.setText(label);
-               lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
-               Text text = new Text(parent, SWT.PASSWORD | SWT.BORDER);
-               text.setText(value);
-               text.setLayoutData(new GridData(SWT.LEAD, SWT.FILL, true, false));
-               return text;
-       }
-
-       /** Creates label and text. */
-       Text createLT(Composite parent, String label, String value) {
-               Label lbl = new Label(parent, SWT.NONE);
-               lbl.setText(label);
-               lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
-               lbl.setFont(EclipseUiUtils.getBoldFont(parent));
-               Text text = new Text(parent, SWT.BORDER);
-               text.setText(value);
-               text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-               // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
-               return text;
-       }
-
-       Text createReadOnlyLT(Composite parent, String label, String value) {
-               Label lbl = new Label(parent, SWT.NONE);
-               lbl.setText(label);
-               lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
-               lbl.setFont(EclipseUiUtils.getBoldFont(parent));
-               Text text = new Text(parent, SWT.NONE);
-               text.setText(value);
-               text.setLayoutData(new GridData(SWT.LEAD, SWT.FILL, true, false));
-               text.setEditable(false);
-               // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
-               return text;
-       }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/CmsWorkbenchStyles.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/CmsWorkbenchStyles.java
deleted file mode 100644 (file)
index 07df312..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.argeo.cms.e4.users;
-
-/** Centralize the declaration of Workbench specific CSS Styles */
-interface CmsWorkbenchStyles {
-
-       // Specific People layouting
-       String WORKBENCH_FORM_TEXT = "workbench_form_text";
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java
deleted file mode 100644 (file)
index d54f8bc..0000000
+++ /dev/null
@@ -1,566 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import static org.argeo.api.cms.CmsContext.WORKGROUP;
-import static org.argeo.cms.auth.UserAdminUtils.setProperty;
-import static org.argeo.util.naming.LdapAttrs.businessCategory;
-import static org.argeo.util.naming.LdapAttrs.description;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsContext;
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.cms.e4.users.providers.CommonNameLP;
-import org.argeo.cms.e4.users.providers.MailLP;
-import org.argeo.cms.e4.users.providers.RoleIconLP;
-import org.argeo.cms.e4.users.providers.UserFilter;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
-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.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.util.naming.LdapAttrs;
-import org.argeo.util.transaction.WorkTransaction;
-import org.eclipse.e4.ui.workbench.modeling.EPartService;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.ViewerDropAdapter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.DropTargetEvent;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.dnd.TransferData;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.ToolBar;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.Role;
-//import org.eclipse.ui.forms.AbstractFormPart;
-//import org.eclipse.ui.forms.IManagedForm;
-//import org.eclipse.ui.forms.SectionPart;
-//import org.eclipse.ui.forms.editor.FormEditor;
-//import org.eclipse.ui.forms.editor.FormPage;
-//import org.eclipse.ui.forms.widgets.FormToolkit;
-//import org.eclipse.ui.forms.widgets.ScrolledForm;
-//import org.eclipse.ui.forms.widgets.Section;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Display/edit main properties of a given group */
-public class GroupEditor extends AbstractRoleEditor {
-       // final static String ID = "GroupEditor.mainPage";
-
-       @Inject
-       private EPartService partService;
-
-       // private final UserEditor editor;
-       @Inject
-       private Repository repository;
-       @Inject
-       private CmsContext nodeInstance;
-       // private final UserAdminWrapper userAdminWrapper;
-       private Session groupsSession;
-
-       // public GroupMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper,
-       // Repository repository,
-       // NodeInstance nodeInstance) {
-       // super(editor, ID, "Main");
-       // try {
-       // session = repository.login();
-       // } catch (RepositoryException e) {
-       // throw new CmsException("Cannot retrieve session of in MainGroupPage
-       // constructor", e);
-       // }
-       // this.editor = (UserEditor) editor;
-       // this.userAdminWrapper = userAdminWrapper;
-       // this.nodeInstance = nodeInstance;
-       // }
-
-       // protected void createFormContent(final IManagedForm mf) {
-       // ScrolledForm form = mf.getForm();
-       // Composite body = form.getBody();
-       // GridLayout mainLayout = new GridLayout();
-       // body.setLayout(mainLayout);
-       // Group group = (Group) editor.getDisplayedUser();
-       // appendOverviewPart(body, group);
-       // appendMembersPart(body, group);
-       // }
-
-       @Override
-       protected void createUi(Composite parent) {
-               try {
-                       groupsSession = repository.login(CmsConstants.SRV_WORKSPACE);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve session", e);
-               }
-               // ScrolledForm form = mf.getForm();
-               // Composite body = form.getBody();
-               // Composite body = new Composite(parent, SWT.NONE);
-               Composite body = parent;
-               GridLayout mainLayout = new GridLayout();
-               body.setLayout(mainLayout);
-               Group group = (Group) getDisplayedUser();
-               appendOverviewPart(body, group);
-               appendMembersPart(body, group);
-       }
-
-       @PreDestroy
-       public void dispose() {
-               JcrUtils.logoutQuietly(groupsSession);
-               super.dispose();
-       }
-
-       /** Creates the general section */
-       protected void appendOverviewPart(final Composite parent, final Group group) {
-               Composite body = new Composite(parent, SWT.NONE);
-               // GridLayout layout = new GridLayout(5, false);
-               GridLayout layout = new GridLayout(2, false);
-               body.setLayout(layout);
-               body.setLayoutData(CmsSwtUtils.fillWidth());
-
-               String cn = UserAdminUtils.getProperty(group, LdapAttrs.cn.name());
-               createReadOnlyLT(body, "Name", cn);
-               createReadOnlyLT(body, "DN", group.getName());
-               createReadOnlyLT(body, "Domain", UserAdminUtils.getDomainName(group));
-
-               // Description
-               Label descLbl = new Label(body, SWT.LEAD);
-               descLbl.setFont(EclipseUiUtils.getBoldFont(body));
-               descLbl.setText("Description");
-               descLbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, true, false, 2, 1));
-               final Text descTxt = new Text(body, SWT.LEAD | SWT.MULTI | SWT.WRAP | SWT.BORDER);
-               GridData gd = EclipseUiUtils.fillWidth();
-               gd.heightHint = 50;
-               gd.horizontalSpan = 2;
-               descTxt.setLayoutData(gd);
-
-               // Mark as workgroup
-               Link markAsWorkgroupLk = new Link(body, SWT.NONE);
-               markAsWorkgroupLk.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
-
-               // create form part (controller)
-               final AbstractFormPart part = new AbstractFormPart() {
-
-                       private MainInfoListener listener;
-
-                       @Override
-                       public void initialize(IManagedForm form) {
-                               super.initialize(form);
-                               listener = new MainInfoListener(parent.getDisplay(), this);
-                               userAdminWrapper.addListener(listener);
-                       }
-
-                       @Override
-                       public void dispose() {
-                               userAdminWrapper.removeListener(listener);
-                               super.dispose();
-                       }
-
-                       public void commit(boolean onSave) {
-                               // group.getProperties().put(LdapAttrs.description.name(), descTxt.getText());
-                               setProperty(group, description, descTxt.getText());
-                               super.commit(onSave);
-                       }
-
-                       @Override
-                       public void refresh() {
-                               // dnTxt.setText(group.getName());
-                               // cnTxt.setText(UserAdminUtils.getProperty(group, LdapAttrs.cn.name()));
-                               descTxt.setText(UserAdminUtils.getProperty(group, LdapAttrs.description.name()));
-                               Node workgroupHome = CmsJcrUtils.getGroupHome(groupsSession, cn);
-                               if (workgroupHome == null)
-                                       markAsWorkgroupLk.setText("<a>Mark as workgroup</a>");
-                               else
-                                       markAsWorkgroupLk.setText("Configured as workgroup");
-                               parent.layout(true, true);
-                               super.refresh();
-                       }
-               };
-
-               markAsWorkgroupLk.addSelectionListener(new SelectionAdapter() {
-                       private static final long serialVersionUID = -6439340898096365078L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-
-                               boolean confirmed = MessageDialog.openConfirm(parent.getShell(), "Mark as workgroup",
-                                               "Are you sure you want to mark " + cn + " as being a workgroup? ");
-                               if (confirmed) {
-                                       Node workgroupHome = CmsJcrUtils.getGroupHome(groupsSession, cn);
-                                       if (workgroupHome != null)
-                                               return; // already marked as workgroup, do nothing
-                                       else {
-                                               // improve transaction management
-                                               userAdminWrapper.beginTransactionIfNeeded();
-                                               nodeInstance.createWorkgroup(group.getName());
-                                               setProperty(group, businessCategory, WORKGROUP);
-                                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                                               userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group));
-                                               part.refresh();
-                                       }
-                               }
-                       }
-               });
-
-               ModifyListener defaultListener = new FormPartML(part);
-               descTxt.addModifyListener(defaultListener);
-               getManagedForm().addPart(part);
-       }
-
-       /** Filtered table with members. Has drag and drop ability */
-       protected void appendMembersPart(Composite parent, Group group) {
-               // Section section = tk.createSection(parent, Section.TITLE_BAR);
-               // section.setText("Members");
-               // section.setLayoutData(EclipseUiUtils.fillAll());
-
-               Composite body = new Composite(parent, SWT.BORDER);
-               body.setLayout(new GridLayout());
-               // section.setClient(body);
-               body.setLayoutData(EclipseUiUtils.fillAll());
-
-               // Define the displayed columns
-               List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-               columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24));
-               columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150));
-               columnDefs.add(new ColumnDefinition(new MailLP(), "Mail", 150));
-               // columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name",
-               // 240));
-
-               // Create and configure the table
-               LdifUsersTable userViewerCmp = new MyUserTableViewer(body, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL,
-                               userAdminWrapper.getUserAdmin());
-
-               userViewerCmp.setColumnDefinitions(columnDefs);
-               userViewerCmp.populate(true, false);
-               userViewerCmp.setLayoutData(EclipseUiUtils.fillAll());
-
-               // Controllers
-               TableViewer userViewer = userViewerCmp.getTableViewer();
-               userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService));
-               int operations = DND.DROP_COPY | DND.DROP_MOVE;
-               Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
-               userViewer.addDropSupport(operations, tt,
-                               new GroupDropListener(userAdminWrapper, userViewerCmp, (Group) getDisplayedUser()));
-
-               AbstractFormPart part = new GroupMembersPart(userViewerCmp);
-               getManagedForm().addPart(part);
-
-               // remove button
-               // addRemoveAbility(toolBarManager, userViewerCmp.getTableViewer(), group);
-               Action action = new RemoveMembershipAction(userViewer, group, "Remove selected items from this group",
-                               SecurityAdminImages.ICON_REMOVE_DESC);
-
-               ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
-               ToolBar toolBar = toolBarManager.createControl(body);
-               toolBar.setLayoutData(CmsSwtUtils.fillWidth());
-
-               toolBarManager.add(action);
-               toolBarManager.update(true);
-
-       }
-
-       // private LdifUsersTable createMemberPart(Composite parent, Group group) {
-       //
-       // // Define the displayed columns
-       // List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-       // columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24));
-       // columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150));
-       // columnDefs.add(new ColumnDefinition(new MailLP(), "Mail", 150));
-       // // columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished
-       // Name",
-       // // 240));
-       //
-       // // Create and configure the table
-       // LdifUsersTable userViewerCmp = new MyUserTableViewer(parent, SWT.MULTI |
-       // SWT.H_SCROLL | SWT.V_SCROLL,
-       // userAdminWrapper.getUserAdmin());
-       //
-       // userViewerCmp.setColumnDefinitions(columnDefs);
-       // userViewerCmp.populate(true, false);
-       // userViewerCmp.setLayoutData(EclipseUiUtils.fillAll());
-       //
-       // // Controllers
-       // TableViewer userViewer = userViewerCmp.getTableViewer();
-       // userViewer.addDoubleClickListener(new
-       // UserTableDefaultDClickListener(partService));
-       // int operations = DND.DROP_COPY | DND.DROP_MOVE;
-       // Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
-       // userViewer.addDropSupport(operations, tt,
-       // new GroupDropListener(userAdminWrapper, userViewerCmp, (Group)
-       // getDisplayedUser()));
-       //
-       // // userViewerCmp.refresh();
-       // return userViewerCmp;
-       // }
-
-       // Local viewers
-       private class MyUserTableViewer extends LdifUsersTable {
-               private static final long serialVersionUID = 8467999509931900367L;
-
-               private final UserFilter userFilter;
-
-               public MyUserTableViewer(Composite parent, int style, UserAdmin userAdmin) {
-                       super(parent, style, true);
-                       userFilter = new UserFilter();
-
-               }
-
-               @Override
-               protected List<User> listFilteredElements(String filter) {
-                       // reload user and set it in the editor
-                       Group group = (Group) getDisplayedUser();
-                       Role[] roles = group.getMembers();
-                       List<User> users = new ArrayList<User>();
-                       userFilter.setSearchText(filter);
-                       // userFilter.setShowSystemRole(true);
-                       for (Role role : roles)
-                               // if (role.getType() == Role.GROUP)
-                               if (userFilter.select(null, null, role))
-                                       users.add((User) role);
-                       return users;
-               }
-       }
-
-       // private void addRemoveAbility(ToolBarManager toolBarManager, TableViewer
-       // userViewer, Group group) {
-       // // Section section = sectionPart.getSection();
-       // // ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
-       // // ToolBar toolbar = toolBarManager.createControl(parent);
-       // // ToolBar toolbar = toolBarManager.getControl();
-       // // final Cursor handCursor = new Cursor(toolbar.getDisplay(),
-       // SWT.CURSOR_HAND);
-       // // toolbar.setCursor(handCursor);
-       // // toolbar.addDisposeListener(new DisposeListener() {
-       // // private static final long serialVersionUID = 3882131405820522925L;
-       // //
-       // // public void widgetDisposed(DisposeEvent e) {
-       // // if ((handCursor != null) && (handCursor.isDisposed() == false)) {
-       // // handCursor.dispose();
-       // // }
-       // // }
-       // // });
-       //
-       // Action action = new RemoveMembershipAction(userViewer, group, "Remove
-       // selected items from this group",
-       // SecurityAdminImages.ICON_REMOVE_DESC);
-       // toolBarManager.add(action);
-       // toolBarManager.update(true);
-       // // section.setTextClient(toolbar);
-       // }
-
-       private class RemoveMembershipAction extends Action {
-               private static final long serialVersionUID = -1337713097184522588L;
-
-               private final TableViewer userViewer;
-               private final Group group;
-
-               RemoveMembershipAction(TableViewer userViewer, Group group, String name, ImageDescriptor img) {
-                       super(name, img);
-                       this.userViewer = userViewer;
-                       this.group = group;
-               }
-
-               @Override
-               public void run() {
-                       ISelection selection = userViewer.getSelection();
-                       if (selection.isEmpty())
-                               return;
-
-                       @SuppressWarnings("unchecked")
-                       Iterator<User> it = ((IStructuredSelection) selection).iterator();
-                       List<User> users = new ArrayList<User>();
-                       while (it.hasNext()) {
-                               User currUser = it.next();
-                               users.add(currUser);
-                       }
-
-                       userAdminWrapper.beginTransactionIfNeeded();
-                       for (User user : users) {
-                               group.removeMember(user);
-                       }
-                       userAdminWrapper.commitOrNotifyTransactionStateChange();
-                       userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group));
-               }
-       }
-
-       // LOCAL CONTROLLERS
-       private class GroupMembersPart extends AbstractFormPart {
-               private final LdifUsersTable userViewer;
-               // private final Group group;
-
-               private GroupChangeListener listener;
-
-               public GroupMembersPart(LdifUsersTable userViewer) {
-                       // super(section);
-                       this.userViewer = userViewer;
-                       // this.group = group;
-               }
-
-               @Override
-               public void initialize(IManagedForm form) {
-                       super.initialize(form);
-                       listener = new GroupChangeListener(userViewer.getDisplay(), GroupMembersPart.this);
-                       userAdminWrapper.addListener(listener);
-               }
-
-               @Override
-               public void dispose() {
-                       userAdminWrapper.removeListener(listener);
-                       super.dispose();
-               }
-
-               @Override
-               public void refresh() {
-                       userViewer.refresh();
-                       super.refresh();
-               }
-       }
-
-       /**
-        * Defines this table as being a potential target to add group membership
-        * (roles) to this group
-        */
-       private class GroupDropListener extends ViewerDropAdapter {
-               private static final long serialVersionUID = 2893468717831451621L;
-
-               private final UserAdminWrapper userAdminWrapper;
-               // private final LdifUsersTable myUserViewerCmp;
-               private final Group myGroup;
-
-               public GroupDropListener(UserAdminWrapper userAdminWrapper, LdifUsersTable userTableViewerCmp, Group group) {
-                       super(userTableViewerCmp.getTableViewer());
-                       this.userAdminWrapper = userAdminWrapper;
-                       this.myGroup = group;
-                       // this.myUserViewerCmp = userTableViewerCmp;
-               }
-
-               @Override
-               public boolean validateDrop(Object target, int operation, TransferData transferType) {
-                       // Target is always OK in a list only view
-                       // TODO check if not a string
-                       boolean validDrop = true;
-                       return validDrop;
-               }
-
-               @Override
-               public void drop(DropTargetEvent event) {
-                       // TODO Is there an opportunity to perform the check before?
-                       String newUserName = (String) event.data;
-                       UserAdmin myUserAdmin = userAdminWrapper.getUserAdmin();
-                       Role role = myUserAdmin.getRole(newUserName);
-                       if (role.getType() == Role.GROUP) {
-                               Group newGroup = (Group) role;
-                               Shell shell = getViewer().getControl().getShell();
-                               // Sanity checks
-                               if (myGroup == newGroup) { // Equality
-                                       MessageDialog.openError(shell, "Forbidden addition ", "A group cannot be a member of itself.");
-                                       return;
-                               }
-
-                               // Cycle
-                               String myName = myGroup.getName();
-                               List<User> myMemberships = getFlatGroups(myGroup);
-                               if (myMemberships.contains(newGroup)) {
-                                       MessageDialog.openError(shell, "Forbidden addition: cycle",
-                                                       "Cannot add " + newUserName + " to group " + myName + ". This would create a cycle");
-                                       return;
-                               }
-
-                               // Already member
-                               List<User> newGroupMemberships = getFlatGroups(newGroup);
-                               if (newGroupMemberships.contains(myGroup)) {
-                                       MessageDialog.openError(shell, "Forbidden addition",
-                                                       "Cannot add " + newUserName + " to group " + myName + ", this membership already exists");
-                                       return;
-                               }
-                               userAdminWrapper.beginTransactionIfNeeded();
-                               myGroup.addMember(newGroup);
-                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                               userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, myGroup));
-                       } else if (role.getType() == Role.USER) {
-                               // TODO check if the group is already member of this group
-                               WorkTransaction transaction = userAdminWrapper.beginTransactionIfNeeded();
-                               User user = (User) role;
-                               myGroup.addMember(user);
-                               if (UserAdminWrapper.COMMIT_ON_SAVE)
-                                       try {
-                                               transaction.commit();
-                                       } catch (Exception e) {
-                                               throw new IllegalStateException(
-                                                               "Cannot commit transaction " + "after user group membership update", e);
-                                       }
-                               userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, myGroup));
-                       }
-                       super.drop(event);
-               }
-
-               @Override
-               public boolean performDrop(Object data) {
-                       // myUserViewerCmp.refresh();
-                       return true;
-               }
-       }
-
-       // LOCAL HELPERS
-       // private Composite addSection(FormToolkit tk, Composite parent) {
-       // Section section = tk.createSection(parent, SWT.NO_FOCUS);
-       // section.setLayoutData(EclipseUiUtils.fillWidth());
-       // Composite body = tk.createComposite(section, SWT.WRAP);
-       // body.setLayoutData(EclipseUiUtils.fillAll());
-       // section.setClient(body);
-       // return body;
-       // }
-
-       /** Creates label and text. */
-       // private Text createLT(Composite parent, String label, String value) {
-       // FormToolkit toolkit = getManagedForm().getToolkit();
-       // Label lbl = toolkit.createLabel(parent, label);
-       // lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
-       // lbl.setFont(EclipseUiUtils.getBoldFont(parent));
-       // Text text = toolkit.createText(parent, value, SWT.BORDER);
-       // text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-       // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
-       // return text;
-       // }
-       //
-       // Text createReadOnlyLT(Composite parent, String label, String value) {
-       // FormToolkit toolkit = getManagedForm().getToolkit();
-       // Label lbl = toolkit.createLabel(parent, label);
-       // lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
-       // lbl.setFont(EclipseUiUtils.getBoldFont(parent));
-       // Text text = toolkit.createText(parent, value, SWT.NONE);
-       // text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-       // text.setEditable(false);
-       // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
-       // return text;
-       // }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java
deleted file mode 100644 (file)
index 73e4f5d..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.e4.users.providers.CommonNameLP;
-import org.argeo.cms.e4.users.providers.DomainNameLP;
-import org.argeo.cms.e4.users.providers.RoleIconLP;
-import org.argeo.cms.e4.users.providers.UserDragListener;
-import org.argeo.cms.swt.CmsException;
-//import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
-//import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener;
-//import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper;
-//import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP;
-//import org.argeo.cms.ui.workbench.internal.useradmin.providers.DomainNameLP;
-//import org.argeo.cms.ui.workbench.internal.useradmin.providers.RoleIconLP;
-//import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserDragListener;
-//import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener;
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
-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;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-//import org.eclipse.ui.part.ViewPart;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdminEvent;
-import org.osgi.service.useradmin.UserAdminListener;
-
-/** List all groups with filter */
-public class GroupsView {
-       private final static CmsLog log = CmsLog.getLog(GroupsView.class);
-       // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".groupsView";
-
-       @Inject
-       private EPartService partService;
-       @Inject
-       private UserAdminWrapper userAdminWrapper;
-
-       // UI Objects
-       private LdifUsersTable groupTableViewerCmp;
-       private TableViewer userViewer;
-       private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-
-       private UserAdminListener listener;
-
-       @PostConstruct
-       public void createPartControl(Composite parent, ESelectionService selectionService) {
-               parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-               // boolean isAdmin = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN);
-
-               // Define the displayed columns
-               columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 19));
-               columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150));
-               columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 100));
-               // Only show technical DN to admin
-               // if (isAdmin)
-               // columnDefs.add(new ColumnDefinition(new UserNameLP(),
-               // "Distinguished Name", 300));
-
-               // Create and configure the table
-               groupTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-
-               groupTableViewerCmp.setColumnDefinitions(columnDefs);
-               // if (isAdmin)
-               // groupTableViewerCmp.populateWithStaticFilters(false, false);
-               // else
-               groupTableViewerCmp.populate(true, false);
-
-               groupTableViewerCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
-               // Links
-               userViewer = groupTableViewerCmp.getTableViewer();
-               userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService));
-               // getViewSite().setSelectionProvider(userViewer);
-               userViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
-                       @Override
-                       public void selectionChanged(SelectionChangedEvent event) {
-                               IStructuredSelection selection = (IStructuredSelection) event.getSelection();
-                               selectionService.setSelection(selection.toList());
-                       }
-               });
-
-               // Really?
-               groupTableViewerCmp.refresh();
-
-               // Drag and drop
-               int operations = DND.DROP_COPY | DND.DROP_MOVE;
-               Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
-               userViewer.addDragSupport(operations, tt, new UserDragListener(userViewer));
-
-               // // Register a useradmin listener
-               // listener = new UserAdminListener() {
-               // @Override
-               // public void roleChanged(UserAdminEvent event) {
-               // if (userViewer != null && !userViewer.getTable().isDisposed())
-               // refresh();
-               // }
-               // };
-               // userAdminWrapper.addListener(listener);
-               // }
-
-               // Register a useradmin listener
-               listener = new MyUiUAListener(parent.getDisplay());
-               userAdminWrapper.addListener(listener);
-       }
-
-       private class MyUiUAListener extends UiUserAdminListener {
-               public MyUiUAListener(Display display) {
-                       super(display);
-               }
-
-               @Override
-               public void roleChangedToUiThread(UserAdminEvent event) {
-                       if (userViewer != null && !userViewer.getTable().isDisposed())
-                               refresh();
-               }
-       }
-
-       private class MyUserTableViewer extends LdifUsersTable {
-               private static final long serialVersionUID = 8467999509931900367L;
-
-               private boolean showSystemRoles = true;
-
-               private final String[] knownProps = { LdapAttrs.uid.name(), LdapAttrs.cn.name(), LdapAttrs.DN };
-
-               public MyUserTableViewer(Composite parent, int style) {
-                       super(parent, style);
-                       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(CmsConstants.ROLE_ADMIN);
-                       showSystemRoleBtn.setSelection(showSystemRoles);
-
-                       showSystemRoleBtn.addSelectionListener(new SelectionAdapter() {
-                               private static final long serialVersionUID = -7033424592697691676L;
-
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       showSystemRoles = showSystemRoleBtn.getSelection();
-                                       refresh();
-                               }
-
-                       });
-               }
-
-               @Override
-               protected List<User> listFilteredElements(String filter) {
-                       Role[] roles;
-                       try {
-                               StringBuilder builder = new StringBuilder();
-                               StringBuilder tmpBuilder = new StringBuilder();
-                               if (EclipseUiUtils.notEmpty(filter))
-                                       for (String prop : knownProps) {
-                                               tmpBuilder.append("(");
-                                               tmpBuilder.append(prop);
-                                               tmpBuilder.append("=*");
-                                               tmpBuilder.append(filter);
-                                               tmpBuilder.append("*)");
-                                       }
-                               if (tmpBuilder.length() > 1) {
-                                       builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
-                                                       .append(LdapObjs.groupOfNames.name()).append(")");
-                                       // hide tokens
-                                       builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.TOKENS_BASEDN)
-                                                       .append("))");
-
-                                       if (!showSystemRoles)
-                                               builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.SYSTEM_ROLES_BASEDN)
-                                                               .append("))");
-                                       builder.append("(|");
-                                       builder.append(tmpBuilder.toString());
-                                       builder.append("))");
-                               } else {
-                                       if (!showSystemRoles)
-                                               builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
-                                                               .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*")
-                                                               .append(CmsConstants.SYSTEM_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(CmsConstants.TOKENS_BASEDN).append(")))");
-
-                               }
-                               roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString());
-                       } catch (InvalidSyntaxException e) {
-                               throw new CmsException("Unable to get roles with filter: " + filter, e);
-                       }
-                       List<User> users = new ArrayList<User>();
-                       for (Role role : roles)
-                               if (!users.contains(role))
-                                       users.add((User) role);
-                               else
-                                       log.warn("Duplicated role: " + role);
-
-                       return users;
-               }
-       }
-
-       public void refresh() {
-               groupTableViewerCmp.refresh();
-       }
-
-       @PreDestroy
-       public void dispose() {
-               userAdminWrapper.removeListener(listener);
-       }
-
-       @Focus
-       public void setFocus() {
-               groupTableViewerCmp.setFocus();
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
-               this.userAdminWrapper = userAdminWrapper;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/SecurityAdminImages.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/SecurityAdminImages.java
deleted file mode 100644 (file)
index 7bbe3c7..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import org.argeo.cms.ui.theme.CmsImages;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-
-/** Shared icons that must be declared programmatically . */
-public class SecurityAdminImages extends CmsImages {
-       private final static String PREFIX = "icons/";
-
-       public final static ImageDescriptor ICON_REMOVE_DESC = createDesc(PREFIX + "delete.png");
-       public final static ImageDescriptor ICON_USER_DESC = createDesc(PREFIX + "person.png");
-
-       public final static Image ICON_USER = ICON_USER_DESC.createImage();
-       public final static Image ICON_GROUP = createImg(PREFIX + "group.png");
-       public final static Image ICON_WORKGROUP = createImg(PREFIX + "workgroup.png");
-       public final static Image ICON_ROLE = createImg(PREFIX + "role.gif");
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UiAdminUtils.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UiAdminUtils.java
deleted file mode 100644 (file)
index fb48a47..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import org.argeo.util.transaction.WorkTransaction;
-
-/** First effort to centralize back end methods used by the user admin UI */
-public class UiAdminUtils {
-       /*
-        * INTERNAL METHODS: Below methods are meant to stay here and are not part
-        * of a potential generic backend to manage the useradmin
-        */
-       /** Easily notify the ActiveWindow that the transaction had a state change */
-       public final static void notifyTransactionStateChange(
-                       WorkTransaction userTransaction) {
-//             try {
-//                     IWorkbenchWindow aww = PlatformUI.getWorkbench()
-//                                     .getActiveWorkbenchWindow();
-//                     ISourceProviderService sourceProviderService = (ISourceProviderService) aww
-//                                     .getService(ISourceProviderService.class);
-//                     UserTransactionProvider esp = (UserTransactionProvider) sourceProviderService
-//                                     .getSourceProvider(UserTransactionProvider.TRANSACTION_STATE);
-//                     esp.fireTransactionStateChange();
-//             } catch (Exception e) {
-//                     throw new CmsException("Unable to begin transaction", e);
-//             }
-       }
-
-       /**
-        * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}.
-        * Thanks to <a href=
-        * "http://www.mkyong.com/regular-expressions/how-to-validate-email-address-with-regular-expression/"
-        * >this tip</a>.
-        */
-       public final static String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UiUserAdminListener.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UiUserAdminListener.java
deleted file mode 100644 (file)
index eb64aba..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import org.eclipse.swt.widgets.Display;
-import org.osgi.service.useradmin.UserAdminEvent;
-import org.osgi.service.useradmin.UserAdminListener;
-
-/** Convenience class to insure the call to refresh is done in the UI thread */
-public abstract class UiUserAdminListener implements UserAdminListener {
-
-       private final Display display;
-
-       public UiUserAdminListener(Display display) {
-               this.display = display;
-       }
-
-       @Override
-       public void roleChanged(final UserAdminEvent event) {
-               display.asyncExec(new Runnable() {
-                       @Override
-                       public void run() {
-                               roleChangedToUiThread(event);
-                       }
-               });
-       }
-
-       public abstract void roleChangedToUiThread(UserAdminEvent event);
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java
deleted file mode 100644 (file)
index dbb629c..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.osgi.useradmin.UserDirectory;
-import org.argeo.util.directory.DirectoryConf;
-import org.argeo.util.transaction.WorkTransaction;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.service.useradmin.UserAdminEvent;
-import org.osgi.service.useradmin.UserAdminListener;
-
-/** Centralise interaction with the UserAdmin in this bundle */
-public class UserAdminWrapper {
-
-       private UserAdmin userAdmin;
-       // private ServiceReference<UserAdmin> userAdminServiceReference;
-//     private Set<String> uris;
-       private Map<UserDirectory, Hashtable<String, String>> userDirectories = Collections
-                       .synchronizedMap(new LinkedHashMap<>());
-       private WorkTransaction userTransaction;
-
-       // First effort to simplify UX while managing users and groups
-       public final static boolean COMMIT_ON_SAVE = true;
-
-       // Registered listeners
-       List<UserAdminListener> listeners = new ArrayList<UserAdminListener>();
-
-       /**
-        * Starts a transaction if necessary. Should always been called together with
-        * {@link UserAdminWrapper#commitOrNotifyTransactionStateChange()} once the
-        * security model changes have been performed.
-        */
-       public WorkTransaction beginTransactionIfNeeded() {
-               try {
-                       // UserTransaction userTransaction = getUserTransaction();
-                       if (userTransaction.isNoTransactionStatus()) {
-                               userTransaction.begin();
-                               // UiAdminUtils.notifyTransactionStateChange(userTransaction);
-                       }
-                       return userTransaction;
-               } catch (Exception e) {
-                       throw new CmsException("Unable to begin transaction", e);
-               }
-       }
-
-       /**
-        * Depending on the current application configuration, it will either commit the
-        * current transaction or throw a notification that the transaction state has
-        * changed (In the later case, it must be called from the UI thread).
-        */
-       public void commitOrNotifyTransactionStateChange() {
-               try {
-                       // UserTransaction userTransaction = getUserTransaction();
-                       if (userTransaction.isNoTransactionStatus())
-                               return;
-
-                       if (UserAdminWrapper.COMMIT_ON_SAVE)
-                               userTransaction.commit();
-                       else
-                               UiAdminUtils.notifyTransactionStateChange(userTransaction);
-               } catch (Exception e) {
-                       throw new CmsException("Unable to clean transaction", e);
-               }
-       }
-
-       // TODO implement safer mechanism
-       public void addListener(UserAdminListener userAdminListener) {
-               if (!listeners.contains(userAdminListener))
-                       listeners.add(userAdminListener);
-       }
-
-       public void removeListener(UserAdminListener userAdminListener) {
-               if (listeners.contains(userAdminListener))
-                       listeners.remove(userAdminListener);
-       }
-
-       public void notifyListeners(UserAdminEvent event) {
-               for (UserAdminListener listener : listeners)
-                       listener.roleChanged(event);
-       }
-
-       public Map<String, String> getKnownBaseDns(boolean onlyWritable) {
-               Map<String, String> dns = new HashMap<String, String>();
-               for (UserDirectory userDirectory : userDirectories.keySet()) {
-                       Boolean readOnly = userDirectory.isReadOnly();
-                       String baseDn = userDirectory.getBase();
-
-                       if (onlyWritable && readOnly)
-                               continue;
-                       if (baseDn.equalsIgnoreCase(CmsConstants.SYSTEM_ROLES_BASEDN))
-                               continue;
-                       if (baseDn.equalsIgnoreCase(CmsConstants.TOKENS_BASEDN))
-                               continue;
-                       dns.put(baseDn, DirectoryConf.propertiesAsUri(userDirectories.get(userDirectory)).toString());
-
-               }
-//             for (String uri : uris) {
-//                     if (!uri.startsWith("/"))
-//                             continue;
-//                     Dictionary<String, ?> props = UserAdminConf.uriAsProperties(uri);
-//                     String readOnly = UserAdminConf.readOnly.getValue(props);
-//                     String baseDn = UserAdminConf.baseDn.getValue(props);
-//
-//                     if (onlyWritable && "true".equals(readOnly))
-//                             continue;
-//                     if (baseDn.equalsIgnoreCase(NodeConstants.ROLES_BASEDN))
-//                             continue;
-//                     if (baseDn.equalsIgnoreCase(NodeConstants.TOKENS_BASEDN))
-//                             continue;
-//                     dns.put(baseDn, uri);
-//             }
-               return dns;
-       }
-
-       public UserAdmin getUserAdmin() {
-               return userAdmin;
-       }
-
-       public WorkTransaction getUserTransaction() {
-               return userTransaction;
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setUserAdmin(UserAdmin userAdmin, Map<String, String> properties) {
-               this.userAdmin = userAdmin;
-//             this.uris = Collections.unmodifiableSortedSet(new TreeSet<>(properties.keySet()));
-       }
-
-       public void setUserTransaction(WorkTransaction userTransaction) {
-               this.userTransaction = userTransaction;
-       }
-
-       public void addUserDirectory(UserDirectory userDirectory, Map<String, String> properties) {
-               userDirectories.put(userDirectory, new Hashtable<>(properties));
-       }
-
-       public void removeUserDirectory(UserDirectory userDirectory, Map<String, String> properties) {
-               userDirectories.remove(userDirectory);
-       }
-
-       // public void setUserAdminServiceReference(
-       // ServiceReference<UserAdmin> userAdminServiceReference) {
-       // this.userAdminServiceReference = userAdminServiceReference;
-       // }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java
deleted file mode 100644 (file)
index 4fc59d3..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.cms.e4.users.providers.CommonNameLP;
-import org.argeo.cms.e4.users.providers.DomainNameLP;
-import org.argeo.cms.e4.users.providers.MailLP;
-import org.argeo.cms.e4.users.providers.UserNameLP;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
-import org.argeo.util.naming.LdapAttrs;
-import org.argeo.util.naming.LdapObjs;
-import org.argeo.util.transaction.WorkTransaction;
-import org.eclipse.jface.dialogs.IPageChangeProvider;
-import org.eclipse.jface.dialogs.IPageChangedListener;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.PageChangedEvent;
-import org.eclipse.jface.wizard.IWizardContainer;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Wizard to update users */
-public class UserBatchUpdateWizard extends Wizard {
-
-       private final static CmsLog log = CmsLog.getLog(UserBatchUpdateWizard.class);
-       private UserAdminWrapper userAdminWrapper;
-
-       // pages
-       private ChooseCommandWizardPage chooseCommandPage;
-       private ChooseUsersWizardPage userListPage;
-       private ValidateAndLaunchWizardPage validatePage;
-
-       // Various implemented commands keys
-       private final static String CMD_UPDATE_PASSWORD = "resetPassword";
-       private final static String CMD_UPDATE_EMAIL = "resetEmail";
-       private final static String CMD_GROUP_MEMBERSHIP = "groupMembership";
-
-       private final Map<String, String> commands = new HashMap<String, String>() {
-               private static final long serialVersionUID = 1L;
-               {
-                       put("Reset password(s)", CMD_UPDATE_PASSWORD);
-                       put("Reset email(s)", CMD_UPDATE_EMAIL);
-                       // TODO implement role / group management
-                       // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP);
-               }
-       };
-
-       public UserBatchUpdateWizard(UserAdminWrapper userAdminWrapper) {
-               this.userAdminWrapper = userAdminWrapper;
-       }
-
-       @Override
-       public void addPages() {
-               chooseCommandPage = new ChooseCommandWizardPage();
-               addPage(chooseCommandPage);
-               userListPage = new ChooseUsersWizardPage();
-               addPage(userListPage);
-               validatePage = new ValidateAndLaunchWizardPage();
-               addPage(validatePage);
-       }
-
-       @Override
-       public boolean performFinish() {
-               if (!canFinish())
-                       return false;
-               WorkTransaction ut = userAdminWrapper.getUserTransaction();
-               if (!ut.isNoTransactionStatus() && !MessageDialog.openConfirm(getShell(), "Existing Transaction",
-                               "A user transaction is already existing, " + "are you sure you want to proceed ?"))
-                       return false;
-
-               // We cannot use jobs, user modifications are still meant to be done in
-               // the UIThread
-               // UpdateJob job = null;
-               // if (job != null)
-               // job.schedule();
-
-               if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) {
-                       char[] newValue = chooseCommandPage.getPwdValue();
-                       if (newValue == null)
-                               throw new CmsException("Password cannot be null or an empty string");
-                       ResetPassword job = new ResetPassword(userAdminWrapper, userListPage.getSelectedUsers(), newValue);
-                       job.doUpdate();
-               } else if (CMD_UPDATE_EMAIL.equals(chooseCommandPage.getCommand())) {
-                       String newValue = chooseCommandPage.getEmailValue();
-                       if (newValue == null)
-                               throw new CmsException("Password cannot be null or an empty string");
-                       ResetEmail job = new ResetEmail(userAdminWrapper, userListPage.getSelectedUsers(), newValue);
-                       job.doUpdate();
-               }
-               return true;
-       }
-
-       public boolean canFinish() {
-               if (this.getContainer().getCurrentPage() == validatePage)
-                       return true;
-               return false;
-       }
-
-       private class ResetPassword {
-               private char[] newPwd;
-               private UserAdminWrapper userAdminWrapper;
-               private List<User> usersToUpdate;
-
-               public ResetPassword(UserAdminWrapper userAdminWrapper, List<User> usersToUpdate, char[] newPwd) {
-                       this.newPwd = newPwd;
-                       this.usersToUpdate = usersToUpdate;
-                       this.userAdminWrapper = userAdminWrapper;
-               }
-
-               @SuppressWarnings("unchecked")
-               protected void doUpdate() {
-                       userAdminWrapper.beginTransactionIfNeeded();
-                       try {
-                               for (User user : usersToUpdate) {
-                                       // the char array is emptied after being used.
-                                       user.getCredentials().put(null, newPwd.clone());
-                               }
-                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                       } catch (Exception e) {
-                               throw new CmsException("Cannot perform batch update on users", e);
-                       } finally {
-                               WorkTransaction ut = userAdminWrapper.getUserTransaction();
-                               if (!ut.isNoTransactionStatus())
-                                       ut.rollback();
-                       }
-               }
-       }
-
-       private class ResetEmail {
-               private String newEmail;
-               private UserAdminWrapper userAdminWrapper;
-               private List<User> usersToUpdate;
-
-               public ResetEmail(UserAdminWrapper userAdminWrapper, List<User> usersToUpdate, String newEmail) {
-                       this.newEmail = newEmail;
-                       this.usersToUpdate = usersToUpdate;
-                       this.userAdminWrapper = userAdminWrapper;
-               }
-
-               @SuppressWarnings("unchecked")
-               protected void doUpdate() {
-                       userAdminWrapper.beginTransactionIfNeeded();
-                       try {
-                               for (User user : usersToUpdate) {
-                                       // the char array is emptied after being used.
-                                       user.getProperties().put(LdapAttrs.mail.name(), newEmail);
-                               }
-
-                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                               if (!usersToUpdate.isEmpty())
-                                       userAdminWrapper.notifyListeners(
-                                                       new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, usersToUpdate.get(0)));
-                       } catch (Exception e) {
-                               throw new CmsException("Cannot perform batch update on users", e);
-                       } finally {
-                               WorkTransaction ut = userAdminWrapper.getUserTransaction();
-                               if (!ut.isNoTransactionStatus())
-                                       ut.rollback();
-                       }
-               }
-       }
-
-       // @SuppressWarnings("unused")
-       // private class AddToGroup extends UpdateJob {
-       // private String groupID;
-       // private Session session;
-       //
-       // public AddToGroup(Session session, List<Node> nodesToUpdate,
-       // String groupID) {
-       // super(session, nodesToUpdate);
-       // this.session = session;
-       // this.groupID = groupID;
-       // }
-       //
-       // protected void doUpdate(Node node) {
-       // log.info("Add/Remove to group actions are not yet implemented");
-       // // TODO implement this
-       // // try {
-       // // throw new CmsException("Not yet implemented");
-       // // } catch (RepositoryException re) {
-       // // throw new CmsException(
-       // // "Unable to update boolean value for node " + node, re);
-       // // }
-       // }
-       // }
-
-       // /**
-       // * Base privileged job that will be run asynchronously to perform the
-       // batch
-       // * update
-       // */
-       // private abstract class UpdateJob extends PrivilegedJob {
-       //
-       // private final UserAdminWrapper userAdminWrapper;
-       // private final List<User> usersToUpdate;
-       //
-       // protected abstract void doUpdate(User user);
-       //
-       // public UpdateJob(UserAdminWrapper userAdminWrapper,
-       // List<User> usersToUpdate) {
-       // super("Perform update");
-       // this.usersToUpdate = usersToUpdate;
-       // this.userAdminWrapper = userAdminWrapper;
-       // }
-       //
-       // @Override
-       // protected IStatus doRun(IProgressMonitor progressMonitor) {
-       // try {
-       // JcrMonitor monitor = new EclipseJcrMonitor(progressMonitor);
-       // int total = usersToUpdate.size();
-       // monitor.beginTask("Performing change", total);
-       // userAdminWrapper.beginTransactionIfNeeded();
-       // for (User user : usersToUpdate) {
-       // doUpdate(user);
-       // monitor.worked(1);
-       // }
-       // userAdminWrapper.getUserTransaction().commit();
-       // } catch (Exception e) {
-       // throw new CmsException(
-       // "Cannot perform batch update on users", e);
-       // } finally {
-       // UserTransaction ut = userAdminWrapper.getUserTransaction();
-       // try {
-       // if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION)
-       // ut.rollback();
-       // } catch (IllegalStateException | SecurityException
-       // | SystemException e) {
-       // log.error("Unable to rollback session in 'finally', "
-       // + "the system might be in a dirty state");
-       // e.printStackTrace();
-       // }
-       // }
-       // return Status.OK_STATUS;
-       // }
-       // }
-
-       // PAGES
-       /**
-        * Displays a combo box that enables user to choose which action to perform
-        */
-       private class ChooseCommandWizardPage extends WizardPage {
-               private static final long serialVersionUID = -8069434295293996633L;
-               private Combo chooseCommandCmb;
-               private Button trueChk;
-               private Text valueTxt;
-               private Text pwdTxt;
-               private Text pwd2Txt;
-
-               public ChooseCommandWizardPage() {
-                       super("Choose a command to run.");
-                       setTitle("Choose a command to run.");
-               }
-
-               @Override
-               public void createControl(Composite parent) {
-                       GridLayout gl = new GridLayout();
-                       Composite container = new Composite(parent, SWT.NO_FOCUS);
-                       container.setLayout(gl);
-
-                       chooseCommandCmb = new Combo(container, SWT.READ_ONLY);
-                       chooseCommandCmb.setLayoutData(EclipseUiUtils.fillWidth());
-                       String[] values = commands.keySet().toArray(new String[0]);
-                       chooseCommandCmb.setItems(values);
-
-                       final Composite bottomPart = new Composite(container, SWT.NO_FOCUS);
-                       bottomPart.setLayoutData(EclipseUiUtils.fillAll());
-                       bottomPart.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-                       chooseCommandCmb.addSelectionListener(new SelectionAdapter() {
-                               private static final long serialVersionUID = 1L;
-
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       if (getCommand().equals(CMD_UPDATE_PASSWORD))
-                                               populatePasswordCmp(bottomPart);
-                                       else if (getCommand().equals(CMD_UPDATE_EMAIL))
-                                               populateEmailCmp(bottomPart);
-                                       else if (getCommand().equals(CMD_GROUP_MEMBERSHIP))
-                                               populateGroupCmp(bottomPart);
-                                       else
-                                               populateBooleanFlagCmp(bottomPart);
-                                       checkPageComplete();
-                                       bottomPart.layout(true, true);
-                               }
-                       });
-                       setControl(container);
-               }
-
-               private void populateBooleanFlagCmp(Composite parent) {
-                       EclipseUiUtils.clear(parent);
-                       trueChk = new Button(parent, SWT.CHECK);
-                       trueChk.setText("Do it. (It will to the contrary if unchecked)");
-                       trueChk.setSelection(true);
-                       trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
-               }
-
-               private void populatePasswordCmp(Composite parent) {
-                       EclipseUiUtils.clear(parent);
-                       Composite body = new Composite(parent, SWT.NO_FOCUS);
-
-                       ModifyListener ml = new ModifyListener() {
-                               private static final long serialVersionUID = -1558726363536729634L;
-
-                               @Override
-                               public void modifyText(ModifyEvent event) {
-                                       checkPageComplete();
-                               }
-                       };
-
-                       body.setLayout(new GridLayout(2, false));
-                       body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-                       pwdTxt = EclipseUiUtils.createGridLP(body, "New password", ml);
-                       pwd2Txt = EclipseUiUtils.createGridLP(body, "Repeat password", ml);
-               }
-
-               private void populateEmailCmp(Composite parent) {
-                       EclipseUiUtils.clear(parent);
-                       Composite body = new Composite(parent, SWT.NO_FOCUS);
-
-                       ModifyListener ml = new ModifyListener() {
-                               private static final long serialVersionUID = 2147704227294268317L;
-
-                               @Override
-                               public void modifyText(ModifyEvent event) {
-                                       checkPageComplete();
-                               }
-                       };
-
-                       body.setLayout(new GridLayout(2, false));
-                       body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-                       valueTxt = EclipseUiUtils.createGridLT(body, "New e-mail", ml);
-               }
-
-               private void checkPageComplete() {
-                       String errorMsg = null;
-                       if (chooseCommandCmb.getSelectionIndex() < 0)
-                               errorMsg = "Please select an action";
-                       else if (CMD_UPDATE_EMAIL.equals(getCommand())) {
-                               if (!valueTxt.getText().matches(UiAdminUtils.EMAIL_PATTERN))
-                                       errorMsg = "Not a valid e-mail address";
-                       } else if (CMD_UPDATE_PASSWORD.equals(getCommand())) {
-                               if (EclipseUiUtils.isEmpty(pwdTxt.getText()) || pwdTxt.getText().length() < 4)
-                                       errorMsg = "Please enter a password that is at least 4 character long";
-                               else if (!pwdTxt.getText().equals(pwd2Txt.getText()))
-                                       errorMsg = "Passwords are different";
-                       }
-                       if (EclipseUiUtils.notEmpty(errorMsg)) {
-                               setMessage(errorMsg, WizardPage.ERROR);
-                               setPageComplete(false);
-                       } else {
-                               setMessage("Page complete, you can proceed to user choice", WizardPage.INFORMATION);
-                               setPageComplete(true);
-                       }
-
-                       getContainer().updateButtons();
-               }
-
-               private void populateGroupCmp(Composite parent) {
-                       EclipseUiUtils.clear(parent);
-                       trueChk = new Button(parent, SWT.CHECK);
-                       trueChk.setText("Add to group. (It will remove user(s) from the " + "corresponding group if unchecked)");
-                       trueChk.setSelection(true);
-                       trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
-               }
-
-               protected String getCommand() {
-                       return commands.get(chooseCommandCmb.getItem(chooseCommandCmb.getSelectionIndex()));
-               }
-
-               protected String getCommandLbl() {
-                       return chooseCommandCmb.getItem(chooseCommandCmb.getSelectionIndex());
-               }
-
-               @SuppressWarnings("unused")
-               protected boolean getBoleanValue() {
-                       // FIXME this is not consistent and will lead to errors.
-                       if ("argeo:enabled".equals(getCommand()))
-                               return trueChk.getSelection();
-                       else
-                               return !trueChk.getSelection();
-               }
-
-               @SuppressWarnings("unused")
-               protected String getStringValue() {
-                       String value = null;
-                       if (valueTxt != null) {
-                               value = valueTxt.getText();
-                               if ("".equals(value.trim()))
-                                       value = null;
-                       }
-                       return value;
-               }
-
-               protected char[] getPwdValue() {
-                       // We do not directly reset the password text fields: There is no
-                       // need to over secure this process: setting a pwd to multi users
-                       // at the same time is anyhow a bad practice and should be used only
-                       // in test environment or for temporary access
-                       if (pwdTxt == null || pwdTxt.isDisposed())
-                               return null;
-                       else
-                               return pwdTxt.getText().toCharArray();
-               }
-
-               protected String getEmailValue() {
-                       // We do not directly reset the password text fields: There is no
-                       // need to over secure this process: setting a pwd to multi users
-                       // at the same time is anyhow a bad practice and should be used only
-                       // in test environment or for temporary access
-                       if (valueTxt == null || valueTxt.isDisposed())
-                               return null;
-                       else
-                               return valueTxt.getText();
-               }
-       }
-
-       /**
-        * Displays a list of users with a check box to be able to choose some of them
-        */
-       private class ChooseUsersWizardPage extends WizardPage implements IPageChangedListener {
-               private static final long serialVersionUID = 7651807402211214274L;
-               private ChooseUserTableViewer userTableCmp;
-
-               public ChooseUsersWizardPage() {
-                       super("Choose Users");
-                       setTitle("Select users who will be impacted");
-               }
-
-               @Override
-               public void createControl(Composite parent) {
-                       Composite pageCmp = new Composite(parent, SWT.NONE);
-                       pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-                       // Define the displayed columns
-                       List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-                       columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150));
-                       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(CmsConstants.ROLE_ADMIN))
-                               columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300));
-
-                       userTableCmp = new ChooseUserTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-                       userTableCmp.setLayoutData(EclipseUiUtils.fillAll());
-                       userTableCmp.setColumnDefinitions(columnDefs);
-                       userTableCmp.populate(true, true);
-                       userTableCmp.refresh();
-
-                       setControl(pageCmp);
-
-                       // Add listener to update message when shown
-                       final IWizardContainer wContainer = this.getContainer();
-                       if (wContainer instanceof IPageChangeProvider) {
-                               ((IPageChangeProvider) wContainer).addPageChangedListener(this);
-                       }
-
-               }
-
-               @Override
-               public void pageChanged(PageChangedEvent event) {
-                       if (event.getSelectedPage() == this) {
-                               String msg = "Chosen batch action: " + chooseCommandPage.getCommandLbl();
-                               ((WizardPage) event.getSelectedPage()).setMessage(msg);
-                       }
-               }
-
-               protected List<User> getSelectedUsers() {
-                       return userTableCmp.getSelectedUsers();
-               }
-
-               private class ChooseUserTableViewer extends LdifUsersTable {
-                       private static final long serialVersionUID = 5080437561015853124L;
-                       private final String[] knownProps = { LdapAttrs.uid.name(), LdapAttrs.DN, LdapAttrs.cn.name(),
-                                       LdapAttrs.givenName.name(), LdapAttrs.sn.name(), LdapAttrs.mail.name() };
-
-                       public ChooseUserTableViewer(Composite parent, int style) {
-                               super(parent, style);
-                       }
-
-                       @Override
-                       protected List<User> listFilteredElements(String filter) {
-                               Role[] roles;
-
-                               try {
-                                       StringBuilder builder = new StringBuilder();
-
-                                       StringBuilder tmpBuilder = new StringBuilder();
-                                       if (EclipseUiUtils.notEmpty(filter))
-                                               for (String prop : knownProps) {
-                                                       tmpBuilder.append("(");
-                                                       tmpBuilder.append(prop);
-                                                       tmpBuilder.append("=*");
-                                                       tmpBuilder.append(filter);
-                                                       tmpBuilder.append("*)");
-                                               }
-                                       if (tmpBuilder.length() > 1) {
-                                               builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
-                                                               .append(LdapObjs.inetOrgPerson.name()).append(")(|");
-                                               builder.append(tmpBuilder.toString());
-                                               builder.append("))");
-                                       } else
-                                               builder.append("(").append(LdapAttrs.objectClass.name()).append("=")
-                                                               .append(LdapObjs.inetOrgPerson.name()).append(")");
-                                       roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString());
-                               } catch (InvalidSyntaxException e) {
-                                       throw new CmsException("Unable to get roles with filter: " + filter, e);
-                               }
-                               List<User> users = new ArrayList<User>();
-                               for (Role role : roles)
-                                       // Prevent current logged in user to perform batch on
-                                       // himself
-                                       if (!UserAdminUtils.isCurrentUser((User) role))
-                                               users.add((User) role);
-                               return users;
-                       }
-               }
-       }
-
-       /** Summary of input data before launching the process */
-       private class ValidateAndLaunchWizardPage extends WizardPage implements IPageChangedListener {
-               private static final long serialVersionUID = 7098918351451743853L;
-               private ChosenUsersTableViewer userTableCmp;
-
-               public ValidateAndLaunchWizardPage() {
-                       super("Validate and launch");
-                       setTitle("Validate and launch");
-               }
-
-               @Override
-               public void createControl(Composite parent) {
-                       Composite pageCmp = new Composite(parent, SWT.NO_FOCUS);
-                       pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-                       List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-                       columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150));
-                       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(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());
-                       userTableCmp.setColumnDefinitions(columnDefs);
-                       userTableCmp.populate(false, false);
-                       userTableCmp.refresh();
-                       setControl(pageCmp);
-                       // Add listener to update message when shown
-                       final IWizardContainer wContainer = this.getContainer();
-                       if (wContainer instanceof IPageChangeProvider) {
-                               ((IPageChangeProvider) wContainer).addPageChangedListener(this);
-                       }
-               }
-
-               @Override
-               public void pageChanged(PageChangedEvent event) {
-                       if (event.getSelectedPage() == this) {
-                               @SuppressWarnings({ "unchecked", "rawtypes" })
-                               Object[] values = ((ArrayList) userListPage.getSelectedUsers())
-                                               .toArray(new Object[userListPage.getSelectedUsers().size()]);
-                               userTableCmp.getTableViewer().setInput(values);
-                               String msg = "Following batch action: [" + chooseCommandPage.getCommandLbl()
-                                               + "] will be perfomed on the users listed below.\n";
-                               // + "Are you sure you want to proceed?";
-                               setMessage(msg);
-                       }
-               }
-
-               private class ChosenUsersTableViewer extends LdifUsersTable {
-                       private static final long serialVersionUID = 7814764735794270541L;
-
-                       public ChosenUsersTableViewer(Composite parent, int style) {
-                               super(parent, style);
-                       }
-
-                       @Override
-                       protected List<User> listFilteredElements(String filter) {
-                               return userListPage.getSelectedUsers();
-                       }
-               }
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java
deleted file mode 100644 (file)
index 66f4420..0000000
+++ /dev/null
@@ -1,535 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import static org.argeo.cms.auth.UserAdminUtils.getProperty;
-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;
-import java.util.List;
-
-import javax.inject.Inject;
-
-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;
-import org.argeo.cms.e4.users.providers.DomainNameLP;
-import org.argeo.cms.e4.users.providers.RoleIconLP;
-import org.argeo.cms.e4.users.providers.UserFilter;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
-//import org.argeo.cms.ui.eclipse.forms.FormToolkit;
-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.util.naming.LdapAttrs;
-import org.eclipse.e4.ui.workbench.modeling.EPartService;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.TrayDialog;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerDropAdapter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.DropTargetEvent;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.dnd.TransferData;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.ToolBar;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Display/edit the properties of a given user */
-public class UserEditor extends AbstractRoleEditor {
-       // final static String ID = "UserEditor.mainPage";
-
-       @Inject
-       private EPartService partService;
-
-       // private final UserEditor editor;
-       // private UserAdminWrapper userAdminWrapper;
-
-       // Local configuration
-       // private final int PRE_TITLE_INDENT = 10;
-
-       // public UserMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) {
-       // super(editor, ID, "Main");
-       // this.editor = (UserEditor) editor;
-       // this.userAdminWrapper = userAdminWrapper;
-       // }
-
-       // protected void createFormContent(final IManagedForm mf) {
-       // ScrolledForm form = mf.getForm();
-       // Composite body = form.getBody();
-       // GridLayout mainLayout = new GridLayout();
-       // // mainLayout.marginRight = 10;
-       // body.setLayout(mainLayout);
-       // User user = editor.getDisplayedUser();
-       // appendOverviewPart(body, user);
-       // // Remove to ability to force the password for his own user. The user
-       // // must then use the change pwd feature
-       // appendMemberOfPart(body, user);
-       // }
-
-       @Override
-       protected void createUi(Composite body) {
-               // Composite body = new Composite(parent, SWT.BORDER);
-               GridLayout mainLayout = new GridLayout();
-               // mainLayout.marginRight = 10;
-               body.setLayout(mainLayout);
-               // body.getParent().setLayout(new GridLayout());
-               // body.setLayoutData(CmsUiUtils.fillAll());
-               User user = getDisplayedUser();
-               appendOverviewPart(body, user);
-               // Remove to ability to force the password for his own user. The user
-               // must then use the change pwd feature
-               appendMemberOfPart(body, user);
-       }
-
-       /** Creates the general section */
-       private void appendOverviewPart(final Composite parent, final User user) {
-               // FormToolkit tk = getManagedForm().getToolkit();
-
-               // Section section = tk.createSection(parent, SWT.NO_FOCUS);
-               // GridData gd = EclipseUiUtils.fillWidth();
-               // // gd.verticalAlignment = PRE_TITLE_INDENT;
-               // section.setLayoutData(gd);
-               Composite body = new Composite(parent, SWT.NONE);
-               body.setLayoutData(EclipseUiUtils.fillWidth());
-               // section.setClient(body);
-               // body.setLayout(new GridLayout(6, false));
-               body.setLayout(new GridLayout(2, false));
-
-               Text commonName = createReadOnlyLT(body, "Name", getProperty(user, cn));
-               Text distinguishedName = createReadOnlyLT(body, "Login", getProperty(user, uid));
-               Text firstName = createLT(body, "First name", getProperty(user, givenName));
-               Text lastName = createLT(body, "Last name", getProperty(user, sn));
-               Text email = createLT(body, "Email", getProperty(user, mail));
-
-               Link resetPwdLk = new Link(body, SWT.NONE);
-               if (!UserAdminUtils.isCurrentUser(user)) {
-                       resetPwdLk.setText("<a>Reset password</a>");
-               }
-               resetPwdLk.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
-
-               // create form part (controller)
-               AbstractFormPart part = new AbstractFormPart() {
-                       private MainInfoListener listener;
-
-                       @Override
-                       public void initialize(IManagedForm form) {
-                               super.initialize(form);
-                               listener = new MainInfoListener(parent.getDisplay(), this);
-                               userAdminWrapper.addListener(listener);
-                       }
-
-                       @Override
-                       public void dispose() {
-                               userAdminWrapper.removeListener(listener);
-                               super.dispose();
-                       }
-
-                       @SuppressWarnings("unchecked")
-                       public void commit(boolean onSave) {
-                               // TODO Sanity checks (mail validity...)
-                               user.getProperties().put(LdapAttrs.givenName.name(), firstName.getText());
-                               user.getProperties().put(LdapAttrs.sn.name(), lastName.getText());
-                               user.getProperties().put(LdapAttrs.cn.name(), commonName.getText());
-                               user.getProperties().put(LdapAttrs.mail.name(), email.getText());
-                               super.commit(onSave);
-                       }
-
-                       @Override
-                       public void refresh() {
-                               distinguishedName.setText(UserAdminUtils.getProperty(user, LdapAttrs.uid.name()));
-                               commonName.setText(UserAdminUtils.getProperty(user, LdapAttrs.cn.name()));
-                               firstName.setText(UserAdminUtils.getProperty(user, LdapAttrs.givenName.name()));
-                               lastName.setText(UserAdminUtils.getProperty(user, LdapAttrs.sn.name()));
-                               email.setText(UserAdminUtils.getProperty(user, LdapAttrs.mail.name()));
-                               refreshFormTitle(user);
-                               super.refresh();
-                       }
-               };
-
-               // Improve this: automatically generate CN when first or last name
-               // changes
-               ModifyListener cnML = new ModifyListener() {
-                       private static final long serialVersionUID = 4298649222869835486L;
-
-                       @Override
-                       public void modifyText(ModifyEvent event) {
-                               String first = firstName.getText();
-                               String last = lastName.getText();
-                               String cn = first.trim() + " " + last.trim() + " ";
-                               cn = cn.trim();
-                               commonName.setText(cn);
-                               // getManagedForm().getForm().setText(cn);
-                               updateEditorTitle(cn);
-                       }
-               };
-               firstName.addModifyListener(cnML);
-               lastName.addModifyListener(cnML);
-
-               ModifyListener defaultListener = new FormPartML(part);
-               firstName.addModifyListener(defaultListener);
-               lastName.addModifyListener(defaultListener);
-               email.addModifyListener(defaultListener);
-
-               if (!UserAdminUtils.isCurrentUser(user))
-                       resetPwdLk.addSelectionListener(new SelectionAdapter() {
-                               private static final long serialVersionUID = 5881800534589073787L;
-
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       new ChangePasswordDialog(user, "Reset password").open();
-                               }
-                       });
-
-               getManagedForm().addPart(part);
-       }
-
-       private class ChangePasswordDialog extends TrayDialog {
-               private static final long serialVersionUID = 2843538207460082349L;
-
-               private User user;
-               private Text password1;
-               private Text password2;
-               private String title;
-               // private FormToolkit tk;
-
-               public ChangePasswordDialog(User user, String title) {
-                       super(Display.getDefault().getActiveShell());
-                       // this.tk = tk;
-                       this.user = user;
-                       this.title = title;
-               }
-
-               protected Control createDialogArea(Composite parent) {
-                       Composite dialogarea = (Composite) super.createDialogArea(parent);
-                       dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-                       Composite body = new Composite(dialogarea, SWT.NO_FOCUS);
-                       body.setLayoutData(EclipseUiUtils.fillAll());
-                       GridLayout layout = new GridLayout(2, false);
-                       body.setLayout(layout);
-
-                       password1 = createLP(body, "New password", "");
-                       password2 = createLP(body, "Repeat password", "");
-                       parent.pack();
-                       return body;
-               }
-
-               @SuppressWarnings("unchecked")
-               @Override
-               protected void okPressed() {
-                       String msg = null;
-
-                       if (password1.getText().equals(""))
-                               msg = "Password cannot be empty";
-                       else if (password1.getText().equals(password2.getText())) {
-                               char[] newPassword = password1.getText().toCharArray();
-                               // userAdminWrapper.beginTransactionIfNeeded();
-                               userAdminWrapper.beginTransactionIfNeeded();
-                               user.getCredentials().put(null, newPassword);
-                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                               super.okPressed();
-                       } else {
-                               msg = "Passwords are not equals";
-                       }
-
-                       if (EclipseUiUtils.notEmpty(msg))
-                               MessageDialog.openError(getParentShell(), "Cannot reset pasword", msg);
-               }
-
-               protected void configureShell(Shell shell) {
-                       super.configureShell(shell);
-                       shell.setText(title);
-               }
-       }
-
-       private LdifUsersTable appendMemberOfPart(final Composite parent, User user) {
-               // Section section = addSection(tk, parent, "Roles");
-               // Composite body = (Composite) section.getClient();
-               // Composite body= parent;
-               Composite body = new Composite(parent, SWT.BORDER);
-               body.setLayout(new GridLayout());
-               body.setLayoutData(CmsSwtUtils.fillAll());
-
-               // boolean isAdmin = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN);
-
-               // Displayed columns
-               List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-               columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24));
-               columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150));
-               columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 100));
-               // Only show technical DN to administrators
-               // if (isAdmin)
-               // columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name",
-               // 300));
-
-               // Create and configure the table
-               final LdifUsersTable userViewerCmp = new MyUserTableViewer(body, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, user);
-
-               userViewerCmp.setColumnDefinitions(columnDefs);
-               // if (isAdmin)
-               // userViewerCmp.populateWithStaticFilters(false, false);
-               // else
-               userViewerCmp.populate(true, false);
-               GridData gd = EclipseUiUtils.fillAll();
-               gd.heightHint = 500;
-               userViewerCmp.setLayoutData(gd);
-
-               // Controllers
-               TableViewer userViewer = userViewerCmp.getTableViewer();
-               userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService));
-               int operations = DND.DROP_COPY | DND.DROP_MOVE;
-               Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
-               GroupDropListener dropL = new GroupDropListener(userAdminWrapper, userViewer, user);
-               userViewer.addDropSupport(operations, tt, dropL);
-
-               AbstractFormPart part = new AbstractFormPart() {
-
-                       private GroupChangeListener listener;
-
-                       @Override
-                       public void initialize(IManagedForm form) {
-                               super.initialize(form);
-                               listener = new GroupChangeListener(parent.getDisplay(), this);
-                               userAdminWrapper.addListener(listener);
-                       }
-
-                       public void commit(boolean onSave) {
-                               super.commit(onSave);
-                       }
-
-                       @Override
-                       public void dispose() {
-                               userAdminWrapper.removeListener(listener);
-                               super.dispose();
-                       }
-
-                       @Override
-                       public void refresh() {
-                               userViewerCmp.refresh();
-                               super.refresh();
-                       }
-               };
-               getManagedForm().addPart(part);
-               // addRemoveAbitily(body, userViewer, user);
-               // userViewerCmp.refresh();
-               String tooltip = "Remove " + UserAdminUtils.getUserLocalId(user.getName()) + " from the below selected groups";
-               Action action = new RemoveMembershipAction(userViewer, user, tooltip, SecurityAdminImages.ICON_REMOVE_DESC);
-               ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
-               ToolBar toolBar = toolBarManager.createControl(body);
-               toolBar.setLayoutData(CmsSwtUtils.fillWidth());
-               toolBarManager.add(action);
-               toolBarManager.update(true);
-               return userViewerCmp;
-       }
-
-       private class MyUserTableViewer extends LdifUsersTable {
-               private static final long serialVersionUID = 2653790051461237329L;
-
-               private Button showSystemRoleBtn;
-
-               private final User user;
-               private final UserFilter userFilter;
-
-               public MyUserTableViewer(Composite parent, int style, User user) {
-                       super(parent, style, true);
-                       this.user = user;
-                       userFilter = new UserFilter();
-               }
-
-               protected void populateStaticFilters(Composite staticFilterCmp) {
-                       staticFilterCmp.setLayout(new GridLayout());
-                       showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK);
-                       showSystemRoleBtn.setText("Show system roles");
-                       boolean showSysRole = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN);
-                       showSystemRoleBtn.setSelection(showSysRole);
-                       userFilter.setShowSystemRole(showSysRole);
-                       showSystemRoleBtn.addSelectionListener(new SelectionAdapter() {
-                               private static final long serialVersionUID = -7033424592697691676L;
-
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       userFilter.setShowSystemRole(showSystemRoleBtn.getSelection());
-                                       refresh();
-                               }
-                       });
-               }
-
-               @Override
-               protected List<User> listFilteredElements(String filter) {
-                       List<User> users = (List<User>) getFlatGroups(null);
-                       List<User> filteredUsers = new ArrayList<User>();
-                       if (users.contains(user))
-                               users.remove(user);
-                       userFilter.setSearchText(filter);
-                       for (User user : users)
-                               if (userFilter.select(null, null, user))
-                                       filteredUsers.add(user);
-                       return filteredUsers;
-               }
-       }
-
-       // private void addRemoveAbility(Composite parent, TableViewer userViewer, User
-       // user) {
-       // // Section section = sectionPart.getSection();
-       // ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
-       // ToolBar toolbar = toolBarManager.createControl(parent);
-       // final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
-       // toolbar.setCursor(handCursor);
-       // toolbar.addDisposeListener(new DisposeListener() {
-       // private static final long serialVersionUID = 3882131405820522925L;
-       //
-       // public void widgetDisposed(DisposeEvent e) {
-       // if ((handCursor != null) && (handCursor.isDisposed() == false)) {
-       // handCursor.dispose();
-       // }
-       // }
-       // });
-       //
-       // String tooltip = "Remove " + UserAdminUtils.getUserLocalId(user.getName()) +
-       // " from the below selected groups";
-       // Action action = new RemoveMembershipAction(userViewer, user, tooltip,
-       // SecurityAdminImages.ICON_REMOVE_DESC);
-       // toolBarManager.add(action);
-       // toolBarManager.update(true);
-       // // section.setTextClient(toolbar);
-       // }
-
-       private class RemoveMembershipAction extends Action {
-               private static final long serialVersionUID = -1337713097184522588L;
-
-               private final TableViewer userViewer;
-               private final User user;
-
-               RemoveMembershipAction(TableViewer userViewer, User user, String name, ImageDescriptor img) {
-                       super(name, img);
-                       this.userViewer = userViewer;
-                       this.user = user;
-               }
-
-               @Override
-               public void run() {
-                       ISelection selection = userViewer.getSelection();
-                       if (selection.isEmpty())
-                               return;
-
-                       @SuppressWarnings("unchecked")
-                       Iterator<Group> it = ((IStructuredSelection) selection).iterator();
-                       List<Group> groups = new ArrayList<Group>();
-                       while (it.hasNext()) {
-                               Group currGroup = it.next();
-                               groups.add(currGroup);
-                       }
-
-                       userAdminWrapper.beginTransactionIfNeeded();
-                       for (Group group : groups) {
-                               group.removeMember(user);
-                       }
-                       userAdminWrapper.commitOrNotifyTransactionStateChange();
-                       for (Group group : groups) {
-                               userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group));
-                       }
-               }
-       }
-
-       /**
-        * Defines the table as being a potential target to add group memberships
-        * (roles) to this user
-        */
-       private class GroupDropListener extends ViewerDropAdapter {
-               private static final long serialVersionUID = 2893468717831451621L;
-
-               private final UserAdminWrapper myUserAdminWrapper;
-               private final User myUser;
-
-               public GroupDropListener(UserAdminWrapper userAdminWrapper, Viewer userViewer, User user) {
-                       super(userViewer);
-                       this.myUserAdminWrapper = userAdminWrapper;
-                       this.myUser = user;
-               }
-
-               @Override
-               public boolean validateDrop(Object target, int operation, TransferData transferType) {
-                       // Target is always OK in a list only view
-                       // TODO check if not a string
-                       boolean validDrop = true;
-                       return validDrop;
-               }
-
-               @Override
-               public void drop(DropTargetEvent event) {
-                       String name = (String) event.data;
-                       UserAdmin myUserAdmin = myUserAdminWrapper.getUserAdmin();
-                       Role role = myUserAdmin.getRole(name);
-                       // TODO this check should be done before.
-                       if (role.getType() == Role.GROUP) {
-                               // TODO check if the user is already member of this group
-
-                               myUserAdminWrapper.beginTransactionIfNeeded();
-                               Group group = (Group) role;
-                               group.addMember(myUser);
-                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                               myUserAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group));
-                       }
-                       super.drop(event);
-               }
-
-               @Override
-               public boolean performDrop(Object data) {
-                       // userTableViewerCmp.refresh();
-                       return true;
-               }
-       }
-
-       // LOCAL HELPERS
-       private void refreshFormTitle(User group) {
-               // getManagedForm().getForm().setText(UserAdminUtils.getProperty(group,
-               // LdapAttrs.cn.name()));
-       }
-
-       /** Appends a section with a title */
-       // private Section addSection(FormToolkit tk, Composite parent, String title) {
-       // Section section = tk.createSection(parent, Section.TITLE_BAR);
-       // GridData gd = EclipseUiUtils.fillWidth();
-       // gd.verticalAlignment = PRE_TITLE_INDENT;
-       // section.setLayoutData(gd);
-       // section.setText(title);
-       // // section.getMenu().setVisible(true);
-       //
-       // Composite body = tk.createComposite(section, SWT.WRAP);
-       // body.setLayoutData(EclipseUiUtils.fillAll());
-       // section.setClient(body);
-       //
-       // return section;
-       // }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java
deleted file mode 100644 (file)
index c6d024e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import org.argeo.cms.e4.CmsE4Utils;
-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;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.User;
-
-/**
- * Default double click listener for the various user tables, will open the
- * clicked item in the editor
- */
-public class UserTableDefaultDClickListener implements IDoubleClickListener {
-       private final EPartService partService;
-
-       public UserTableDefaultDClickListener(EPartService partService) {
-               this.partService = partService;
-       }
-
-       public void doubleClick(DoubleClickEvent evt) {
-               if (evt.getSelection().isEmpty())
-                       return;
-               Object obj = ((IStructuredSelection) evt.getSelection()).getFirstElement();
-               User user = (User) obj;
-
-               String editorId = getEditorId(user);
-               CmsE4Utils.openEditor(partService, editorId, LdapAttrs.uid.name(), user.getName());
-       }
-
-       protected String getEditorId(User user) {
-               if (user instanceof Group)
-                       return "org.argeo.cms.e4.partdescriptor.groupEditor";
-               else
-                       return "org.argeo.cms.e4.partdescriptor.userEditor";
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java
deleted file mode 100644 (file)
index 720945c..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-package org.argeo.cms.e4.users;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.e4.users.providers.CommonNameLP;
-import org.argeo.cms.e4.users.providers.DomainNameLP;
-import org.argeo.cms.e4.users.providers.MailLP;
-import org.argeo.cms.e4.users.providers.UserDragListener;
-import org.argeo.cms.e4.users.providers.UserNameLP;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
-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;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdminEvent;
-import org.osgi.service.useradmin.UserAdminListener;
-
-/** List all users with filter - based on Ldif userAdmin */
-public class UsersView {
-       // private final static Log log = LogFactory.getLog(UsersView.class);
-
-       // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".usersView";
-
-       @Inject
-       private UserAdminWrapper userAdminWrapper;
-       @Inject
-       private EPartService partService;
-
-       // UI Objects
-       private LdifUsersTable userTableViewerCmp;
-       private TableViewer userViewer;
-       private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-
-       private UserAdminListener listener;
-
-       @PostConstruct
-       public void createPartControl(Composite parent, ESelectionService selectionService) {
-
-               parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-               // Define the displayed columns
-               columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150));
-               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(CmsConstants.ROLE_ADMIN))
-                       columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300));
-
-               // Create and configure the table
-               userTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-               userTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll());
-               userTableViewerCmp.setColumnDefinitions(columnDefs);
-               userTableViewerCmp.populate(true, false);
-
-               // Links
-               userViewer = userTableViewerCmp.getTableViewer();
-               userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService));
-               userViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
-                       @Override
-                       public void selectionChanged(SelectionChangedEvent event) {
-                               IStructuredSelection selection = (IStructuredSelection) event.getSelection();
-                               selectionService.setSelection(selection.toList());
-                       }
-               });
-               // getViewSite().setSelectionProvider(userViewer);
-
-               // Really?
-               userTableViewerCmp.refresh();
-
-               // Drag and drop
-               int operations = DND.DROP_COPY | DND.DROP_MOVE;
-               Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
-               userViewer.addDragSupport(operations, tt, new UserDragListener(userViewer));
-
-               // Register a useradmin listener
-               listener = new MyUiUAListener(parent.getDisplay());
-               userAdminWrapper.addListener(listener);
-       }
-
-       private class MyUiUAListener extends UiUserAdminListener {
-               public MyUiUAListener(Display display) {
-                       super(display);
-               }
-
-               @Override
-               public void roleChangedToUiThread(UserAdminEvent event) {
-                       if (userViewer != null && !userViewer.getTable().isDisposed())
-                               refresh();
-               }
-       }
-
-       private class MyUserTableViewer extends LdifUsersTable {
-               private static final long serialVersionUID = 8467999509931900367L;
-
-               private final String[] knownProps = { LdapAttrs.DN, LdapAttrs.uid.name(), LdapAttrs.cn.name(),
-                               LdapAttrs.givenName.name(), LdapAttrs.sn.name(), LdapAttrs.mail.name() };
-
-               public MyUserTableViewer(Composite parent, int style) {
-                       super(parent, style);
-               }
-
-               @Override
-               protected List<User> listFilteredElements(String filter) {
-                       Role[] roles;
-
-                       try {
-                               StringBuilder builder = new StringBuilder();
-
-                               StringBuilder tmpBuilder = new StringBuilder();
-                               if (EclipseUiUtils.notEmpty(filter))
-                                       for (String prop : knownProps) {
-                                               tmpBuilder.append("(");
-                                               tmpBuilder.append(prop);
-                                               tmpBuilder.append("=*");
-                                               tmpBuilder.append(filter);
-                                               tmpBuilder.append("*)");
-                                       }
-                               if (tmpBuilder.length() > 1) {
-                                       builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
-                                                       .append(LdapObjs.inetOrgPerson.name()).append(")(|");
-                                       builder.append(tmpBuilder.toString());
-                                       builder.append("))");
-                               } else
-                                       builder.append("(").append(LdapAttrs.objectClass.name()).append("=")
-                                                       .append(LdapObjs.inetOrgPerson.name()).append(")");
-                               roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString());
-                       } catch (InvalidSyntaxException e) {
-                               throw new CmsException("Unable to get roles with filter: " + filter, e);
-                       }
-                       List<User> users = new ArrayList<User>();
-                       for (Role role : roles)
-                               // if (role.getType() == Role.USER && role.getType() !=
-                               // Role.GROUP)
-                               users.add((User) role);
-                       return users;
-               }
-       }
-
-       public void refresh() {
-               userTableViewerCmp.refresh();
-       }
-
-       // Override generic view methods
-       @PreDestroy
-       public void dispose() {
-               userAdminWrapper.removeListener(listener);
-       }
-
-       @Focus
-       public void setFocus() {
-               userTableViewerCmp.setFocus();
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
-               this.userAdminWrapper = userAdminWrapper;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/DeleteGroups.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/DeleteGroups.java
deleted file mode 100644 (file)
index 742bc3f..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.argeo.cms.e4.users.handlers;
-
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.cms.e4.users.GroupsView;
-import org.argeo.cms.e4.users.UserAdminWrapper;
-import org.eclipse.e4.core.di.annotations.CanExecute;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Display;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Delete the selected groups */
-public class DeleteGroups {
-       // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID +
-       // ".deleteGroups";
-
-       /* DEPENDENCY INJECTION */
-       @Inject
-       private UserAdminWrapper userAdminWrapper;
-
-       @Inject
-       ESelectionService selectionService;
-
-       @SuppressWarnings("unchecked")
-       @Execute
-       public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) {
-               // ISelection selection = null;// HandlerUtil.getCurrentSelection(event);
-               // if (selection.isEmpty())
-               // return null;
-               //
-               // List<Group> groups = new ArrayList<Group>();
-               // Iterator<Group> it = ((IStructuredSelection) selection).iterator();
-
-               List<Group> selection = (List<Group>) selectionService.getSelection();
-               if (selection == null)
-                       return;
-
-               StringBuilder builder = new StringBuilder();
-               for (Group group : selection) {
-                       Group currGroup = group;
-                       String groupName = UserAdminUtils.getUserLocalId(currGroup.getName());
-                       // TODO add checks
-                       builder.append(groupName).append("; ");
-                       // groups.add(currGroup);
-               }
-
-               if (!MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "Delete Groups", "Are you sure that you "
-                               + "want to delete these groups?\n" + builder.substring(0, builder.length() - 2)))
-                       return;
-
-               userAdminWrapper.beginTransactionIfNeeded();
-               UserAdmin userAdmin = userAdminWrapper.getUserAdmin();
-               // IWorkbenchPage iwp =
-               // HandlerUtil.getActiveWorkbenchWindow(event).getActivePage();
-               for (Group group : selection) {
-                       String groupName = group.getName();
-                       // TODO find a way to close the editor cleanly if opened. Cannot be
-                       // done through the UserAdminListeners, it causes a
-                       // java.util.ConcurrentModificationException because disposing the
-                       // editor unregisters and disposes the listener
-                       // IEditorPart part = iwp.findEditor(new UserEditorInput(groupName));
-                       // if (part != null)
-                       // iwp.closeEditor(part, false);
-                       userAdmin.removeRole(groupName);
-               }
-               userAdminWrapper.commitOrNotifyTransactionStateChange();
-
-               // Update the view
-               for (Group group : selection) {
-                       userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, group));
-               }
-
-               // return null;
-       }
-
-       @CanExecute
-       public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) {
-               return part.getObject() instanceof GroupsView && selectionService.getSelection() != null;
-       }
-
-       /* DEPENDENCY INJECTION */
-       // public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
-       // this.userAdminWrapper = userAdminWrapper;
-       // }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/DeleteUsers.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/DeleteUsers.java
deleted file mode 100644 (file)
index d1afd22..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.argeo.cms.e4.users.handlers;
-
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.cms.e4.users.UserAdminWrapper;
-import org.argeo.cms.e4.users.UsersView;
-import org.eclipse.e4.core.di.annotations.CanExecute;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Display;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Delete the selected users */
-public class DeleteUsers {
-       // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".deleteUsers";
-
-       /* DEPENDENCY INJECTION */
-       @Inject
-       private UserAdminWrapper userAdminWrapper;
-
-       @SuppressWarnings("unchecked")
-       @Execute
-       public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) {
-               // ISelection selection = null;// HandlerUtil.getCurrentSelection(event);
-               // if (selection.isEmpty())
-               // return null;
-               List<User> selection = (List<User>) selectionService.getSelection();
-               if (selection == null)
-                       return;
-
-//             Iterator<User> it = ((IStructuredSelection) selection).iterator();
-//             List<User> users = new ArrayList<User>();
-               StringBuilder builder = new StringBuilder();
-
-               for(User user:selection) {
-                       User currUser = user;
-//                     User currUser = it.next();
-                       String userName = UserAdminUtils.getUserLocalId(currUser.getName());
-                       if (UserAdminUtils.isCurrentUser(currUser)) {
-                               MessageDialog.openError(Display.getCurrent().getActiveShell(), "Deletion forbidden",
-                                               "You cannot delete your own user this way.");
-                               return;
-                       }
-                       builder.append(userName).append("; ");
-//                     users.add(currUser);
-               }
-
-               if (!MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "Delete Users",
-                               "Are you sure that you want to delete these users?\n" + builder.substring(0, builder.length() - 2)))
-                       return;
-
-               userAdminWrapper.beginTransactionIfNeeded();
-               UserAdmin userAdmin = userAdminWrapper.getUserAdmin();
-               // IWorkbenchPage iwp =
-               // HandlerUtil.getActiveWorkbenchWindow(event).getActivePage();
-
-               for (User user : selection) {
-                       String userName = user.getName();
-                       // TODO find a way to close the editor cleanly if opened. Cannot be
-                       // done through the UserAdminListeners, it causes a
-                       // java.util.ConcurrentModificationException because disposing the
-                       // editor unregisters and disposes the listener
-                       // IEditorPart part = iwp.findEditor(new UserEditorInput(userName));
-                       // if (part != null)
-                       // iwp.closeEditor(part, false);
-                       userAdmin.removeRole(userName);
-               }
-               userAdminWrapper.commitOrNotifyTransactionStateChange();
-
-               for (User user : selection) {
-                       userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, user));
-               }
-       }
-
-       @CanExecute
-       public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) {
-               return part.getObject() instanceof UsersView && selectionService.getSelection() != null;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java
deleted file mode 100644 (file)
index 41e14e0..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-package org.argeo.cms.e4.users.handlers;
-
-import java.util.Dictionary;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.argeo.cms.e4.users.UserAdminWrapper;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.argeo.util.directory.DirectoryConf;
-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;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Create a new group */
-public class NewGroup {
-       // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newGroup";
-
-       /* DEPENDENCY INJECTION */
-       @Inject
-       private UserAdminWrapper userAdminWrapper;
-
-       @Execute
-       public Object execute() {
-               NewGroupWizard newGroupWizard = new NewGroupWizard();
-               newGroupWizard.setWindowTitle("Group creation");
-               WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), newGroupWizard);
-               dialog.open();
-               return null;
-       }
-
-       private class NewGroupWizard extends Wizard {
-
-               // Pages
-               private MainGroupInfoWizardPage mainGroupInfo;
-
-               // UI fields
-               private Text dNameTxt, commonNameTxt, descriptionTxt;
-               private Combo baseDnCmb;
-
-               public NewGroupWizard() {
-               }
-
-               @Override
-               public void addPages() {
-                       mainGroupInfo = new MainGroupInfoWizardPage();
-                       addPage(mainGroupInfo);
-               }
-
-               @SuppressWarnings({ "rawtypes", "unchecked" })
-               @Override
-               public boolean performFinish() {
-                       if (!canFinish())
-                               return false;
-                       String commonName = commonNameTxt.getText();
-                       try {
-                               userAdminWrapper.beginTransactionIfNeeded();
-                               String dn = getDn(commonName);
-                               Group group = (Group) userAdminWrapper.getUserAdmin().createRole(dn, Role.GROUP);
-                               Dictionary props = group.getProperties();
-                               String descStr = descriptionTxt.getText();
-                               if (EclipseUiUtils.notEmpty(descStr))
-                                       props.put(LdapAttrs.description.name(), descStr);
-                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                               userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CREATED, group));
-                               return true;
-                       } catch (Exception e) {
-                               ErrorFeedback.show("Cannot create new group " + commonName, e);
-                               return false;
-                       }
-               }
-
-               private class MainGroupInfoWizardPage extends WizardPage implements FocusListener {
-                       private static final long serialVersionUID = -3150193365151601807L;
-
-                       public MainGroupInfoWizardPage() {
-                               super("Main");
-                               setTitle("General information");
-                               setMessage("Please choose a domain, provide a common name " + "and a free description");
-                       }
-
-                       @Override
-                       public void createControl(Composite parent) {
-                               Composite bodyCmp = new Composite(parent, SWT.NONE);
-                               setControl(bodyCmp);
-                               bodyCmp.setLayout(new GridLayout(2, false));
-
-                               dNameTxt = EclipseUiUtils.createGridLT(bodyCmp, "Distinguished name");
-                               dNameTxt.setEnabled(false);
-
-                               baseDnCmb = createGridLC(bodyCmp, "Base DN");
-                               // Initialise before adding the listener to avoid NPE
-                               initialiseDnCmb(baseDnCmb);
-                               baseDnCmb.addFocusListener(this);
-
-                               commonNameTxt = EclipseUiUtils.createGridLT(bodyCmp, "Common name");
-                               commonNameTxt.addFocusListener(this);
-
-                               Label descLbl = new Label(bodyCmp, SWT.LEAD);
-                               descLbl.setText("Description");
-                               descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
-                               descriptionTxt = new Text(bodyCmp, SWT.LEAD | SWT.MULTI | SWT.WRAP | SWT.BORDER);
-                               descriptionTxt.setLayoutData(EclipseUiUtils.fillAll());
-                               descriptionTxt.addFocusListener(this);
-
-                               // Initialize buttons
-                               setPageComplete(false);
-                               getContainer().updateButtons();
-                       }
-
-                       @Override
-                       public void focusLost(FocusEvent event) {
-                               String name = commonNameTxt.getText();
-                               if (EclipseUiUtils.isEmpty(name))
-                                       dNameTxt.setText("");
-                               else
-                                       dNameTxt.setText(getDn(name));
-
-                               String message = checkComplete();
-                               if (message != null) {
-                                       setMessage(message, WizardPage.ERROR);
-                                       setPageComplete(false);
-                               } else {
-                                       setMessage("Complete", WizardPage.INFORMATION);
-                                       setPageComplete(true);
-                               }
-                               getContainer().updateButtons();
-                       }
-
-                       @Override
-                       public void focusGained(FocusEvent event) {
-                       }
-
-                       /** @return the error message or null if complete */
-                       protected String checkComplete() {
-                               String name = commonNameTxt.getText();
-
-                               if (name.trim().equals(""))
-                                       return "Common name must not be empty";
-                               Role role = userAdminWrapper.getUserAdmin().getRole(getDn(name));
-                               if (role != null)
-                                       return "Group " + name + " already exists";
-                               return null;
-                       }
-
-                       @Override
-                       public void setVisible(boolean visible) {
-                               super.setVisible(visible);
-                               if (visible)
-                                       if (baseDnCmb.getSelectionIndex() == -1)
-                                               baseDnCmb.setFocus();
-                                       else
-                                               commonNameTxt.setFocus();
-                       }
-               }
-
-               private Map<String, String> getDns() {
-                       return userAdminWrapper.getKnownBaseDns(true);
-               }
-
-               private String getDn(String cn) {
-                       Map<String, String> dns = getDns();
-                       String bdn = baseDnCmb.getText();
-                       if (EclipseUiUtils.notEmpty(bdn)) {
-                               Dictionary<String, ?> props = DirectoryConf.uriAsProperties(dns.get(bdn));
-                               String dn = LdapAttrs.cn.name() + "=" + cn + "," + DirectoryConf.groupBase.getValue(props) + "," + bdn;
-                               return dn;
-                       }
-                       return null;
-               }
-
-               private void initialiseDnCmb(Combo combo) {
-                       Map<String, String> dns = userAdminWrapper.getKnownBaseDns(true);
-                       if (dns.isEmpty())
-                               throw new CmsException("No writable base dn found. Cannot create group");
-                       combo.setItems(dns.keySet().toArray(new String[0]));
-                       if (dns.size() == 1)
-                               combo.select(0);
-               }
-       }
-
-       private Combo createGridLC(Composite parent, String label) {
-               Label lbl = new Label(parent, SWT.LEAD);
-               lbl.setText(label);
-               lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
-               Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY);
-               combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-               return combo;
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
-               this.userAdminWrapper = userAdminWrapper;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java
deleted file mode 100644 (file)
index 40a4460..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-package org.argeo.cms.e4.users.handlers;
-
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
-
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.cms.e4.users.UiAdminUtils;
-import org.argeo.cms.e4.users.UserAdminWrapper;
-import org.argeo.cms.swt.CmsException;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.argeo.util.directory.DirectoryConf;
-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;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdminEvent;
-
-/** Open a wizard that enables creation of a new user. */
-public class NewUser {
-       // private final static Log log = LogFactory.getLog(NewUser.class);
-       // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newUser";
-
-       /* DEPENDENCY INJECTION */
-       @Inject
-       private UserAdminWrapper userAdminWrapper;
-
-       @Execute
-       public Object execute() {
-               NewUserWizard newUserWizard = new NewUserWizard();
-               newUserWizard.setWindowTitle("User creation");
-               WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), newUserWizard);
-               dialog.open();
-               return null;
-       }
-
-       private class NewUserWizard extends Wizard {
-
-               // pages
-               private MainUserInfoWizardPage mainUserInfo;
-
-               // End user fields
-               private Text dNameTxt, usernameTxt, firstNameTxt, lastNameTxt, primaryMailTxt, pwd1Txt, pwd2Txt;
-               private Combo baseDnCmb;
-
-               public NewUserWizard() {
-
-               }
-
-               @Override
-               public void addPages() {
-                       mainUserInfo = new MainUserInfoWizardPage();
-                       addPage(mainUserInfo);
-                       String message = "Default wizard that also eases user creation tests:\n "
-                                       + "Mail and last name are automatically "
-                                       + "generated form the uid. Password are defauted to 'demo'.";
-                       mainUserInfo.setMessage(message, WizardPage.WARNING);
-               }
-
-               @SuppressWarnings({ "rawtypes", "unchecked" })
-               @Override
-               public boolean performFinish() {
-                       if (!canFinish())
-                               return false;
-                       String username = mainUserInfo.getUsername();
-                       userAdminWrapper.beginTransactionIfNeeded();
-                       try {
-                               User user = (User) userAdminWrapper.getUserAdmin().createRole(getDn(username), Role.USER);
-
-                               Dictionary props = user.getProperties();
-
-                               String lastNameStr = lastNameTxt.getText();
-                               if (EclipseUiUtils.notEmpty(lastNameStr))
-                                       props.put(LdapAttrs.sn.name(), lastNameStr);
-
-                               String firstNameStr = firstNameTxt.getText();
-                               if (EclipseUiUtils.notEmpty(firstNameStr))
-                                       props.put(LdapAttrs.givenName.name(), firstNameStr);
-
-                               String cn = UserAdminUtils.buildDefaultCn(firstNameStr, lastNameStr);
-                               if (EclipseUiUtils.notEmpty(cn))
-                                       props.put(LdapAttrs.cn.name(), cn);
-
-                               String mailStr = primaryMailTxt.getText();
-                               if (EclipseUiUtils.notEmpty(mailStr))
-                                       props.put(LdapAttrs.mail.name(), mailStr);
-
-                               char[] password = mainUserInfo.getPassword();
-                               user.getCredentials().put(null, password);
-                               userAdminWrapper.commitOrNotifyTransactionStateChange();
-                               userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CREATED, user));
-                               return true;
-                       } catch (Exception e) {
-                               ErrorFeedback.show("Cannot create new user " + username, e);
-                               return false;
-                       }
-               }
-
-               private class MainUserInfoWizardPage extends WizardPage implements ModifyListener {
-                       private static final long serialVersionUID = -3150193365151601807L;
-
-                       public MainUserInfoWizardPage() {
-                               super("Main");
-                               setTitle("Required Information");
-                       }
-
-                       @Override
-                       public void createControl(Composite parent) {
-                               Composite composite = new Composite(parent, SWT.NONE);
-                               composite.setLayout(new GridLayout(2, false));
-                               dNameTxt = EclipseUiUtils.createGridLT(composite, "Distinguished name", this);
-                               dNameTxt.setEnabled(false);
-
-                               baseDnCmb = createGridLC(composite, "Base DN");
-                               initialiseDnCmb(baseDnCmb);
-                               baseDnCmb.addModifyListener(this);
-                               baseDnCmb.addModifyListener(new ModifyListener() {
-                                       private static final long serialVersionUID = -1435351236582736843L;
-
-                                       @Override
-                                       public void modifyText(ModifyEvent event) {
-                                               String name = usernameTxt.getText();
-                                               dNameTxt.setText(getDn(name));
-                                       }
-                               });
-
-                               usernameTxt = EclipseUiUtils.createGridLT(composite, "Local ID", this);
-                               usernameTxt.addModifyListener(new ModifyListener() {
-                                       private static final long serialVersionUID = -1435351236582736843L;
-
-                                       @Override
-                                       public void modifyText(ModifyEvent event) {
-                                               String name = usernameTxt.getText();
-                                               if (name.trim().equals("")) {
-                                                       dNameTxt.setText("");
-                                                       lastNameTxt.setText("");
-                                                       primaryMailTxt.setText("");
-                                                       pwd1Txt.setText("");
-                                                       pwd2Txt.setText("");
-                                               } else {
-                                                       dNameTxt.setText(getDn(name));
-                                                       lastNameTxt.setText(name.toUpperCase());
-                                                       primaryMailTxt.setText(getMail(name));
-                                                       pwd1Txt.setText("demo");
-                                                       pwd2Txt.setText("demo");
-                                               }
-                                       }
-                               });
-
-                               primaryMailTxt = EclipseUiUtils.createGridLT(composite, "Email", this);
-                               firstNameTxt = EclipseUiUtils.createGridLT(composite, "First name", this);
-                               lastNameTxt = EclipseUiUtils.createGridLT(composite, "Last name", this);
-                               pwd1Txt = EclipseUiUtils.createGridLP(composite, "Password", this);
-                               pwd2Txt = EclipseUiUtils.createGridLP(composite, "Repeat password", this);
-                               setControl(composite);
-
-                               // Initialize buttons
-                               setPageComplete(false);
-                               getContainer().updateButtons();
-                       }
-
-                       @Override
-                       public void modifyText(ModifyEvent event) {
-                               String message = checkComplete();
-                               if (message != null) {
-                                       setMessage(message, WizardPage.ERROR);
-                                       setPageComplete(false);
-                               } else {
-                                       setMessage("Complete", WizardPage.INFORMATION);
-                                       setPageComplete(true);
-                               }
-                               getContainer().updateButtons();
-                       }
-
-                       /** @return error message or null if complete */
-                       protected String checkComplete() {
-                               String name = usernameTxt.getText();
-
-                               if (name.trim().equals(""))
-                                       return "User name must not be empty";
-                               Role role = userAdminWrapper.getUserAdmin().getRole(getDn(name));
-                               if (role != null)
-                                       return "User " + name + " already exists";
-                               if (!primaryMailTxt.getText().matches(UiAdminUtils.EMAIL_PATTERN))
-                                       return "Not a valid email address";
-                               if (lastNameTxt.getText().trim().equals(""))
-                                       return "Specify a last name";
-                               if (pwd1Txt.getText().trim().equals(""))
-                                       return "Specify a password";
-                               if (pwd2Txt.getText().trim().equals(""))
-                                       return "Repeat the password";
-                               if (!pwd2Txt.getText().equals(pwd1Txt.getText()))
-                                       return "Passwords are different";
-                               return null;
-                       }
-
-                       @Override
-                       public void setVisible(boolean visible) {
-                               super.setVisible(visible);
-                               if (visible)
-                                       if (baseDnCmb.getSelectionIndex() == -1)
-                                               baseDnCmb.setFocus();
-                                       else
-                                               usernameTxt.setFocus();
-                       }
-
-                       public String getUsername() {
-                               return usernameTxt.getText();
-                       }
-
-                       public char[] getPassword() {
-                               return pwd1Txt.getTextChars();
-                       }
-
-               }
-
-               private Map<String, String> getDns() {
-                       return userAdminWrapper.getKnownBaseDns(true);
-               }
-
-               private String getDn(String uid) {
-                       Map<String, String> dns = getDns();
-                       String bdn = baseDnCmb.getText();
-                       if (EclipseUiUtils.notEmpty(bdn)) {
-                               Dictionary<String, ?> props = DirectoryConf.uriAsProperties(dns.get(bdn));
-                               String dn = LdapAttrs.uid.name() + "=" + uid + "," + DirectoryConf.userBase.getValue(props) + "," + bdn;
-                               return dn;
-                       }
-                       return null;
-               }
-
-               private void initialiseDnCmb(Combo combo) {
-                       Map<String, String> dns = userAdminWrapper.getKnownBaseDns(true);
-                       if (dns.isEmpty())
-                               throw new CmsException("No writable base dn found. Cannot create user");
-                       combo.setItems(dns.keySet().toArray(new String[0]));
-                       if (dns.size() == 1)
-                               combo.select(0);
-               }
-
-               private String getMail(String username) {
-                       if (baseDnCmb.getSelectionIndex() == -1)
-                               return null;
-                       String baseDn = baseDnCmb.getText();
-                       try {
-                               LdapName name = new LdapName(baseDn);
-                               List<Rdn> rdns = name.getRdns();
-                               return username + "@" + (String) rdns.get(1).getValue() + '.' + (String) rdns.get(0).getValue();
-                       } catch (InvalidNameException e) {
-                               throw new CmsException("Unable to generate mail for " + username + " with base dn " + baseDn, e);
-                       }
-               }
-       }
-
-       private Combo createGridLC(Composite parent, String label) {
-               Label lbl = new Label(parent, SWT.LEAD);
-               lbl.setText(label);
-               lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
-               Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY);
-               combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-               return combo;
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
-               this.userAdminWrapper = userAdminWrapper;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/package-info.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/package-info.java
deleted file mode 100644 (file)
index cf3db1d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Users management handlers. */
-package org.argeo.cms.e4.users.handlers;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/package-info.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/package-info.java
deleted file mode 100644 (file)
index c6f14b0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Users management perspective. */
-package org.argeo.cms.e4.users;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java
deleted file mode 100644 (file)
index 2d8db67..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import org.argeo.cms.auth.UserAdminUtils;
-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 */
-public class CommonNameLP extends UserAdminAbstractLP {
-       private static final long serialVersionUID = 5256703081044911941L;
-
-       @Override
-       public String getText(User user) {
-               return UserAdminUtils.getProperty(user, LdapAttrs.cn.name());
-       }
-
-       @Override
-       public String getToolTipText(Object element) {
-               return UserAdminUtils.getProperty((User) element, LdapAttrs.DN);
-       }
-
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/DomainNameLP.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/DomainNameLP.java
deleted file mode 100644 (file)
index e23729d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import org.argeo.cms.auth.UserAdminUtils;
-import org.osgi.service.useradmin.User;
-
-/** The human friendly domain name for the corresponding user. */
-public class DomainNameLP extends UserAdminAbstractLP {
-       private static final long serialVersionUID = 5256703081044911941L;
-
-       @Override
-       public String getText(User user) {
-               return UserAdminUtils.getDomainName(user);
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java
deleted file mode 100644 (file)
index 52d3b85..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import org.argeo.cms.auth.UserAdminUtils;
-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 */
-public class MailLP extends UserAdminAbstractLP {
-       private static final long serialVersionUID = 8329764452141982707L;
-
-       @Override
-       public String getText(User user) {
-               return UserAdminUtils.getProperty(user, LdapAttrs.mail.name());
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java
deleted file mode 100644 (file)
index 8e12eed..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import org.argeo.api.cms.CmsContext;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.cms.e4.users.SecurityAdminImages;
-import org.argeo.util.naming.LdapAttrs;
-import org.eclipse.swt.graphics.Image;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-
-/** Provide a bundle specific image depending on the current user type */
-public class RoleIconLP extends UserAdminAbstractLP {
-       private static final long serialVersionUID = 6550449442061090388L;
-
-       @Override
-       public String getText(User user) {
-               return "";
-       }
-
-       @Override
-       public Image getImage(Object element) {
-               User user = (User) element;
-               String dn = user.getName();
-               if (dn.endsWith(CmsConstants.SYSTEM_ROLES_BASEDN))
-                       return SecurityAdminImages.ICON_ROLE;
-               else if (user.getType() == Role.GROUP) {
-                       String businessCategory = UserAdminUtils.getProperty(user, LdapAttrs.businessCategory);
-                       if (businessCategory != null && businessCategory.equals(CmsContext.WORKGROUP))
-                               return SecurityAdminImages.ICON_WORKGROUP;
-                       return SecurityAdminImages.ICON_GROUP;
-               } else
-                       return SecurityAdminImages.ICON_USER;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserAdminAbstractLP.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserAdminAbstractLP.java
deleted file mode 100644 (file)
index 29873db..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.cms.swt.CmsException;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.widgets.Display;
-import org.osgi.service.useradmin.User;
-
-/**
- * Utility class that add font modifications to a column label provider
- * depending on the given user properties
- */
-public abstract class UserAdminAbstractLP extends ColumnLabelProvider {
-       private static final long serialVersionUID = 137336765024922368L;
-
-       // private Font italic;
-       private Font bold;
-
-       @Override
-       public Font getFont(Object element) {
-               // Self as bold
-               try {
-                       LdapName selfUserName = UserAdminUtils.getCurrentUserLdapName();
-                       String userName = ((User) element).getName();
-                       LdapName userLdapName = new LdapName(userName);
-                       if (userLdapName.equals(selfUserName)) {
-                               if (bold == null)
-                                       bold = JFaceResources.getFontRegistry()
-                                                       .defaultFontDescriptor().setStyle(SWT.BOLD)
-                                                       .createFont(Display.getCurrent());
-                               return bold;
-                       }
-               } catch (InvalidNameException e) {
-                       throw new CmsException("cannot parse dn for " + element, e);
-               }
-
-               // Disabled as Italic
-               // Node userProfile = (Node) elem;
-               // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean())
-               // return italic;
-
-               return null;
-               // return super.getFont(element);
-       }
-
-       @Override
-       public String getText(Object element) {
-               User user = (User) element;
-               return getText(user);
-       }
-
-       public void setDisplay(Display display) {
-               // italic = JFaceResources.getFontRegistry().defaultFontDescriptor()
-               // .setStyle(SWT.ITALIC).createFont(display);
-               bold = JFaceResources.getFontRegistry().defaultFontDescriptor()
-                               .setStyle(SWT.BOLD).createFont(Display.getCurrent());
-       }
-
-       public abstract String getText(User user);
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserDragListener.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserDragListener.java
deleted file mode 100644 (file)
index 56a2624..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.dnd.DragSourceEvent;
-import org.eclipse.swt.dnd.DragSourceListener;
-import org.osgi.service.useradmin.User;
-
-/** Default drag listener to modify group and users via the UI */
-public class UserDragListener implements DragSourceListener {
-       private static final long serialVersionUID = -2074337775033781454L;
-       private final Viewer viewer;
-
-       public UserDragListener(Viewer viewer) {
-               this.viewer = viewer;
-       }
-
-       public void dragStart(DragSourceEvent event) {
-               // TODO implement finer checks
-               IStructuredSelection selection = (IStructuredSelection) viewer
-                               .getSelection();
-               if (selection.isEmpty() || selection.size() > 1)
-                       event.doit = false;
-               else
-                       event.doit = true;
-       }
-
-       public void dragSetData(DragSourceEvent event) {
-               // TODO Support multiple selection
-               Object obj = ((IStructuredSelection) viewer.getSelection())
-                               .getFirstElement();
-               if (obj != null) {
-                       User user = (User) obj;
-                       event.data = user.getName();
-               }
-       }
-
-       public void dragFinished(DragSourceEvent event) {
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java
deleted file mode 100644 (file)
index 7a7bfbf..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.auth.UserAdminUtils;
-import org.argeo.util.naming.LdapAttrs;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.osgi.service.useradmin.User;
-
-/**
- * Filter user list using JFace mechanism on the client (yet on the server) side
- * rather than having the UserAdmin to process the search
- */
-public class UserFilter extends ViewerFilter {
-       private static final long serialVersionUID = 5082509381672880568L;
-
-       private String searchString;
-       private boolean showSystemRole = true;
-
-       private final String[] knownProps = { LdapAttrs.DN, LdapAttrs.cn.name(), LdapAttrs.givenName.name(),
-                       LdapAttrs.sn.name(), LdapAttrs.uid.name(), LdapAttrs.description.name(), LdapAttrs.mail.name() };
-
-       public void setSearchText(String s) {
-               // ensure that the value can be used for matching
-               if (notEmpty(s))
-                       searchString = ".*" + s.toLowerCase() + ".*";
-               else
-                       searchString = ".*";
-       }
-
-       public void setShowSystemRole(boolean showSystemRole) {
-               this.showSystemRole = showSystemRole;
-       }
-
-       @Override
-       public boolean select(Viewer viewer, Object parentElement, Object element) {
-               User user = (User) element;
-               if (!showSystemRole && user.getName().matches(".*(" + CmsConstants.SYSTEM_ROLES_BASEDN + ")"))
-                       // UserAdminUtils.getProperty(user, LdifName.dn.name())
-                       // .toLowerCase().endsWith(AuthConstants.ROLES_BASEDN))
-                       return false;
-
-               if (searchString == null || searchString.length() == 0)
-                       return true;
-
-               if (user.getName().matches(searchString))
-                       return true;
-
-               for (String key : knownProps) {
-                       String currVal = UserAdminUtils.getProperty(user, key);
-                       if (notEmpty(currVal) && currVal.toLowerCase().matches(searchString))
-                               return true;
-               }
-               return false;
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserNameLP.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserNameLP.java
deleted file mode 100644 (file)
index 3cd00eb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.argeo.cms.e4.users.providers;
-
-import org.osgi.service.useradmin.User;
-
-/** Simply declare a label provider that returns the username of a user */
-public class UserNameLP extends UserAdminAbstractLP {
-       private static final long serialVersionUID = 6550449442061090388L;
-
-       @Override
-       public String getText(User user) {
-               return user.getName();
-       }
-}
diff --git a/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/package-info.java b/swt/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/package-info.java
deleted file mode 100644 (file)
index 33bef8d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Users management content providers. */
-package org.argeo.cms.e4.users.providers;
\ No newline at end of file
index 5b250eebfb3a1f0a8e50fb666196196f14413023..afaf71f983e6bdbdbf4065f1ebd6fd556c6887d8 100644 (file)
@@ -6,7 +6,7 @@
         <children xsi:type="basic:PartSashContainer" xmi:id="_qc16ECnCEei1F8sdBz8Mpw" elementId="org.argeo.cms.e4.rcp.partsashcontainer.0" horizontal="true">
           <children xsi:type="basic:PartStack" xmi:id="_RE87kDsXEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.rcp.partstack.1">
             <children xsi:type="basic:Part" xmi:id="_V1WvgDsXEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.rcp.part.files" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.files.NodeFsBrowserView" label="Files"/>
-            <children xsi:type="basic:Part" xmi:id="_vOqDQCnCEei1F8sdBz8Mpw" elementId="org.argeo.cms.e4.rcp.part.jcr" containerData="4000" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrBrowserView" label="JCR"/>
+            <children xsi:type="basic:Part" xmi:id="_vOqDQCnCEei1F8sdBz8Mpw" elementId="org.argeo.cms.e4.rcp.part.jcr" containerData="4000" contributionURI="bundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.jcr.JcrBrowserView" label="JCR"/>
           </children>
           <children xsi:type="basic:PartStack" xmi:id="_0eRiwCnCEei1F8sdBz8Mpw" elementId="org.argeo.cms.e4.rcp.partstack.0" containerData="6000">
             <tags>editorArea</tags>
@@ -15,7 +15,7 @@
       </children>
     </children>
   </children>
-  <descriptors xmi:id="__9SDsC8JEeq0koquN4xGyg" elementId="org.argeo.cms.e4.partdescriptor.nodeEditor" allowMultiple="true" category="editorArea" closeable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrNodeEditor"/>
+  <descriptors xmi:id="__9SDsC8JEeq0koquN4xGyg" elementId="org.argeo.cms.e4.partdescriptor.nodeEditor" allowMultiple="true" category="editorArea" closeable="true" contributionURI="bundleclass://org.argeo.cms.jcr.e4/org.argeo.cms.e4.jcr.JcrNodeEditor"/>
   <addons xmi:id="_c4iAgSnCEei1F8sdBz8Mpw" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
   <addons xmi:id="_c4iAginCEei1F8sdBz8Mpw" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
   <addons xmi:id="_c4iAgynCEei1F8sdBz8Mpw" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>