From e89dfe9dc78f57a9e6af8def551393d88f4747c6 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 4 Jan 2020 11:01:59 +0100 Subject: [PATCH] Integrate legacy Eclipse 3 support from Argeo Commons. --- dep/org.argeo.slc.dep.backend/pom.xml | 4 +- .../META-INF/MANIFEST.MF | 2 +- legacy/argeo-commons/.gitignore | 1 + legacy/argeo-commons/dep/.gitignore | 1 + .../dep/org.argeo.dep.cms.platform/.gitignore | 4 + .../META-INF/.gitignore | 1 + .../dep/org.argeo.dep.cms.platform/bnd.bnd | 0 .../build.properties | 2 + .../dep/org.argeo.dep.cms.platform/p2.inf | 2 + .../dep/org.argeo.dep.cms.platform/pom.xml | 458 ++++++++++ legacy/argeo-commons/dep/pom.xml | 102 +++ .../org.argeo.cms.ui.workbench.rap/.classpath | 9 + .../org.argeo.cms.ui.workbench.rap/.gitignore | 2 + .../org.argeo.cms.ui.workbench.rap/.project | 28 + .../META-INF/.gitignore | 1 + .../META-INF/spring/commands.xml | 21 + .../META-INF/spring/osgi.xml | 14 + .../OSGI-INF/l10n/bundle.properties | 1 + .../OSGI-INF/l10n/bundle_de.properties | 1 + .../OSGI-INF/l10n/bundle_fr.properties | 1 + .../OSGI-INF/l10n/bundle_ru.properties | 1 + .../org.argeo.cms.ui.workbench.rap/bnd.bnd | 14 + .../branding/afterLogout.html | 18 + .../branding/empty.html | 5 + .../branding/favicon.ico | Bin 0 -> 4286 bytes .../branding/login.html | 18 + .../branding/public.html | 18 + .../build.properties | 2 + .../icons/active.gif | Bin 0 -> 193 bytes .../icons/add.gif | Bin 0 -> 318 bytes .../icons/addFolder.gif | Bin 0 -> 343 bytes .../icons/addPrivileges.gif | Bin 0 -> 564 bytes .../icons/addRepo.gif | Bin 0 -> 964 bytes .../icons/addWorkspace.png | Bin 0 -> 479 bytes .../icons/binary.png | Bin 0 -> 523 bytes .../icons/browser.gif | Bin 0 -> 582 bytes .../icons/bundles.gif | Bin 0 -> 344 bytes .../icons/close-all.png | Bin 0 -> 538 bytes .../icons/closeAll.gif | Bin 0 -> 204 bytes .../icons/dumpNode.gif | Bin 0 -> 564 bytes .../icons/exit.png | Bin 0 -> 214 bytes .../icons/file.gif | Bin 0 -> 577 bytes .../icons/folder.gif | Bin 0 -> 219 bytes .../icons/getSize.gif | Bin 0 -> 587 bytes .../icons/home.gif | Bin 0 -> 583 bytes .../icons/home.png | Bin 0 -> 266 bytes .../icons/import_fs.png | Bin 0 -> 729 bytes .../icons/installed.gif | Bin 0 -> 183 bytes .../icons/main.gif | Bin 0 -> 310 bytes .../icons/node.gif | Bin 0 -> 586 bytes .../icons/nodes.gif | Bin 0 -> 166 bytes .../icons/osgi_explorer.gif | Bin 0 -> 344 bytes .../icons/password.gif | Bin 0 -> 564 bytes .../icons/person-logged-in.png | Bin 0 -> 359 bytes .../icons/preferences.png | Bin 0 -> 603 bytes .../icons/query.png | Bin 0 -> 1086 bytes .../icons/refresh.png | Bin 0 -> 465 bytes .../icons/remote_connected.gif | Bin 0 -> 159 bytes .../icons/remote_disconnected.gif | Bin 0 -> 155 bytes .../icons/remove.gif | Bin 0 -> 351 bytes .../icons/removePrivileges.gif | Bin 0 -> 636 bytes .../icons/rename.gif | Bin 0 -> 889 bytes .../icons/repositories.gif | Bin 0 -> 588 bytes .../icons/repository_connected.gif | Bin 0 -> 328 bytes .../icons/repository_disconnected.gif | Bin 0 -> 209 bytes .../icons/resolved.gif | Bin 0 -> 176 bytes .../icons/role.gif | Bin 0 -> 563 bytes .../icons/save-all.png | Bin 0 -> 283 bytes .../icons/save.png | Bin 0 -> 226 bytes .../icons/security.gif | Bin 0 -> 324 bytes .../icons/service_published.gif | Bin 0 -> 197 bytes .../icons/service_referenced.gif | Bin 0 -> 185 bytes .../icons/sort.gif | Bin 0 -> 162 bytes .../icons/starting.gif | Bin 0 -> 181 bytes .../icons/user.gif | Bin 0 -> 310 bytes .../icons/users.gif | Bin 0 -> 598 bytes .../icons/workspace_connected.png | Bin 0 -> 498 bytes .../icons/workspace_disconnected.png | Bin 0 -> 493 bytes .../org.argeo.cms.ui.workbench.rap/plugin.xml | 192 +++++ .../org.argeo.cms.ui.workbench.rap/pom.xml | 37 + .../ui/workbench/rap/AnonymousEntryPoint.java | 112 +++ .../ui/workbench/rap/RapActionBarAdvisor.java | 232 +++++ .../ui/workbench/rap/RapWindowAdvisor.java | 100 +++ .../ui/workbench/rap/RapWorkbenchAdvisor.java | 64 ++ .../ui/workbench/rap/RapWorkbenchLogin.java | 90 ++ .../ui/workbench/rap/SecureRapActivator.java | 38 + .../workbench/rap/SpnegoWorkbenchLogin.java | 99 +++ .../ui/workbench/rap/commands/OpenHome.java | 48 ++ .../ui/workbench/rap/commands/UserMenu.java | 30 + .../org.argeo.cms.ui.workbench/.classpath | 9 + .../org.argeo.cms.ui.workbench/.gitignore | 2 + .../org.argeo.cms.ui.workbench/.project | 28 + .../META-INF/.gitignore | 1 + .../META-INF/spring/commands.xml | 55 ++ .../META-INF/spring/common.xml | 22 + .../META-INF/spring/osgi.xml | 37 + .../META-INF/spring/parts.xml | 68 ++ .../OSGI-INF/l10n/bundle.properties | 1 + .../OSGI-INF/l10n/bundle_de.properties | 1 + .../org.argeo.cms.ui.workbench/bnd.bnd | 26 + .../build.properties | 7 + .../keyring.properties | 1 + .../org.argeo.cms.ui.workbench/plugin.xml | 807 ++++++++++++++++++ .../org.argeo.cms.ui.workbench/pom.xml | 57 ++ .../cms/spring/AbstractSystemExecution.java | 64 ++ ...catedApplicationContextInitialization.java | 80 ++ .../cms/spring/SimpleRoleRegistration.java | 89 ++ .../cms/spring/osgi/OsgiModuleLabel.java | 41 + .../cms/ui/workbench/CmsWorkbenchStyles.java | 8 + .../ui/workbench/JcrBrowserPerspective.java | 34 + .../ui/workbench/MaintenancePerspective.java | 42 + .../ui/workbench/OsgiExplorerPerspective.java | 28 + .../workbench/SecurityAdminPerspective.java | 36 + .../cms/ui/workbench/UserHomePerspective.java | 38 + .../cms/ui/workbench/WorkbenchUiPlugin.java | 160 ++++ .../cms/ui/workbench/commands/DoNothing.java | 15 + .../commands/OpenChangePasswordDialog.java | 176 ++++ .../cms/ui/workbench/commands/OpenEditor.java | 60 ++ .../commands/OpenHomePerspective.java | 38 + .../internal/WorkbenchConstants.java | 21 + .../internal/jcr/commands/AddFolderNode.java | 92 ++ .../internal/jcr/commands/AddPrivileges.java | 87 ++ .../jcr/commands/AddRemoteRepository.java | 217 +++++ .../jcr/commands/ConfigurableNodeDump.java | 295 +++++++ .../jcr/commands/CreateWorkspace.java | 71 ++ .../internal/jcr/commands/DeleteNodes.java | 118 +++ .../internal/jcr/commands/DumpNode.java | 105 +++ .../internal/jcr/commands/EditNode.java | 65 ++ .../internal/jcr/commands/GetNodeSize.java | 101 +++ .../internal/jcr/commands/Refresh.java | 67 ++ .../jcr/commands/RemovePrivileges.java | 206 +++++ .../jcr/commands/RemoveRemoteRepository.java | 51 ++ .../internal/jcr/commands/RenameNode.java | 83 ++ .../internal/jcr/commands/SortChildNodes.java | 49 ++ .../internal/jcr/commands/UploadFiles.java | 132 +++ .../jcr/parts/AbstractJcrQueryEditor.java | 350 ++++++++ .../jcr/parts/AddPrivilegeWizard.java | 278 ++++++ .../internal/jcr/parts/ChildNodesPage.java | 106 +++ .../internal/jcr/parts/ChooseNameDialog.java | 68 ++ .../jcr/parts/GenericNodeEditorInput.java | 107 +++ .../internal/jcr/parts/GenericNodePage.java | 182 ++++ .../jcr/parts/GenericPropertyPage.java | 165 ++++ .../jcr/parts/JcrQueryEditorInput.java | 69 ++ .../internal/jcr/parts/NodeEditorInput.java | 62 ++ .../jcr/parts/NodePrivilegesPage.java | 238 ++++++ .../jcr/parts/NodeVersionHistoryPage.java | 289 +++++++ .../jcr/parts/StringNodeEditorInput.java | 121 +++ .../internal/useradmin/PartStateChanged.java | 58 ++ .../useradmin/SecurityAdminImages.java | 46 + .../internal/useradmin/UiAdminUtils.java | 40 + .../useradmin/UiUserAdminListener.java | 27 + .../internal/useradmin/UserAdminWrapper.java | 127 +++ .../useradmin/commands/DeleteGroups.java | 95 +++ .../useradmin/commands/DeleteUsers.java | 99 +++ .../useradmin/commands/ForceRefresh.java | 43 + .../internal/useradmin/commands/NewGroup.java | 240 ++++++ .../internal/useradmin/commands/NewUser.java | 322 +++++++ .../useradmin/commands/SaveArgeoUser.java | 47 + .../useradmin/commands/UserBatchUpdate.java | 44 + .../commands/UserTransactionHandler.java | 93 ++ .../useradmin/parts/ArgeoUserEditorInput.java | 66 ++ .../useradmin/parts/GroupMainPage.java | 523 ++++++++++++ .../internal/useradmin/parts/GroupsView.java | 240 ++++++ .../parts/UserBatchUpdateWizard.java | 627 ++++++++++++++ .../internal/useradmin/parts/UserEditor.java | 229 +++++ .../useradmin/parts/UserEditorInput.java | 69 ++ .../useradmin/parts/UserMainPage.java | 571 +++++++++++++ .../internal/useradmin/parts/UsersView.java | 194 +++++ .../useradmin/providers/CommonNameLP.java | 21 + .../useradmin/providers/DomainNameLP.java | 14 + .../internal/useradmin/providers/MailLP.java | 15 + .../useradmin/providers/RoleIconLP.java | 35 + .../providers/UserAdminAbstractLP.java | 66 ++ .../useradmin/providers/UserDragListener.java | 40 + .../useradmin/providers/UserFilter.java | 58 ++ .../useradmin/providers/UserNameLP.java | 13 + .../UserTableDefaultDClickListener.java | 43 + .../providers/UserTransactionProvider.java | 74 ++ .../ui/workbench/jcr/DefaultNodeEditor.java | 147 ++++ .../workbench/jcr/GenericJcrQueryEditor.java | 63 ++ .../cms/ui/workbench/jcr/JcrBrowserView.java | 340 ++++++++ .../ui/workbench/jcr/NodeFsBrowserView.java | 58 ++ .../jcr/WorkbenchJcrDClickListener.java | 101 +++ .../cms/ui/workbench/messages.properties | 29 + .../cms/ui/workbench/osgi/BundleNode.java | 46 + .../cms/ui/workbench/osgi/BundlesView.java | 126 +++ .../ui/workbench/osgi/CmsSessionsView.java | 186 ++++ .../cms/ui/workbench/osgi/ModulesView.java | 106 +++ .../workbench/osgi/MultiplePackagesView.java | 177 ++++ .../ui/workbench/osgi/OsgiExplorerImages.java | 35 + .../workbench/osgi/ServiceReferenceNode.java | 46 + .../ui/workbench/osgi/StateLabelProvider.java | 82 ++ .../ui/workbench/useradmin/AdminLogView.java | 88 ++ .../useradmin/LogContentProvider.java | 188 ++++ .../cms/ui/workbench/useradmin/LogView.java | 77 ++ .../ui/workbench/useradmin/UserProfile.java | 80 ++ .../cms/ui/workbench/util/CommandUtils.java | 152 ++++ .../cms/ui/workbench/util/PrivilegedJob.java | 49 ++ .../workbench/util/RolesSourceProvider.java | 49 ++ .../spring/ApplicationContextTracker.java | 152 ++++ .../eclipse/spring/SpringCommandHandler.java | 93 ++ .../spring/SpringExtensionFactory.java | 113 +++ .../org.argeo.ext.rap.ui.workbench/.gitignore | 1 + .../org.argeo.ext.rap.ui.workbench/.project | 20 + .../META-INF/.gitignore | 1 + .../META-INF/spring/osgi.xml | 19 + .../org.argeo.ext.rap.ui.workbench/bnd.bnd | 4 + .../build.properties | 2 + .../org.argeo.ext.rap.ui.workbench/pom.xml | 13 + legacy/argeo-commons/pom.xml | 76 ++ legacy/pom.xml | 17 + org.argeo.slc.client.rap/pom.xml | 8 +- org.argeo.slc.client.ui.dist/pom.xml | 12 +- org.argeo.slc.client.ui/pom.xml | 8 +- org.argeo.slc.e4/SlcMain.java | 338 -------- pom.xml | 7 +- 216 files changed, 14533 insertions(+), 354 deletions(-) create mode 100644 legacy/argeo-commons/.gitignore create mode 100644 legacy/argeo-commons/dep/.gitignore create mode 100644 legacy/argeo-commons/dep/org.argeo.dep.cms.platform/.gitignore create mode 100644 legacy/argeo-commons/dep/org.argeo.dep.cms.platform/META-INF/.gitignore create mode 100644 legacy/argeo-commons/dep/org.argeo.dep.cms.platform/bnd.bnd create mode 100644 legacy/argeo-commons/dep/org.argeo.dep.cms.platform/build.properties create mode 100644 legacy/argeo-commons/dep/org.argeo.dep.cms.platform/p2.inf create mode 100644 legacy/argeo-commons/dep/org.argeo.dep.cms.platform/pom.xml create mode 100644 legacy/argeo-commons/dep/pom.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.classpath create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.gitignore create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.project create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/.gitignore create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/osgi.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_de.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_fr.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_ru.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/bnd.bnd create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/afterLogout.html create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/empty.html create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/favicon.ico create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/login.html create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/public.html create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/build.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/active.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/add.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addFolder.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addPrivileges.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addRepo.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addWorkspace.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/binary.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/browser.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/bundles.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/close-all.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/closeAll.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/dumpNode.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/exit.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/file.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/folder.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/getSize.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/home.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/home.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/import_fs.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/installed.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/main.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/node.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/nodes.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/osgi_explorer.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/password.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/person-logged-in.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/preferences.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/query.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/refresh.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/remote_connected.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/remote_disconnected.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/remove.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/removePrivileges.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/rename.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repositories.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repository_connected.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repository_disconnected.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/resolved.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/role.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/save-all.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/save.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/security.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/service_published.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/service_referenced.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/sort.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/starting.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/user.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/users.gif create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/workspace_connected.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/workspace_disconnected.png create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/plugin.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/pom.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/AnonymousEntryPoint.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapActionBarAdvisor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWindowAdvisor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchAdvisor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchLogin.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SecureRapActivator.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SpnegoWorkbenchLogin.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/OpenHome.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/UserMenu.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/.classpath create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/.gitignore create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/.project create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/.gitignore create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/common.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/osgi.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle_de.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/bnd.bnd create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/build.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/keyring.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/plugin.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/pom.xml create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AbstractSystemExecution.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AuthenticatedApplicationContextInitialization.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/SimpleRoleRegistration.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/osgi/OsgiModuleLabel.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/CmsWorkbenchStyles.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/MaintenancePerspective.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/OsgiExplorerPerspective.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityAdminPerspective.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/WorkbenchUiPlugin.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/DoNothing.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenChangePasswordDialog.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenEditor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenHomePerspective.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/WorkbenchConstants.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddFolderNode.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddPrivileges.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/ConfigurableNodeDump.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/CreateWorkspace.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DeleteNodes.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DumpNode.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/EditNode.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/GetNodeSize.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/Refresh.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemovePrivileges.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemoveRemoteRepository.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RenameNode.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/SortChildNodes.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/UploadFiles.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChildNodesPage.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChooseNameDialog.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodePage.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericPropertyPage.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeEditorInput.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/PartStateChanged.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/SecurityAdminImages.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiAdminUtils.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiUserAdminListener.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UserAdminWrapper.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteGroups.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteUsers.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/ForceRefresh.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewGroup.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewUser.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/SaveArgeoUser.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserBatchUpdate.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserTransactionHandler.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/ArgeoUserEditorInput.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupMainPage.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupsView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserBatchUpdateWizard.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditorInput.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserMainPage.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UsersView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/CommonNameLP.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/DomainNameLP.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/MailLP.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/RoleIconLP.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserAdminAbstractLP.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserDragListener.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserFilter.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserNameLP.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTableDefaultDClickListener.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTransactionProvider.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/DefaultNodeEditor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/GenericJcrQueryEditor.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrBrowserView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/WorkbenchJcrDClickListener.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/messages.properties create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundleNode.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundlesView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/CmsSessionsView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ModulesView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/MultiplePackagesView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/OsgiExplorerImages.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ServiceReferenceNode.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/StateLabelProvider.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/AdminLogView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogContentProvider.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogView.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserProfile.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/CommandUtils.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/PrivilegedJob.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/RolesSourceProvider.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/ApplicationContextTracker.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringCommandHandler.java create mode 100644 legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringExtensionFactory.java create mode 100644 legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.gitignore create mode 100644 legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.project create mode 100644 legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/.gitignore create mode 100644 legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/spring/osgi.xml create mode 100644 legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/bnd.bnd create mode 100644 legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/build.properties create mode 100644 legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/pom.xml create mode 100644 legacy/argeo-commons/pom.xml create mode 100644 legacy/pom.xml delete mode 100644 org.argeo.slc.e4/SlcMain.java diff --git a/dep/org.argeo.slc.dep.backend/pom.xml b/dep/org.argeo.slc.dep.backend/pom.xml index 8816fe9f0..77792933c 100644 --- a/dep/org.argeo.slc.dep.backend/pom.xml +++ b/dep/org.argeo.slc.dep.backend/pom.xml @@ -104,9 +104,9 @@ - org.argeo.commons + org.argeo.slc.legacy.commons org.argeo.dep.cms.platform - ${version.argeo-commons} + ${version.argeo-commons-legacy} diff --git a/dep/org.argeo.slc.dep.spring/META-INF/MANIFEST.MF b/dep/org.argeo.slc.dep.spring/META-INF/MANIFEST.MF index a0edd6303..5117c8973 100644 --- a/dep/org.argeo.slc.dep.spring/META-INF/MANIFEST.MF +++ b/dep/org.argeo.slc.dep.spring/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: SLC Agent based on Spring Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-SymbolicName: org.argeo.slc.dep.spring -Bundle-Version: 2.1.17.SNAPSHOT-r202001021027 +Bundle-Version: 2.1.17.SNAPSHOT-r202001040954 Private-Package: !* SLC-Category: org.argeo.slc SLC-ModularDistribution: default diff --git a/legacy/argeo-commons/.gitignore b/legacy/argeo-commons/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/legacy/argeo-commons/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/legacy/argeo-commons/dep/.gitignore b/legacy/argeo-commons/dep/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/legacy/argeo-commons/dep/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/.gitignore b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/.gitignore new file mode 100644 index 000000000..e26e09f82 --- /dev/null +++ b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/.gitignore @@ -0,0 +1,4 @@ +/target/ +/feature.xml +/modularDistribution.csv +/*-maven.target diff --git a/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/META-INF/.gitignore b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/META-INF/.gitignore new file mode 100644 index 000000000..4854a41b9 --- /dev/null +++ b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/bnd.bnd b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/bnd.bnd new file mode 100644 index 000000000..e69de29bb diff --git a/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/build.properties b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/build.properties new file mode 100644 index 000000000..edef3d9d1 --- /dev/null +++ b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/build.properties @@ -0,0 +1,2 @@ +bin.includes = feature.xml,\ + modularDistribution.csv diff --git a/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/p2.inf b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/p2.inf new file mode 100644 index 000000000..0423aa509 --- /dev/null +++ b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/p2.inf @@ -0,0 +1,2 @@ +properties.1.name=org.eclipse.equinox.p2.type.category +properties.1.value=true \ No newline at end of file diff --git a/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/pom.xml b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/pom.xml new file mode 100644 index 000000000..249782a8b --- /dev/null +++ b/legacy/argeo-commons/dep/org.argeo.dep.cms.platform/pom.xml @@ -0,0 +1,458 @@ + + + 4.0.0 + + org.argeo.slc.legacy.commons + legacy-dep + 2.1.85-SNAPSHOT + .. + + org.argeo.dep.cms.platform + CMS Platform (Legacy) + + + + + org.argeo.commons + org.argeo.dep.cms.node + ${version.argeo-commons} + pom + + + + + org.argeo.tp.rap.e4 + org.eclipse.rap.rwt + + + org.argeo.tp.rap.e4 + org.eclipse.core.commands + + + org.argeo.tp.rap.e4 + org.eclipse.rap.jface + + + org.argeo.tp.rap.e4 + org.eclipse.rap.filedialog + + + org.argeo.tp.rap.e4 + org.eclipse.rap.fileupload + + + + + org.argeo.commons + org.argeo.eclipse.ui + ${version.argeo-commons} + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + + + org.argeo.commons + org.argeo.cms.ui + ${version.argeo-commons} + + + org.argeo.commons + org.argeo.cms.ui.theme + ${version.argeo-commons} + + + + + org.argeo.slc.legacy.commons + org.argeo.cms.ui.workbench + 2.1.85-SNAPSHOT + + + org.argeo.slc.legacy.commons + org.argeo.cms.ui.workbench.rap + 2.1.85-SNAPSHOT + + + org.argeo.slc.legacy.commons + org.argeo.ext.rap.ui.workbench + 2.1.85-SNAPSHOT + + + + + + + + + org.argeo.tp.bouncycastle + bcmail + + + org.argeo.tp.bouncycastle + bcpg + + + org.argeo.tp.apache.ant + org.apache.ant + + + org.argeo.tp.apache.ant + org.apache.ant.launch + + + + + + + + + + + org.argeo.tp.javax + javax.mail + + + + + org.argeo.tp.spring + org.springframework.beans + + + org.argeo.tp.spring + org.springframework.core + + + org.argeo.tp.javax + javax.el + + + org.argeo.tp.gemini + org.eclipse.gemini.blueprint.core + + + org.argeo.tp.gemini + org.eclipse.gemini.blueprint.extender + + + org.argeo.tp.gemini + org.eclipse.gemini.blueprint.io + + + org.argeo.tp.misc + org.aspectj.weaver + + + org.argeo.tp.misc + org.aopalliance + + + org.argeo.tp.spring + org.springframework.aop + + + org.argeo.tp.spring + org.springframework.context + + + org.argeo.tp.spring + org.springframework.expression + + + org.argeo.tp.spring + org.springframework.instrument + + + + + org.argeo.tp.spring + org.springframework.aspects + + + org.argeo.tp.spring + org.springframework.context.support + + + org.argeo.tp.spring + org.springframework.jdbc + + + org.argeo.tp.spring + org.springframework.tx + + + org.argeo.tp.spring + org.springframework.web + + + org.argeo.tp.spring + org.springframework.web.servlet + + + + + org.argeo.tp.equinox + org.eclipse.equinox.http.registry + + + + + org.argeo.tp.rap.platform + org.eclipse.core.databinding + + + org.argeo.tp.rap.platform + org.eclipse.core.databinding.beans + + + org.argeo.tp.rap.platform + org.eclipse.core.runtime + + + org.argeo.tp.rap.platform + org.eclipse.core.databinding.property + + + org.argeo.tp.rap.platform + com.ibm.icu + + + org.argeo.tp.rap.platform + org.eclipse.core.contenttype + + + org.argeo.tp.rap.platform + org.eclipse.rap.rwt.osgi + + + org.argeo.tp.rap.platform + org.eclipse.rap.jface.databinding + + + org.argeo.tp.rap.platform + org.eclipse.core.jobs + + + org.argeo.tp.rap.platform + org.eclipse.core.expressions + + + org.argeo.tp.rap.platform + org.eclipse.core.databinding.observable + + + org.argeo.tp.rap.platform + org.eclipse.help + + + + + org.argeo.tp.rap.platform + org.eclipse.rap.ui + + + org.argeo.tp.rap.platform + org.eclipse.rap.ui.forms + + + org.argeo.tp.rap.platform + org.eclipse.rap.ui.views + + + org.argeo.tp.rap.platform + org.eclipse.rap.ui.workbench + + + + + + org.argeo.tp + argeo-tp-rap-e3 + ${version.argeo-tp} + pom + import + + + + + + + rpmbuild + + + + maven-assembly-plugin + + + prepare-source + package + + single + + + + a2-source + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.codehaus.mojo + rpm-maven-plugin + + + rpm-argeo + package + + rpm + + + argeo-cms-platform + + + /usr/share/osgi + root + root + 644 + false + + + ${project.build.directory}/${project.artifactId}-${project.version}-a2-source + + **/*.jar + + + + + + + + + + + + + + argeo-cms-node + argeo-cms-platform-tp + + + + + + + + + + rpmbuild-tp + + + + maven-assembly-plugin + + + prepare-source-tp + package + + single + + + + a2-source-tp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.codehaus.mojo + rpm-maven-plugin + + + rpm-tp + package + + rpm + + + argeo-cms-platform-tp + ${version.argeo-tp} + + + /usr/share/osgi + root + root + 644 + false + + + ${project.build.directory}/${project.artifactId}-${project.version}-a2-source-tp + + **/*.jar + + + + + + + argeo-cms-node-tp + + + + + + + + + + \ No newline at end of file diff --git a/legacy/argeo-commons/dep/pom.xml b/legacy/argeo-commons/dep/pom.xml new file mode 100644 index 000000000..d4abd083e --- /dev/null +++ b/legacy/argeo-commons/dep/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + org.argeo.slc.legacy.commons + argeo-commons-legacy + 2.1.85-SNAPSHOT + .. + + legacy-dep + Commons Modular Distributions (Legacy) + pom + + org.argeo.dep.cms.platform + + + + + org.apache.felix + maven-bundle-plugin + + + default + + + + + org.argeo.maven.plugins + argeo-osgi-plugin + + + generate-descriptors + + descriptors + + generate-resources + + + + + maven-assembly-plugin + + + org.argeo.commons + assembly-descriptors + ${version.argeo-commons} + + + + false + + + + + + + org.argeo.tp.equinox + org.eclipse.osgi + test + + + org.argeo.tp.sdk + org.junit + test + + + + + check-osgi + + + + org.argeo.maven.plugins + argeo-osgi-plugin + + + check-osgi + test + + equinox + + + true + + + + + + + + + org.argeo.commons + org.argeo.osgi.boot + ${version.argeo-commons} + test + + + + + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.classpath b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.classpath new file mode 100644 index 000000000..457b11571 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.classpath @@ -0,0 +1,9 @@ + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.gitignore b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.project b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.project new file mode 100644 index 000000000..49b4b902d --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/.project @@ -0,0 +1,28 @@ + + + org.argeo.cms.ui.workbench.rap + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/.gitignore b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/.gitignore new file mode 100644 index 000000000..4854a41b9 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml new file mode 100644 index 000000000..2bfa179a4 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/commands.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/osgi.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/osgi.xml new file mode 100644 index 000000000..231b7d883 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/META-INF/spring/osgi.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle.properties new file mode 100644 index 000000000..4dff7af99 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle.properties @@ -0,0 +1 @@ +changePassword=Change password \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_de.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_de.properties new file mode 100644 index 000000000..3769714f2 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_de.properties @@ -0,0 +1 @@ +changePassword=Passwort ändern \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_fr.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_fr.properties new file mode 100644 index 000000000..158d6faa0 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_fr.properties @@ -0,0 +1 @@ +changePassword=Changer de mot de passe \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_ru.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_ru.properties new file mode 100644 index 000000000..11dd1007c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/OSGI-INF/l10n/bundle_ru.properties @@ -0,0 +1 @@ +changePassword=\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u043F\u0430\u0440\u043E\u043B\u044C diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/bnd.bnd b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/bnd.bnd new file mode 100644 index 000000000..f9e7f66df --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/bnd.bnd @@ -0,0 +1,14 @@ +Bundle-SymbolicName: org.argeo.cms.ui.workbench.rap;singleton:=true +Bundle-Activator: org.argeo.cms.ui.workbench.rap.SecureRapActivator +Bundle-ActivationPolicy: lazy + +Require-Bundle: org.eclipse.rap.ui,org.eclipse.core.runtime + +Import-Package: org.argeo.cms,\ +org.argeo.cms.auth,\ +org.argeo.cms.ui.workbench,\ +org.argeo.cms.ui.workbench.commands,\ +org.argeo.eclipse.ui.specific,\ +org.argeo.eclipse.spring,\ +org.argeo.node,\ +* diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/afterLogout.html b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/afterLogout.html new file mode 100644 index 000000000..ae0901bff --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/afterLogout.html @@ -0,0 +1,18 @@ + + + +
+ + + + +
+ Login... +
+
+ + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/empty.html b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/empty.html new file mode 100644 index 000000000..94fe28ac8 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/empty.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/favicon.ico b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..213cdf73f443f7923187a156e3a6a4d9c9beb995 GIT binary patch literal 4286 zcmbW4drXye7{`yn#Q5sQT~#ADdOg9k?+IB;NbS67#F&z?OW zc6N6D*xufLYsZcqw_00UFEuwepK5Aq+Sbs}kiBu^#ur8ZLn8N!+$S@GgFYMjB7s7;aP+wn<+S*#w)YQOcv+3Dxw?p`FyWN)>8ymODy-0yREJ8bmWW%vz z$3`AKdbHy3;lo$<@86G(jt=FLDeJ@9wQG@|pN|zQR;a98xl+Fu6&30IEnBw0>2zKb zJKvROCkg*Sk>Ph^hp>Z%?GZM*ySsJGTvtU!1y-+Kjm*qUBqb#wE-nu9=g&t>OpKo6 z!F7wA z7Ct22*tKgH>gwvSe*Jo6Wo04e^+lMvd@Cjtoxr%V(_Z-kFRVF)sTnm03X4{of`fzA zj(PLuAu%yg?WT^+n>T-3SXh`KP^l8Np)V(dJ5t0$w&Wak@7@iU%Y_XaHXvhp0cI3- zW26grlqtpUAtW|c{X-vxhlgvN7!z-9d?Y@cDSY~YvCu=<6(TrtdCv9&LXvXT7qo%-${dnB_*Lp9QPA`O`F5_IeCE6K5|mZdVobyJduAIp(Egdr z>(m$Y0pq~B5Z|^5`U&BV66q!1h&yY|TKn~Y>``@pBB0_VQYv?&z|oDB&8M(%`}YGr zPg{cX-AGPO)?QIwUJmI`mrF`YCJQ%(Y_45;tk(J)cF%yi#%wx^(744~=Q%k!nxE`@ z^jX6$4-#6>o4z}y;Re!*wrDN!dFk7fOkq0=KKmT?OmhBau0z-}LnAPI_G}on#k!Q5 zLRD3j_FkC~GQ0(c0_i3w}>aOS`S_rnx^?8|aH=ZD%yM8DsWV#@oxj>B}GQy6I=Pv3}q4 zM8_|P&Z!1_KKbm)oCEC7%yIVJbrm*Poflzi+M_ki+G38A?d6l*$A71DVBh<)eLqjD zIg16E1z;SaqN3Ce)*0uMksH!?neW)SbEo>iXZ>XN`M;|3Bh$4{$#x@Pb-VO~8>aVZ z&#bqOAuc&xeGwKG)>rR~7A-<*QchsgMxx|JzNWGEzjPC zVE1LyXKBaS+AEkApNr|!rz0RBKz+hJ17{icPRw&JpX?N}DZJ(zTjO)!yd<6N%y-TZ z+Q79eb@t#T*B_?us6WTwIKj@@mA{j$^EI;M`#D(Er>gwzakC-a=TtWcQyxIUQ&H_~Y$Y5f-yheLx%7 zf0*y==d5{3Yv*&Z~%zc%toh+-uz5nF9?muWlZs&J?e6C}3 z{dEN8y0rIlp3?^IwI(lf4ak1keh%CVb1pFM-rBG5W%ILeb^k>^^B}qXqNxo=PEM*k zgBLb^1d*Jup!-kSz&M1p{4${K{w%ZaS&bj)oaMT` z?9-w<*o=jU7YzW-?5tMyq9aDi+wUhggv`Qgmd$zSNNIN zc#qF$U%ML)N-cq~Sf2S;exKfy->1LJ@8n*2vBxW=a;6ORC>1@F9??nZ75$?7F=3EJ JCeSk+{{dc%*&6@= literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/login.html b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/login.html new file mode 100644 index 000000000..6de7eb216 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/login.html @@ -0,0 +1,18 @@ + + + +
+ + + + +
+ Login... +
+
+ + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/public.html b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/public.html new file mode 100644 index 000000000..e50f6e943 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/branding/public.html @@ -0,0 +1,18 @@ + + + +
+ + + + +
+ Refresh... +
+
+ + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/build.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/build.properties new file mode 100644 index 000000000..ae37429d8 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/build.properties @@ -0,0 +1,2 @@ +source.. = src/ +bin.includes = OSGI-INF/ diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/active.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/active.gif new file mode 100644 index 0000000000000000000000000000000000000000..7d24707ee82f54aa9fb10d1d9050013cbf161a7a GIT binary patch literal 193 zcmV;y06zamNk%w1VGsZi0K@VRxXubL!4|)qjO}gg>klxZ?TGXw~#-V zU_Y2&N}FX?r*L1YbYiM-aj|xBv2}#Mgo3?-guaA=wSS1Yfrz+)iMWB7#*ml2h^x<; ztIwFU(w+bR{{R30A^8LW0015UEC2ui01yBW000F(peK%GX`X1Rt}L1aL$Vf5mpMgx vG+WO#2NYmJDM}^)l;8n@L?90V%CN9pFcyU&MPO(u48jTlL$uClRtNw)MiWcq literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/add.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/add.gif new file mode 100644 index 0000000000000000000000000000000000000000..252d7ebcb8c74d6e5de66ef0eb8856622a0e9d89 GIT binary patch literal 318 zcmZ?wbhEHb6krfwxXQp_S{7na6>d=(Ze15;Qy1mX8t2lT^ zHOHgY9FJamJZkN+sI|wVk6ueSb}ixP)r4bLfn?%^+sU^crQUj&`rv8W|Ns9PC;*B- zSr{1@v>9|jW`O*}z!rUAYJrE2RKG`JYNRKhwpQrnor{(Ph`sVEnyR2Kc;c~(o$WdP zMb0Wl6K^dQ-0hgs;k}oL|=^|Nm0SzrXK)y_|Qr)9ml(^YbdjmNrRk zE>Qb_f9jiy-T!ZOY@Mh)vqbp+>n)or4gNe|{QGY6|6A?fl zjZ!=6j2<7X-BD|Fb5r5B`_ukkEd770^Z)D3|DP`T59EG5^Z(Z?ku4)and9)6>(=d)mgLW n@W?m|DJ@#Om`_y7SyOTKnl&senl74~w`|?$w_~TLBZD;nnW}>Q literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addPrivileges.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addPrivileges.gif new file mode 100644 index 0000000000000000000000000000000000000000..a6b251fc8553fe59749bc1a6baa172ae3d9e2723 GIT binary patch literal 564 zcmZ?wbhEHb6krfwc*el6<-kp^tmVFWt9&x&CDd(8Yuetu_-sJgrktMr1^ov~CLOAn zcC=~EiMIKt{L426Rc;Qg+8kc9HL`A7Y~zlM&OMdWk4#;C`rflom+!s3@#uZmiZfU4 zzrFh4?c5#LcAUPm+k2& zU!HCI`+o1=4~PDKI{x?5$-ke^ZJVU>^;XB9hy8z^%=+_e-k)dl|2$i;v0HIVzw*I( z7Rx#15+*@oPB6j z@yTtS*G_M`d124zw-5h=0mEPdia%Kx85jZ>bU=;*#R&uZ#D;(-IW|_grjE`IUR6<+ zt_cA=@}kTWCvY=O@8VLIoi;mwQ$tBsjBz1{hOCs7jJK7Q=L8XjHIiO7ettF{UBW7I z;y#8>{{Fs(6NEG+-Cexh-MwAhy9AYGER78uw6)AEy95-aE%bD)ZFS5oy7<*3T=gBD iogGbGyV&^{-0V$iek@Qtd}3+3i;&tDF|8m425SKKG1WZ) literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addRepo.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addRepo.gif new file mode 100644 index 0000000000000000000000000000000000000000..26d81c06595326b8f29d12272587491bed580e75 GIT binary patch literal 964 zcmXYwacC1~7{;HA*Cy>!P0pUJGq4827_OjnHg= z(X%RD=)Ev zX*hvbD*&I244@@I*P#eV01g8G0GoLQq~z%&O0v_3Tn{Y5(I2ll0#pI!7&O$3!M=Nm z`>X>M#4yaDGiV>9y+VNLFzo)Vo!`|BXdEb4i(*-p?C*vN zhOG<+m$MW&k3+-z^_GCrTAF-6A_W+Gc$fn$yUa>DlQf1KV_z0ae@oI{E>FEEBqJr+ zkhtdRT)tr?BJZ_92X3E#COwz-*|WCb`(}at0@jHWg_-u+(0 zGz?ACm;i>gw+R{dcGJ#s6yF{~CEucx>(9Hbl`TJ-Z?*DR!GA@8k3pk-*#Csva}9zg z&=yam>MAz6biZp?rO;Zv`{j;DuJk#9wl1LZUNsKkl!4qqkvvXYiaqx{Vf| zyd69(Z8&>jf3ny!`(1V6Vp!k*p!3c#! literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addWorkspace.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/addWorkspace.png new file mode 100644 index 0000000000000000000000000000000000000000..bbee7755fe05ebe19b59c1ffc3f4a3d77fea3faf GIT binary patch literal 479 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQn*IARMP3W4?(K)-RbzW7& zqJpYr*YA9cD_ECax+=S3c)_Uqr@_kX{fzjSWj-_Pf_PE_7HNqN_FwLi}n&#M$$ z)+n{CNor}6)VePD-*=m5mI$9cx&Qm))8C$6et7-r+^&xQ|NjHsMG`PgsmTCpFenM~ z3kGT@1u!Hny-)$v%b4Wt?qYA3Y)}g1a29w(76WMyFm^kcZ3kr3c)B=-NL)@m?IXaVr4z7rm+ngS`uUp37@8NaR)tj%&yyM<`F`8%5|Ke}1Jd+N4N~Fx5Y`8*f nd6I$8xdRJw{@R!S5cAdfBv)~H#f3vacQAOm`njxgN@xNAdhX?w literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/binary.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/binary.png new file mode 100644 index 0000000000000000000000000000000000000000..fdf4f82bec2de73e8e635d5b51c798c6db6cccd5 GIT binary patch literal 523 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQn*Dv4x{P_9j#JRg)zyJC2 z?f3faC(~P7Be`d^>IBVvFxwCs0%e`Jf>Nl-uSi7|8_}0Rs zn~RQaDL%BRbl>{&U2Cfzoan!@DdWnf%v*bFu5QZw|NlSG6Q>F<+y_$jB|(0{KoJT6 zL!VlWIM67@ByV>Yd%I+VQXq%3z$3C4NPB>>+sSM@AY-Pdi(`ny<=C^=g_;ZmS|18X zciFlHGAB7~G#8P6_E-LN3a8}p|Igmkn0FtE_vl!1!a@1{+>9NO)81Qf+y9O!_IRDQ z|Msf0^KNRh-te_}-Z9;K&V9yj+pML&S-nlWTE`&6zKr=mWu6sd%pNXPxrGsHn|xgi zdkv0eiRR3-nZdFwQTCMb6oIS=)|N>QO;M~Lw`9m1p8nL|sfO|F7S;LN^}~Q}WMJ@g L^>bP0l+XkKDjg<6 literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/browser.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/browser.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c7320c69eddd9a250ffaf7734c36617cb24ce8f GIT binary patch literal 582 zcmZ?wbhEHb6krfwc*elc+%@IbpZ^(sdvYf3%b&bIsD49O)8??|%~7peqg%JecWjUE z+@9RCGo@!|M*p7dNqh6B?Dwr*?_0Ajuwmonr(e!I`n>wm+wC{rAHMhT*Wdpw2cAth z_F~?dS3m#$zxw(A%b)*0{Qm#%@1uWzAOHEW_|K0ezrQZ|`|HBL-&YT9u{yCc?B}bJ zpRdY)zN-BBs`}@v`afTff4*-2>4y8K8y=r-czu7IG;><>%xNv3ui1RM;q&W3VtuL8 z;pN)LR+;{~8`WCjuy9uGfjP2=7pWXxtbTf>{`=DoeKmHg7nDBRCi&~6-i#*eryC_d z?o#`>Oa0d|?KM57i`y+8Z?WCfZ}R=guGjaEY_I1&)Ter|SM6~d=f+yA7dMVPtz`fI z|33pAf#OdVMh1px1|5){pg3V*U)&Jg)ZEhA)~xAh?c|`@-lXAcsjOqKuOEcXJxdMw2YXzgs2FMlJ>OFCLvaKPHtX4eilVt zWA9_pfpT(gH*N$f>RDWA@{^NylYcJnr)J<47188xYQ|vy)!tv-#3jPH$x}{&p+SN} l$x}=xVgZlVBSnS=J^^D9%O}q5N4u?RY;K*{n5@8H4FJ8>>N5ZU literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/bundles.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/bundles.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9a6bd966a5392e7755776c0c69d9385e2298f69 GIT binary patch literal 344 zcmZ?wbhEHb6krfwxXQqATF>%kT-v?-@+VE5wmHkVTv{Z9CaA~F67cSj3!gY^$Cc!j z?G@W+s5JN+bVhUKn2QwHM9hwjm>rX~I;&tw`sx;`<&9Fy8>Hryh|MVxn~^IrIYVSd zuIRr@wUg6@|LqU{|NlP&ErH@s7DfgJ1qL0EB_KaBu$4MYDDcqXVm$F=!ovcCwuZ(M z1_2`}5wFLbOdR`~v{o2udP^N|uu`aVxi|5+pp2NF+|A>UX1MT)3sku^x3o5Mak+_# zy0Njjip$E1xo~lCbUI1O&ykmK=3r;%aGpJPz5*8~3k&B=1(``w&a7LvxyVVkwK_6b F0|3)}RLKAU literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/close-all.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/close-all.png new file mode 100644 index 0000000000000000000000000000000000000000..85d4d429befdca9fc9d14b233f469d8d36f4d83d GIT binary patch literal 538 zcmV+#0_FXQP)i*b(^5~A7d;9p_WMyUB4%0kq)@+a^3?Dy!WZ1WF z{|n{=`}h3-8nW``%aLiHUQBg$Bbl!@#d!zcw%;`4QyY z{rdWP2G5^8WjJ{75L}_WygbZ%$icE;#foK#jA#Lc(-1TO)(m1WBa1@4a}(&D1RY%+ z27Z1%bX!q0gQF2kRILXF7=x;c3d4g353$*f62*+@@r)kYIKTxUb_BZQ10yk-L4l~C zAdem+7mNpc?|h`T2Q;j7agXP*+<8&S8v-rkP#C*lC&X!LwxVz&)al#c-qnqcDm}#WIy(BLW0V%N5`2M zYBi)fD)t0U*`nI(nzTRThYA-TS95cdU1Kv3A5Uwk5NlIM^h7?h?zV>Mb~Eg!3Nly& E026Ie7ytkO literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/dumpNode.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/dumpNode.gif new file mode 100644 index 0000000000000000000000000000000000000000..14eb1be09569a9c7d7dbbbf035622ba4ddecf874 GIT binary patch literal 564 zcmZ?wbhEHb6krfwc*el+!>_lWetrJ-yMN}2`!9byeD&kO%kPg~ z|9JA|$MbhTUVQ+n|MmUnp9!;;-v^0*fBWg@*B^gAfBW_D_4g-le|-A(Thk*uyK&}} zIZNAStp57r_xGQ_r_Nn6W8R`!3l_{O}Tjt3|DuWZV=vMKY{-kPhMGXMYo&oHEb;!hSv1_oCK9gwR* zal*hpvB9;exuvzmzN53Ft;vSHe}a>JkL`pB&MuQ%tr+I&F~~bOJKD8c=;~@}F=}b5 zuvxcSimK{pYG~?+iki2Y^6|;-)Ra4D)@m$rYMYMoDU()1*~^E8FB`S$3khwL*?HTb zRY96}mB3ncY3){S9v%rPK_v+_39(jw#b1(=;=fs2MFb=kC^Ry$FmZAu94QD;V6X-N Du-DPt literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/exit.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/exit.png new file mode 100644 index 0000000000000000000000000000000000000000..cfbf9d15eefae33fd12b8312e11bab985a5a02ba GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Wq?nJ>;M1%U-$=oD6jglY~_t< zGhgUiy)burVej?AJ?Mpk(TDV+g96GYHLNbi7oGHXIvMWuW8KP=_EtO1t*Q^7{{}RK zu_VYZn8D%MjWi&~+tbA{q~g}x^Oiyf6nLBin@%#N8Q%H7L1a@<`lnO&St5t@GXtDn zxXpdY@X_Ec<7~MnY;B_c9XzVeksM!RLs+(Q`$!(C%r3zvl!E{&^PlisvBy=hZM)24#1 z9pw}ERe;dm+Gz(r{{H{r&;OtQ{(t!Q|KtDv-~Rvq{{R1v|Nnpf|Nra%|KI=r|M~y_ z-~a!`S@y+Q4#n9HCE1Rpxvu3o4n>&`#aWIO`R*0@-c7}JwfXjydCp}yuI;7P)2fXp zRG4;`S*&W)UD#kSyUuV%wZWWvqeU&IE7~m{9cy0KrnROYC}Z5GBYybE5lN#yT~U6Xo$Ra(3=+D1dScga+z`_1)0SMcgq@9vNlLp4}NkYYq1|o9u5f+1+4#yxaU}r`gdi^F!@s8_V^#R2r-=)!$xYw6WY^bAj4_ zFkpZI#h)yU3=A?1Iv@d%oeZoI3hI3+ne)<@xV>1B`(fEuK?V+&Lu+13upU?-aN>~% z+leJYmV$v?7gmUP30m^pSR?jZz)|4A1_>U)M7|eWr0xntihbB2lP8!e@?(!&ykzXZ OhQ@l`mR1!-25SJE4`R#! literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/getSize.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/getSize.gif new file mode 100644 index 0000000000000000000000000000000000000000..b05bf3e3dd02120798859e837bd3b390f66aa343 GIT binary patch literal 587 zcmZ?wbhEHb6krfwc*ekRv-bA&{#(adPVdV-dTj3L#YtdRX+5WUX2w z(-vFTULXH?VId1*4qQE?UvFyH@8UAS)2iGqbV>BKOFPVatj)@-JZAVj>|g(<^`-hy>{)Xwc9Uj|N7(Wj!WBP=SGC|`$tU*DOsCSxGdeP!#ZbieEyPz zoW+r+?;I^!7MHr%qisuG`u+7xmOcf&*{y(8b4!y?z($L>+Y2O z{{QXgzYqWZ|2W`baU#Ow!-S3-83`Q{5+52G{=Rwh9}E~M28usf7#SEc8FWA~_PQF%CtBoHOzbku^^EnU#9I9&tz7M` zEgUq{QeLMuJ4&i+8<;8jr>6f%ZSj|vlCgMojZ@|FxqumlsmC;YB%TG%FycS$(DEX{ WN5W7--^?UMt><`u;u#hu25SKL^x~cX literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/home.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/home.gif new file mode 100644 index 0000000000000000000000000000000000000000..fd0c66950972e9fd6b4eee2a45293db7b0402a95 GIT binary patch literal 583 zcmZ?wbhEHb6krfwc*ek>=hf;IH{B?(Il6LneC_)9y7e)Ys}kzgCpT_NZrqsBx;3M1 zYfjfr^Oy#Un1=ILZ(q4_=gaqB7ao7P|N7gr_usES|9bEBw__J?ox6Jb!jmu8UwnP~ z{`vgb@~XsXFsG`()# z)P`jC{<4g|#s1N)K&pC%tK(wV?&6UV6I0Yt5EGW+>Ef1>5|vq# o@xi~D$(7S6WrD(k7KT$!PO1slaf?Yx}nH z1q*BE`DeYVcQRbO^a_X31KTqK5eiK?rGLJ(cPCtl`>k}Gfj5HHCvxLYme_`MZLG7U zOn?68yTFjVUHPbqVrdd~dTrF+$K=9`u-cBon6*RrB@+1`k*RVfqK zWKLN-Y3qThI}T3WabVi6gUikwU4G`sw)-cx-8;Vh-iht^j~{$}>etJ8|G%F3c7NLc zkB9!h-u(aj!~Z{@zq#1`|LKzdUvK}v)%hPN_2K;g4;TJ_y88c8$^VO`j}O-Ve|zHQ zroy9LW}B-F4z-)^Z#LQ8V7$H7=yQ)xE;9@A0!;d-r7D-u^zZTq8C!Eum$( oGn1lA$3G!YEyl(MRmC^VDelI0bKcdR0Xmhz)78&qol`;+01Q4Zvj6}9 literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/installed.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/installed.gif new file mode 100644 index 0000000000000000000000000000000000000000..298871653f056a8123af853bd587a3a394a208f0 GIT binary patch literal 183 zcmZ?wbhEHb6krfwIKsg2JR$LfrojmVlM|YTCuDU#`Nn+ojrm&Ea6(e+`Q+}C&Ne6A z?M~WReVf$xJR#w0P0icp=KufyGY}0Ff3h$#FbFc}fOLTDWMDN(Q0Ys_oR_g`UCwH~ wf;~&Tl5cyRGV#A}pn33MfPoClO2#9M3=T}1PDxg(O9XD{96I`To)d#L0F!by`Tzg` literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/main.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/main.gif new file mode 100644 index 0000000000000000000000000000000000000000..90a00147bcb02b6855aa21c532a1ccfa992db5c7 GIT binary patch literal 310 zcmZ?wbhEHb6krfwxXQqw=RZ|1V5&*zbjzr@wlTAuk{7w9FY(G+?v^sgH*b|s=DdWu zZD~#0yBD7gDBG0Nv%jGKK*^*-71NG3%{kFF|CE3E#-Pg0p;ep1Yqmz#ZHsN(kz1OCBW9Gn(60SWa+}gzo||X6OdpAC pniZ}UB2{8+qLvgXp{K+VYbvgzz|tvZD96;vC(6Ls8R^Ji4FH!Gg(Uz0 literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/node.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/node.gif new file mode 100644 index 0000000000000000000000000000000000000000..364c0e70b1d6dc48f9d9abfceafbb4f63e5e1edb GIT binary patch literal 586 zcmZ?wbhEHb6krfwc*el6W%tD&KmUCB_Pefs%iNVm(`#3L`uh9Zk3TTdfM8Hb2nXEy7Tt)cRyde`|-ygpG`u5}Z!`D9^y!!t5&5tK+PqXU%vnDpS5D*?Bx$%1I52TfB*C4 zho3Lr|9Jo9*Qam4r_5RU^xco=?|;1d`19kp-=Dty`uOeF_g{Zz%wJ?aBVon4?KL}U z=PjDIXzA<~E2ghqJ!Rv%iCZ`H?cLhBb5qa$Z5{vr|7RG2K=CIFBLjmogAT~;pg3V* zU*6#C?9|fQ*3#7Ez|qs&=g{fw$YEh_(bwZR(Vo%V(wvc%nT5gBexjZ1R0~=5wQKDr z+A^tZW!kbu#de~N$!c9=Ha2M^n~Byk^UQS?E#bAEXeGK@^s17wsMSO>DMP8dckgML zP1Ms|ZJ^B~EF!5lQC0tx{#gcn)rnjRs}(d96cimaI$9DN+l4u7Z3-qFXzuiIHmI5L XgV9NeM?!&bXM&>>OK%esBZD;nX%XK6 literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/nodes.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/nodes.gif new file mode 100644 index 0000000000000000000000000000000000000000..bba3dbc69e5fe573644be01ece5ea0f5c374851e GIT binary patch literal 166 zcmZ?wbhEHb6krfw*v!Ci_x8uyj^#5pT$nR=`rO&=+gDbd-ductfBAnfV88&1KUo+V z7&sYpKr$dR7+8W0PI~s5n)o+QxEk5W;U3r^q*Rtwl$hzz!{oH%Zad4#14_*;9Vw5# zvUx1|Q0}Cf)^y9~)2ts6%?wP>8&xNBzTI$zg*9xh5rrn?;V;j*FfdpH04k_I ALI3~& literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/osgi_explorer.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/osgi_explorer.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9a6bd966a5392e7755776c0c69d9385e2298f69 GIT binary patch literal 344 zcmZ?wbhEHb6krfwxXQqATF>%kT-v?-@+VE5wmHkVTv{Z9CaA~F67cSj3!gY^$Cc!j z?G@W+s5JN+bVhUKn2QwHM9hwjm>rX~I;&tw`sx;`<&9Fy8>Hryh|MVxn~^IrIYVSd zuIRr@wUg6@|LqU{|NlP&ErH@s7DfgJ1qL0EB_KaBu$4MYDDcqXVm$F=!ovcCwuZ(M z1_2`}5wFLbOdR`~v{o2udP^N|uu`aVxi|5+pp2NF+|A>UX1MT)3sku^x3o5Mak+_# zy0Njjip$E1xo~lCbUI1O&ykmK=3r;%aGpJPz5*8~3k&B=1(``w&a7LvxyVVkwK_6b F0|3)}RLKAU literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/password.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/password.gif new file mode 100644 index 0000000000000000000000000000000000000000..a6b251fc8553fe59749bc1a6baa172ae3d9e2723 GIT binary patch literal 564 zcmZ?wbhEHb6krfwc*el6<-kp^tmVFWt9&x&CDd(8Yuetu_-sJgrktMr1^ov~CLOAn zcC=~EiMIKt{L426Rc;Qg+8kc9HL`A7Y~zlM&OMdWk4#;C`rflom+!s3@#uZmiZfU4 zzrFh4?c5#LcAUPm+k2& zU!HCI`+o1=4~PDKI{x?5$-ke^ZJVU>^;XB9hy8z^%=+_e-k)dl|2$i;v0HIVzw*I( z7Rx#15+*@oPB6j z@yTtS*G_M`d124zw-5h=0mEPdia%Kx85jZ>bU=;*#R&uZ#D;(-IW|_grjE`IUR6<+ zt_cA=@}kTWCvY=O@8VLIoi;mwQ$tBsjBz1{hOCs7jJK7Q=L8XjHIiO7ettF{UBW7I z;y#8>{{Fs(6NEG+-Cexh-MwAhy9AYGER78uw6)AEy95-aE%bD)ZFS5oy7<*3T=gBD iogGbGyV&^{-0V$iek@Qtd}3+3i;&tDF|8m425SKKG1WZ) literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/person-logged-in.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/person-logged-in.png new file mode 100644 index 0000000000000000000000000000000000000000..87acc143578dd58ab75d0f3de6b315d4232eb582 GIT binary patch literal 359 zcmV-t0hs=YP)k{qZ~=$|fd)N*8vxaO9*6~yRjLRuf$2LR{-GQ40f-Gj zhOj^d)}w3AF<@f|QG-aYx%G!(%7tIZ(gILDhKx`@&qtP(;AUi4;mwI+rO*2B3}1f# zM|Vjg6EwgWPz_+h@VJT~6SnY(XTlQN40qmR_!+AhNH11nK~7z8^*5XkVqDRmhCfxme^DGC|Y! z1!DY*o}@u~aVBL@GUj1pL<-1%$cDp{GIcT&CD|DuzyKqYWqdoBV*>yH002ovPDHLk FV1nI1hQ9y+ literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/preferences.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/preferences.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0dc0be98db6b2fb711b970e1e606c625d94b3d GIT binary patch literal 603 zcmV-h0;K(kP)S_CM`$0H`p`dRU zJj?(B2yDQgf6PEvFfepi1cK>rzyB~yDRL(m9@%|682|zZV!&UZ3xGN+y4Evvlm#+; z{P73qs{agyt?L;2fi9Z3^eDsc-;nV5@dFq(K-^XC&+r+j4j_O~T+mhualw0_0%j&g zhDo)-V4I5KY_PiE-H%@k009II17=`M{AZ}`-N4XX9Ki7Y`!Awg@c#R627my9djVu~ zLty}z{`B)VPz(|#fBpge8flGWFC=Du|NY1C5g5$?0R;B~C=8k=Ze*y-_h7C-OH0d~z8Wfl&_08jNVF5J_TsQ#M1}#5r&U00D%Q5*ZoVCv9Y? z%=KqjzUc(klvtVT$H2|Yi()oF03o6gXmxpxADE8tHD~ybY&qC=MsPrL^75k?01!aX p%*4cSXvNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`)E9 z;1lAyW#gtdPu@Iv@+POWXX=9OS>O>_%)r2R z1cVu&+uB-9mxU-|IVbz4>o(p8sw8hP~s2 zbhgd@D2EVBmlDxHpUNtR%68Yl1)mE!9vU-B?vb*QyTJ4CPO0RHqQfWSE_A*3tW(%@ zk>#85D;}N7SH64mG%sG=9K{s%qtDzy$a}))O}CkQJars%X7dQGnZBtrO=7!)uWyv^ nh1IveWIvG9FWnz`{ohq_0ZqyD{@ok4g96ag)z4*}Q$iB}>U+SI literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/refresh.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..a3884fb4888c2a68f0fa64d523e69da2f0569ab2 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQn*B?J#{QLX<$A=BSKWzE= zV#<#fGk(9E_w#PmhZ_waZ#DmT(DC8HijS9zf8T38JWck{Oobm85`NsM_;I7*=h^tZ zEn*uhgm*WJ?rId>RwJ^l7Kngsu@!j&Yl{R|<_WII6I@#)w6<7iO_9)=VxeW(0{{R2 z2iioM&sl5KBX4_u+Q8p}12WsEYxhqZ46z5UO4 xC{IX5qW?tG!t@NQxhzk8CmDO_&kQNvl+j$RV9uyFP1Eu=fc2X4FC}0Hs=5U literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/remote_disconnected.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/remote_disconnected.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c54da9ad04e75a4d661cde11103d636f93d003d GIT binary patch literal 155 zcmZ?wbhEHb6krfw*v!E2|NsBjuU{`)wrug@#S0fMoHuXYtXZ?BPoLh`*Vo?O-q6rc zTwI)ykpWc300xRbSr{1@co}p+Jdha-EFK$9dakw&zEL&p%2fxEV~JG{)JlUE`OP?D z!tp7LBO$spo_UuSlZOsdj7V$IN)8qgb5G%_nP;YGg)w^yPV`w5a_zD}ep0G83xhQP D%T+uT literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/remove.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/remove.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ae6decd03fb76703952b2cc8eaf9e41ed577933 GIT binary patch literal 351 zcmZ?wbhEHb6krfwxXQqA+}QL>Vab=`lFvmYpNmUxXz4%DF}bf}d|cDunVH>FGrOY- z+D{EEKZPcINzVS9ob?$uHn=&y~n$8D`1 z2l;<(sQc1T_xQ+>|Ns9p5DgT6vM@3*7&7R9bb$QCz*ci$MuCTpRKMGd^bncK1eb^v zqDfrti^MpzbSB1VUt0b}aql73M;xvKD|}WtK1fk5iV!?;_@hVR1O_f%UNKGv4?_+f zX(=fl4i6boi78XK>s@7pr?3jKN=S;#aFP{YATA>-vrJN4*4aRuZH4n{cJUaejfg!)lQ^<$D6M-{Y>Dd-&6G`OLqe_zM=xUuO29h0X9 zmd9;@$m*$?T}8C;Gc&sr?)E3$?M}Mef3OeyXdmR0InOI=`N;rh-@H{HJt97NM4SqD zI~n12D#Gn?kbgkgCjat{r(!*WDmRB#ZT=LJ@F_GQyk=`;-L?mb(Xov?uB4VMuah~K z7xy_i>vMAUm*nivDcP%=tZS3c>Dj-m(_&+{VnP3bFNGzai%LEhmwqWO+0w6E zGU-sow4;^Nk6i7j`O;AL6^I&Zcg%EYnscIU{;BT8XS-IMnY#M){W&X+Zm7MpY{A?e z*G_Khys%p@Zf1b_z@@(6mXY>C&Tkzn;%LgxCKY9D=>AP2d-|zkV;n3et z$Nzph`SIt% z7__IY`QXlYV3NJYfe^+83<{Igb=Z^`4!k%rQ=dEBL-F%6pZ><4e-i{AKXsEfGwWJo wSj>EJzF_383kAtf4>D^fXY61RRO;f(^b literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/rename.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/rename.gif new file mode 100644 index 0000000000000000000000000000000000000000..8048405a782b4e283a28717437d42d49d0d183d8 GIT binary patch literal 889 zcmYL|Pe>GT6vsca&bnKuZKIPbL|ArM7C{jY+h$vV|57l6u#PKKMyw&!VWq{!(ZWN> zE_vu6>2V1U3wbld)O9;_kT4MIP$%iK6ohNB`0MwZHT)gkyx*HQ-}imr_onMwXXwJ9 z4<7~4UHb1g`s@RJ^7-U!i(cHBc{iqSecGCI>BWPXUal8k$J#sF+rn+dgT>;*^TmTA zY#w)gul@^-FiJVRg}zOtOB53DivQ92nbD)gTP2@&cR5ky!>ba7jVtPqCu<*f+zf5|kC#pP&%Lu+@nC`18yqu@b7Ta3d8_`Unic zoWN2VQtQ?ZC)%@HyBEZ=6@3;~$bL2rXYQ+lpum>tA`M5n`4=_08zmOY(?qthdu82Q zVrEZlSi(pMUS*zSH+~vMpX#OXVJNa;I!)gDy3F4QeTry0(_3fc%agV9os%#-CA96UclUT*X(_7?1vn;yG4c5x4lB(=}If;K#{3 mJ!OrRJ+n*XWP{ literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repositories.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repositories.gif new file mode 100644 index 0000000000000000000000000000000000000000..c13bea1ca4123cee4276db0a468963bf2ca6fa94 GIT binary patch literal 588 zcmZ?wbhEHb6krfwc*el+`SaKR|EpfTI{fnG=|4Y~{Qb56-=9lAUseA8u<*~f|e{QkZp@nt_=Q$jntgwHs z^S;@xzusLuG*M|^zw(nU&hPg}?w;YXW19D?Gd<7G&w6-v-i{6PkF@g~YT?<}t+u06 z^TSrV2kSkyPxgB@op)a&-~LAaZ!2WCwQAp5>9=J<;LnHK9`p7<5360>udf`^tuZ06y_nalWR`t`=c7 zPX6|;E(v9M9b;E*RT0U#k|Iq~$_@<7Tq|8P%c2}fQEvenVYws`UykL0Nn!y3Z^oQ+>ZL!wE|2ISloN?$o#rdvz?#i z>xYh3*R7lQ)SSLPa$ff_z~xE2fYOO64PGTj6eh|0im9zS@FdzoO;km5)rTdIC-+D> KxACwrSOWlhFVLI- literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repository_connected.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repository_connected.gif new file mode 100644 index 0000000000000000000000000000000000000000..a15fa55380a15b034026ae13e7f62dc231ab2433 GIT binary patch literal 328 zcmZ?wbhEHb6krfwxXQrr`)kkNUweOjEIPEs>i36ff4;2w^JVS#M-eA>hW&h5`tw!e z&sR;~A18gim-zX*)0gXBzaM4)eo}gPx%RPDrhjhv{JHJ-^=86>IkK-0svcgXa(J=& z>6QBLPdj`&Y4Q4)|K3R=uXn0EU9b0ei|xmwA-gAA?4Dw|Ym(*mdhSDgst0@3-p=EB zyhMLvt<{TmrT_o`Gms7xf3h$#Fz7MpfV6`A#K4y7FulM-M@&$%^VugyiB@JWm4pZr ztLEoRm=;D^FHh$zVNj8g2z`~gNnp?QtrMT{iHL+>nf!0x^Y5i~vQ@>670nH`?Jce~ mW!?Td+WbsBGK#u7{>nO2rYY)3`|HW+EL*0uc$JGIgEasv#fKRH literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repository_disconnected.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/repository_disconnected.gif new file mode 100644 index 0000000000000000000000000000000000000000..4576dc5635fc40f20c0ad41d96b081e891bf8633 GIT binary patch literal 209 zcmZ?wbhEHb6krfwIKsg2?%lK7w@y8Jc;(6C8&@tJeD(6dwJS$%-#mTq&iQ+HF5J3) z;_9Wt=T7Z7eSF*H^ZU-9-gW2ZnZx^5pEczu{_pUy?XYIbNix2N!yLs)>gIiY~ zI(YE^|Njg~K=CIFBLjmpgAPaxWG4fw-vhP2l*p`%RWlbob8wibb17?=m(BGxZh}qB z%1ImNsxix+^|+*v+>!b|vg1=;h<5Q4pRlD7>&vv*=Iix0EDSuE6FuY0uBOWEAsW-} Ji7+u(0{~PHYlr{< literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/resolved.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/resolved.gif new file mode 100644 index 0000000000000000000000000000000000000000..f4a1ea1507068ad913d6151b496e2b303bec9dfe GIT binary patch literal 176 zcmZ?wbhEHb6krfwIKsdX(zwmBe0@;cuHd#^aw&_I)0bG5Z?LS`AP_T0C~mH3{5-LQ z`I5;CWKtH%q%M+4StygbP%d?`QpQrX?B(h?%m4rX&wv*w{$ycfU=U@{0jUDn$-t_c zpxT#`IWJ??x}4KN!Oi?Ij z|6i&;6Au`2SMm{|nLoFGc^qHva#{rX3NNcrT2`U9tP+T{mbW;~PU2b89KNbM zVRd)nhDjM4CS`7!p4XFVHX+M;LYB?6Lg%T4&eIBA=2rU7sq|ga6dqz>@c;jRhQSRK zf3h$#FnBTOfSd`669)DP4PH&nO`>e9qAgv`JmS18-QC=xyv!53xtOMRaY_hJo9)FR zDJIOvIMIHUq@=KbAVaskoSclkh=>qBdzYQ8tcI+No$ZmMc1_mm2Il%|=hdXt)TPyI zygXFRJWaJU^$d-SEmc*myxf#^O>|V=>FHT$8@e|;D<~-{>AAQz{p)I~`SHNXL&MQQ MNG?W0Lx8~=0EiT{v;Y7A literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/save-all.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/save-all.png new file mode 100644 index 0000000000000000000000000000000000000000..b68a29b2cc3af872ba9f0e0d77b3d6989df66749 GIT binary patch literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X_IkQFhE&{23YivuZu$T#0AcwM5`9>j?*jS5h$#n9cML9B`k&w1Ahrp@dn^nQ6hjyA5Yq z4FdX)*fA`XXZYx>(AR#dImW87v!lR@gZD*yz;xS&uJ6nrYm#^-xEHlDo6Jd2Xl&(R z7MfskeX+NZVE_k*B!icHPs9f0yD<(o7!nR8wy4Q%Vo>J$_&=bE(d6Go*IXt$W~q)+ dMu!GQhM#-1R^(heG8^a-22WQ%mvv4FO#lh0W2OKA literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/save.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/save.png new file mode 100644 index 0000000000000000000000000000000000000000..f27ef2d26bad58ee0416704ffbd5dc1059750299 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XT0C7GLn>}1r6eR2G$bV*WKyVOcx=E_$SiPuvF0v@Bk~uH zur%CY(0a!a%FL#~{BLpMgzj(7hCCJuC-=8Y9Xrr;eC3Zlstl%g1m`pMvK(Sc@nFzn zo-jAA|GbDA8yDkM-i#JEUAsFLJN6o|@H+T=e00e1cj#x@#mMfl<%@#QZw7}3Muz*H W5@s=~eQ`kdFnGH9xvXK%dGPg|6>q#}6kYzm~%Vt`k^VCA;X@xFR z3ti?``p&8JUD6aDVqx(A|9=Lef#OdVMg|5$1|5(Nke?XX5)aHM@X(R!Ke41pQ^#_q zDwAVC&?GkI;|>l|rF&HpS0ug+k;q_cxX5APvhjKo^KA#YDcowGBXt}MbvcElgt*#8 nMC1g;^_(@?IM_Kvw6qO%rn{=MvWjT)BmCdH>AyS7xlgyky6X6}xX* z1EorLhcq0C?KoXG=T!URa~(_0bu2#Hx#aBBb(g2Ey|iTKjpe&||hddZ5;qk~uG9)wI6NUFSaUSS{>Za!ZN*?!N=wZiNd) sIZmi7WXNEWTGUu#wO7JG@>rJQ1{Id|3`>PLoK>C{{5opa%D`X^0EsGB(EtDd literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/service_referenced.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/service_referenced.gif new file mode 100644 index 0000000000000000000000000000000000000000..c24a95fba3116080010f8ed5a3764e4d90276584 GIT binary patch literal 185 zcmZ?wbhEHb6krfwIKsg2`OC-8Up_p#x#jEYV_PSwY@edKYr5L+`<=hpK-Tb}4S|Q`*q2II~1}O{@I>|Nj|?28usf7#SD@8FWB8Kz1^)nkA_8rDV>_Sha3N z;)c9QdlqLOZ_Bai@A%`uPF**XjMmUwGAU-6$GW(pMcgqb z(|2w9;dV}`sl!pnk4?!TK`?#5FDL$gHF5i7)qQg`cF$1XJyZSvvl;8!CMAi|&nQV6n>fz?Ps zwJ#-eUdF0*IbH&~j0_v1I4TmBoId!c=P<+44xhfs9!jheEmS+E9{!nODz$daHc=)9 FYXDFdK#l+a literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/user.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/user.gif new file mode 100644 index 0000000000000000000000000000000000000000..90a00147bcb02b6855aa21c532a1ccfa992db5c7 GIT binary patch literal 310 zcmZ?wbhEHb6krfwxXQqw=RZ|1V5&*zbjzr@wlTAuk{7w9FY(G+?v^sgH*b|s=DdWu zZD~#0yBD7gDBG0Nv%jGKK*^*-71NG3%{kFF|CE3E#-Pg0p;ep1Yqmz#ZHsN(kz1OCBW9Gn(60SWa+}gzo||X6OdpAC pniZ}UB2{8+qLvgXp{K+VYbvgzz|tvZD96;vC(6Ls8R^Ji4FH!Gg(Uz0 literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/users.gif b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/users.gif new file mode 100644 index 0000000000000000000000000000000000000000..2de7edd6467d1cda72bf3f3261a851ef5123c3d1 GIT binary patch literal 598 zcmZ?wbhEHb6krfwc*ek>-T+ljue_7{>xtp$SJo0$c(Z|!5 z?OV6+`s!Vm*6g~ta{IYW2d=N%b7{lg%j@@CTD$A~hP{^>rfi+|z>vY9 z12PO0Ck*VH8#0=jTUuKJg(6#hMZ;R{l7%y@_*^r@Qw&-og}YQ^cr$#(eOuy;wYXAU zd0kUw^gI)q9sF!#%@hO}%wj`>oSN<9ZDN(Zq@|c+gQFdr-4gv{mAuV0*kVJHBAP|? ztz%Vu%w2EFI%~H`2E_8HOQ|u%hMTk+M#ZMfSu&=5apzikqw&ERb{Up4DlZN!5}0Vn oe$M8?gaXEyQmrWw8HH*r)0xr|5*(5;1iCoXyjJN*axho}0DT+s*Z=?k literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/workspace_connected.png b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/icons/workspace_connected.png new file mode 100644 index 0000000000000000000000000000000000000000..0430baaf50765aa5c313b3da35d3d2ad5092f2d0 GIT binary patch literal 498 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQn*Qt#iQyV)wt9y$IC&#DE zO-PxS03=iACa2GgPn{bUKQAz5aZv0c*U%NNVJp0%mbOkjVd=ltGGL8;$SMuD&3c|2 z^u0Ffdu=fFTRUm%n@QW=OxpT-(ze%gkA9ka?9;rXpXMF=wDQ`|l~;ePy!K<`!@s{? z&ii(M+W(J-{=eS*=3@8%r%V3d>iiEBxmf!DYVG5LwKq2vURYCcac$*=HI@It0O(RY z;D%)CX`r-ONswPKL_LWl!@_<)L!b$aN#5=*_IAkzr9cj6fk$L9koEv$x0Bg+Kt`vh zi(`ny<AEIQcD@AqbASA9v%ZozqTFR<<1)U%4zb-%jBWwMK#pi#lx%#VY-?ue4er>q-cjMi^8}9$x`0(%F2S@%qzVLhd z>}6d|^V(Yf|NjqkFIEsNey9{EVNnv~7YtNJ4q&j35j+JngE7h5-NoK6*#Kl9XMsm# zF_88EW4Dvpc0fjxr;B5V#N}iIcV?a&tUiqlkq6G)xN)L|QSHEy6H6AaR8dtr!@=ak z^K4JjuQs+efd$8pa)+E)vzD9vjDm55sY%FI1&67uDhHM=TDORYG3$*2BVT2uYo*2m z7S0c+6dB|_90J0Ef~1&4Djb-Y9xZw#^vKBQk;5!$6@?@HECrQ(oD2+&b{Zbe>4Mxq P*D!dx`njxgN@xNA4VCJx literal 0 HcmV?d00001 diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/plugin.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/plugin.xml new file mode 100644 index 000000000..3dfbf2dc1 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/plugin.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/pom.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/pom.xml new file mode 100644 index 000000000..d756da075 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.argeo.slc.legacy.commons + argeo-commons-legacy + 2.1.85-SNAPSHOT + .. + + org.argeo.cms.ui.workbench.rap + CMS Workbench RAP + jar + + + org.argeo.slc.legacy.commons + org.argeo.cms.ui.workbench + 2.1.85-SNAPSHOT + + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + + + + org.argeo.tp + argeo-tp-rap-e3 + ${version.argeo-tp} + pom + provided + + + + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/AnonymousEntryPoint.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/AnonymousEntryPoint.java new file mode 100644 index 000000000..f657ec368 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/AnonymousEntryPoint.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.rap; + +import java.security.PrivilegedAction; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.node.NodeConstants; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.application.EntryPoint; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; + +/** + * RAP entry point which authenticates the subject as anonymous, for public + * unauthenticated access. + */ +public class AnonymousEntryPoint implements EntryPoint { + private final static Log log = LogFactory.getLog(AnonymousEntryPoint.class); + + /** + * How many seconds to wait before invalidating the session if the user has + * not yet logged in. + */ + private Integer sessionTimeout = 5 * 60; + + @Override + public int createUI() { + RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout); + + // if (log.isDebugEnabled()) + // log.debug("Anonymous THREAD=" + Thread.currentThread().getId() + // + ", sessionStore=" + RWT.getSessionStore().getId()); + + final Display display = PlatformUI.createDisplay(); + Subject subject = new Subject(); + + final LoginContext loginContext; + try { + loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, + subject); + loginContext.login(); + } catch (LoginException e1) { + throw new CmsException("Cannot initialize login context", e1); + } + + // identify after successful login + if (log.isDebugEnabled()) + log.debug("Authenticated " + subject); + final String username = subject.getPrincipals().iterator().next() + .getName(); + + // Logout callback when the display is disposed + display.disposeExec(new Runnable() { + public void run() { + log.debug("Display disposed"); + logout(loginContext, username); + } + }); + + // + // RUN THE WORKBENCH + // + Integer returnCode = null; + try { + returnCode = Subject.doAs(subject, new PrivilegedAction() { + public Integer run() { + RapWorkbenchAdvisor workbenchAdvisor = new RapWorkbenchAdvisor( + null); + int result = PlatformUI.createAndRunWorkbench(display, + workbenchAdvisor); + return new Integer(result); + } + }); + logout(loginContext, username); + if (log.isTraceEnabled()) + log.trace("Return code " + returnCode); + } finally { + display.dispose(); + } + return 1; + } + + private void logout(LoginContext loginContext, String username) { + try { + loginContext.logout(); + log.info("Logged out " + (username != null ? username : "") + + " (THREAD=" + Thread.currentThread().getId() + ")"); + } catch (LoginException e) { + log.error("Erorr when logging out", e); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapActionBarAdvisor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapActionBarAdvisor.java new file mode 100644 index 000000000..c18a9a78e --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapActionBarAdvisor.java @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.rap; + +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.workbench.commands.OpenHomePerspective; +import org.eclipse.core.commands.Category; +import org.eclipse.core.commands.Command; +import org.eclipse.jface.action.ICoolBarManager; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.commands.ICommandService; + +/** Eclipse rap specific action bar advisor */ +public class RapActionBarAdvisor extends ActionBarAdvisor { + private final static String ID_BASE = SecureRapActivator.ID; + // private final static Log log = LogFactory + // .getLog(SecureActionBarAdvisor.class); + + /** Null means anonymous */ + private String username = null; + + // private IAction logoutAction; + // private IWorkbenchAction openPerspectiveDialogAction; + // private IWorkbenchAction showViewMenuAction; + // private IWorkbenchAction preferences; + private IWorkbenchAction saveAction; + private IWorkbenchAction saveAllAction; + + // private IWorkbenchAction closeAllAction; + + public RapActionBarAdvisor(IActionBarConfigurer configurer, String username) { + super(configurer); + this.username = username; + } + + protected void makeActions(IWorkbenchWindow window) { + // preferences = ActionFactory.PREFERENCES.create(window); + // register(preferences); + // openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG + // .create(window); + // register(openPerspectiveDialogAction); + // showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window); + // register(showViewMenuAction); + // + // // logout + // logoutAction = ActionFactory.QUIT.create(window); + // // logoutAction = createLogoutAction(); + // register(logoutAction); + // + // Save semantics + saveAction = ActionFactory.SAVE.create(window); + register(saveAction); + saveAllAction = ActionFactory.SAVE_ALL.create(window); + register(saveAllAction); + // closeAllAction = ActionFactory.CLOSE_ALL.create(window); + // register(closeAllAction); + + } + + protected void fillMenuBar(IMenuManager menuBar) { + // MenuManager fileMenu = new MenuManager("&File", + // IWorkbenchActionConstants.M_FILE); + // MenuManager editMenu = new MenuManager("&Edit", + // IWorkbenchActionConstants.M_EDIT); + // MenuManager windowMenu = new MenuManager("&Window", + // IWorkbenchActionConstants.M_WINDOW); + // + // menuBar.add(fileMenu); + // menuBar.add(editMenu); + // menuBar.add(windowMenu); + // // Add a group marker indicating where action set menus will appear. + // menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + // + // // File + // fileMenu.add(saveAction); + // fileMenu.add(saveAllAction); + // fileMenu.add(closeAllAction); + // fileMenu.add(new + // GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + // fileMenu.add(new Separator()); + // fileMenu.add(logoutAction); + // + // // Edit + // editMenu.add(preferences); + // + // // Window + // windowMenu.add(openPerspectiveDialogAction); + // windowMenu.add(showViewMenuAction); + } + + @Override + protected void fillCoolBar(ICoolBarManager coolBar) { + // Add a command which label is the display name of the current + // logged-in user + if (username != null) { + ICommandService cmdService = (ICommandService) getActionBarConfigurer() + .getWindowConfigurer().getWorkbenchConfigurer() + .getWorkbench().getService(ICommandService.class); + Category userMenus = cmdService.getCategory(ID_BASE + ".userMenus"); + if (!userMenus.isDefined()) + userMenus.define("User Menus", "User related menus"); + Command userMenu = cmdService.getCommand(ID_BASE + + ".userMenuCommand"); + if (userMenu.isDefined()) + userMenu.undefine(); + userMenu.define(CurrentUser.getDisplayName(), "User menu actions", + userMenus); + // userMenu.define(username, "User menu actions", userMenus); + + userMenu.setHandler(new OpenHomePerspective()); + + // userToolbar.add(new UserMenuAction()); + // coolBar.add(userToolbar); + } else {// anonymous + IToolBarManager userToolbar = new ToolBarManager(SWT.FLAT + | SWT.RIGHT); + // userToolbar.add(logoutAction); + coolBar.add(userToolbar); + } + // IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT | + // SWT.RIGHT); + // saveToolbar.add(saveAction); + // saveToolbar.add(saveAllAction); + // coolBar.add(saveToolbar); + } + + // class UserMenuAction extends Action implements IWorkbenchAction { + // + // public UserMenuAction() { + // super(username, IAction.AS_DROP_DOWN_MENU); + // // setMenuCreator(new UserMenu()); + // } + // + // @Override + // public String getId() { + // return "org.argeo.cms.ui.workbench.rap.userMenu"; + // } + // + // @Override + // public void dispose() { + // } + // + // } + + // class UserMenu implements IMenuCreator { + // private Menu menu; + // + // public Menu getMenu(Control parent) { + // Menu menu = new Menu(parent); + // addActionToMenu(menu, logoutAction); + // return menu; + // } + // + // private void addActionToMenu(Menu menu, IAction action) { + // ActionContributionItem item = new ActionContributionItem(action); + // item.fill(menu, -1); + // } + // + // public void dispose() { + // if (menu != null) { + // menu.dispose(); + // } + // } + // + // public Menu getMenu(Menu parent) { + // // Not use + // return null; + // } + // + // } + + // protected IAction createLogoutAction() { + // Subject subject = Subject.getSubject(AccessController.getContext()); + // final String username = subject.getPrincipals().iterator().next() + // .getName(); + // + // IAction logoutAction = new Action() { + // public String getId() { + // return SecureRapActivator.ID + ".logoutAction"; + // } + // + // public String getText() { + // return "Logout " + username; + // } + // + // public void run() { + // // try { + // // Subject subject = SecureRapActivator.getLoginContext() + // // .getSubject(); + // // String subjectStr = subject.toString(); + // // subject.getPrincipals().clear(); + // // SecureRapActivator.getLoginContext().logout(); + // // log.info(subjectStr + " logged out"); + // // } catch (LoginException e) { + // // log.error("Error when logging out", e); + // // } + // // SecureEntryPoint.logout(username); + // // PlatformUI.getWorkbench().close(); + // // try { + // // RWT.getRequest().getSession().setMaxInactiveInterval(1); + // // } catch (Exception e) { + // // if (log.isTraceEnabled()) + // // log.trace("Error when invalidating session", e); + // // } + // } + // + // }; + // return logoutAction; + // } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWindowAdvisor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWindowAdvisor.java new file mode 100644 index 000000000..60bad090c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWindowAdvisor.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.rap; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** Eclipse RAP specific window advisor */ +public class RapWindowAdvisor extends WorkbenchWindowAdvisor { + + private String username; + + public RapWindowAdvisor(IWorkbenchWindowConfigurer configurer, + String username) { + super(configurer); + this.username = username; + } + + @Override + public ActionBarAdvisor createActionBarAdvisor( + IActionBarConfigurer configurer) { + return new RapActionBarAdvisor(configurer, username); + } + + public void preWindowOpen() { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + configurer.setShowCoolBar(true); + configurer.setShowMenuBar(false); + configurer.setShowStatusLine(false); + configurer.setShowPerspectiveBar(true); + configurer.setTitle("Argeo Web UI"); //$NON-NLS-1$ + // Full screen, see + // http://wiki.eclipse.org/RAP/FAQ#How_to_create_a_fullscreen_application + configurer.setShellStyle(SWT.NO_TRIM); + Rectangle bounds = Display.getCurrent().getBounds(); + configurer.setInitialSize(new Point(bounds.width, bounds.height)); + + // Handle window resize in Rap 2.1+ see + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=417254 + Display.getCurrent().addListener(SWT.Resize, new Listener() { + private static final long serialVersionUID = 2970912561866704526L; + + @Override + public void handleEvent(Event event) { + Rectangle bounds = event.display.getBounds(); + IWorkbenchWindow iww = getWindowConfigurer().getWindow() + .getWorkbench().getActiveWorkbenchWindow(); + iww.getShell().setBounds(bounds); + } + }); + } + + @Override + public void postWindowCreate() { + Shell shell = getWindowConfigurer().getWindow().getShell(); + shell.setMaximized(true); + } + + @Override + public void postWindowOpen() { + String defaultPerspective = getWindowConfigurer() + .getWorkbenchConfigurer().getWorkbench() + .getPerspectiveRegistry().getDefaultPerspective(); + if (defaultPerspective == null) { + IWorkbenchWindow window = getWindowConfigurer().getWindow(); + if (window == null) + return; + + IWorkbenchAction openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG + .create(window); + openPerspectiveDialogAction.run(); + } + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchAdvisor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchAdvisor.java new file mode 100644 index 000000000..b650dbbf5 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchAdvisor.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.rap; + +import org.eclipse.ui.IPerspectiveDescriptor; +import org.eclipse.ui.application.IWorkbenchConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** Eclipse RAP specific workbench advisor */ +public class RapWorkbenchAdvisor extends WorkbenchAdvisor { + public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective"; + public final static String SAVE_AND_RESTORE_PROPERTY = "org.argeo.security.ui.saveAndRestore"; + + private String initialPerspective = System.getProperty( + INITIAL_PERSPECTIVE_PROPERTY, null); + + private String username; + + public RapWorkbenchAdvisor(String username) { + this.username = username; + } + + @Override + public void initialize(IWorkbenchConfigurer configurer) { + super.initialize(configurer); + Boolean saveAndRestore = Boolean.parseBoolean(System.getProperty( + SAVE_AND_RESTORE_PROPERTY, "false")); + configurer.setSaveAndRestore(saveAndRestore); + } + + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( + IWorkbenchWindowConfigurer configurer) { + return new RapWindowAdvisor(configurer, username); + } + + public String getInitialWindowPerspectiveId() { + if (initialPerspective != null) { + // check whether this user can see the declared perspective + // (typically the perspective won't be listed if this user doesn't + // have the right to see it) + IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench() + .getPerspectiveRegistry() + .findPerspectiveWithId(initialPerspective); + if (pd == null) + return null; + } + return initialPerspective; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchLogin.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchLogin.java new file mode 100644 index 000000000..353f3e929 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/RapWorkbenchLogin.java @@ -0,0 +1,90 @@ +package org.argeo.cms.ui.workbench.rap; + +import java.security.PrivilegedAction; +import java.util.Locale; + +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; + +import org.argeo.cms.CmsMsg; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.util.CmsUtils; +import org.argeo.cms.util.LoginEntryPoint; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.client.service.JavaScriptExecutor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; + +public class RapWorkbenchLogin extends LoginEntryPoint { + // private final static Log log = + // LogFactory.getLog(RapWorkbenchLogin.class); + + /** Override to provide an application specific workbench advisor */ + protected RapWorkbenchAdvisor createRapWorkbenchAdvisor(String username) { + return new RapWorkbenchAdvisor(username); + } + + @Override + public int createUI() { + JavaScriptExecutor jsExecutor = RWT.getClient().getService(JavaScriptExecutor.class); + int returnCode; + try { + returnCode = super.createUI(); + } finally { + // always reload + // TODO optimise? + jsExecutor.execute("location.reload()"); + } + return returnCode; + } + + @Override + protected int postLogin() { + Subject subject = getSubject(); + final Display display = Display.getCurrent(); + if (subject.getPrincipals(X500Principal.class).isEmpty()) { + RWT.getClient().getService(JavaScriptExecutor.class).execute("location.reload()"); + } + // + // RUN THE WORKBENCH + // + Integer returnCode = null; + try { + returnCode = Subject.doAs(subject, new PrivilegedAction() { + public Integer run() { + int result = createAndRunWorkbench(display, CurrentUser.getUsername(subject)); + return new Integer(result); + } + }); + // explicit workbench closing + logout(); + } finally { + display.dispose(); + } + return returnCode; + } + + protected int createAndRunWorkbench(Display display, String username) { + RapWorkbenchAdvisor workbenchAdvisor = createRapWorkbenchAdvisor(username); + return PlatformUI.createAndRunWorkbench(display, workbenchAdvisor); + } + + @Override + protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale, + SelectionListener loginSelectionListener) { +// Button loginButton = new Button(credentialsBlock, SWT.PUSH); +// loginButton.setText(CmsMsg.login.lead(selectedLocale)); +// loginButton.setLayoutData(CmsUtils.fillWidth()); +// loginButton.addSelectionListener(loginSelectionListener); + } + + @Override + protected Display createDisplay() { + return PlatformUI.createDisplay(); + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SecureRapActivator.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SecureRapActivator.java new file mode 100644 index 000000000..74068c241 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SecureRapActivator.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.rap; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** Configure Equinox login context from the bundle context. */ +public class SecureRapActivator implements BundleActivator { + public final static String ID = "org.argeo.cms.ui.workbench.rap"; + + private static BundleContext bundleContext; + + public void start(BundleContext bc) throws Exception { + bundleContext = bc; + } + + public void stop(BundleContext context) throws Exception { + bundleContext = null; + } + + public static BundleContext getBundleContext() { + return bundleContext; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SpnegoWorkbenchLogin.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SpnegoWorkbenchLogin.java new file mode 100644 index 000000000..412fecfc6 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/SpnegoWorkbenchLogin.java @@ -0,0 +1,99 @@ +package org.argeo.cms.ui.workbench.rap; + +import java.security.PrivilegedAction; +import java.util.Locale; + +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.argeo.cms.CmsMsg; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.util.CmsUtils; +import org.argeo.cms.util.LoginEntryPoint; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.client.service.JavaScriptExecutor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; + +public class SpnegoWorkbenchLogin extends LoginEntryPoint { + // private final static Log log = + // LogFactory.getLog(RapWorkbenchLogin.class); + + /** Override to provide an application specific workbench advisor */ + protected RapWorkbenchAdvisor createRapWorkbenchAdvisor(String username) { + return new RapWorkbenchAdvisor(username); + } + + @Override + public int createUI() { + HttpServletRequest request = RWT.getRequest(); + String authorization = request.getHeader(HEADER_AUTHORIZATION); + if (authorization == null || !authorization.startsWith("Negotiate")) { + HttpServletResponse response = RWT.getResponse(); + response.setStatus(401); + response.setHeader(HEADER_WWW_AUTHENTICATE, "Negotiate"); + response.setDateHeader("Date", System.currentTimeMillis()); + response.setDateHeader("Expires", System.currentTimeMillis() + (24 * 60 * 60 * 1000)); + response.setHeader("Accept-Ranges", "bytes"); + response.setHeader("Connection", "Keep-Alive"); + response.setHeader("Keep-Alive", "timeout=5, max=97"); + // response.setContentType("text/html; charset=UTF-8"); + } + + int returnCode; + returnCode = super.createUI(); + return returnCode; + } + + @Override + protected int postLogin() { + Subject subject = getSubject(); + final Display display = Display.getCurrent(); + if (subject.getPrincipals(X500Principal.class).isEmpty()) { + RWT.getClient().getService(JavaScriptExecutor.class).execute("location.reload()"); + } + // + // RUN THE WORKBENCH + // + Integer returnCode = null; + try { + returnCode = Subject.doAs(subject, new PrivilegedAction() { + public Integer run() { + int result = createAndRunWorkbench(display, CurrentUser.getUsername(subject)); + return new Integer(result); + } + }); + // explicit workbench closing + logout(); + } finally { + display.dispose(); + } + return returnCode; + } + + protected int createAndRunWorkbench(Display display, String username) { + RapWorkbenchAdvisor workbenchAdvisor = createRapWorkbenchAdvisor(username); + return PlatformUI.createAndRunWorkbench(display, workbenchAdvisor); + } + + @Override + protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale, + SelectionListener loginSelectionListener) { +// Button loginButton = new Button(credentialsBlock, SWT.PUSH); +// loginButton.setText(CmsMsg.login.lead(selectedLocale)); +// loginButton.setLayoutData(CmsUtils.fillWidth()); +// loginButton.addSelectionListener(loginSelectionListener); + } + + @Override + protected Display createDisplay() { + return PlatformUI.createDisplay(); + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/OpenHome.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/OpenHome.java new file mode 100644 index 000000000..86e01036d --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/OpenHome.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.rap.commands; + +import org.argeo.cms.ui.workbench.UserHomePerspective; +import org.argeo.cms.ui.workbench.util.CommandUtils; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Default action of the user menu */ +public class OpenHome extends AbstractHandler { + private final static String PROP_OPEN_HOME_CMD_ID = "org.argeo.ui.openHomeCommandId"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + String defaultCmdId = System.getProperty(PROP_OPEN_HOME_CMD_ID, ""); + if (!"".equals(defaultCmdId.trim())) + CommandUtils.callCommand(defaultCmdId); + else { + try { + String defaultPerspective = HandlerUtil.getActiveWorkbenchWindow(event).getWorkbench() + .getPerspectiveRegistry().getDefaultPerspective(); + HandlerUtil.getActiveSite(event).getWorkbenchWindow() + .openPage(defaultPerspective != null ? defaultPerspective : UserHomePerspective.ID, null); + } catch (WorkbenchException e) { + ErrorFeedback.show("Cannot open home perspective", e); + } + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/UserMenu.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/UserMenu.java new file mode 100644 index 000000000..4934e5620 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench.rap/src/org/argeo/cms/ui/workbench/rap/commands/UserMenu.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.rap.commands; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** Default action of the user menu */ +public class UserMenu extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + return null; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/.classpath b/legacy/argeo-commons/org.argeo.cms.ui.workbench/.classpath new file mode 100644 index 000000000..457b11571 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/.classpath @@ -0,0 +1,9 @@ + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/.gitignore b/legacy/argeo-commons/org.argeo.cms.ui.workbench/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/.project b/legacy/argeo-commons/org.argeo.cms.ui.workbench/.project new file mode 100644 index 000000000..f7f7a8e6a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/.project @@ -0,0 +1,28 @@ + + + org.argeo.cms.ui.workbench + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/.gitignore b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/.gitignore new file mode 100644 index 000000000..4854a41b9 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml new file mode 100644 index 000000000..1c74f7a2b --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/commands.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/common.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/common.xml new file mode 100644 index 000000000..32a3a8f9d --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/common.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/osgi.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/osgi.xml new file mode 100644 index 000000000..a32241299 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/osgi.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml new file mode 100644 index 000000000..a884d5108 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/META-INF/spring/parts.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle.properties new file mode 100644 index 000000000..3ec4305b9 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle.properties @@ -0,0 +1 @@ +search=Finden \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle_de.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle_de.properties new file mode 100644 index 000000000..8c4ac22ce --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/OSGI-INF/l10n/bundle_de.properties @@ -0,0 +1 @@ +search=Search \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/bnd.bnd b/legacy/argeo-commons/org.argeo.cms.ui.workbench/bnd.bnd new file mode 100644 index 000000000..da2875c31 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/bnd.bnd @@ -0,0 +1,26 @@ +Bundle-SymbolicName: org.argeo.cms.ui.workbench;singleton:=true +Bundle-Activator: org.argeo.cms.ui.workbench.WorkbenchUiPlugin +Bundle-ActivationPolicy: lazy + +Require-Bundle: org.eclipse.core.runtime,\ +org.eclipse.core.commands + +Import-Package: org.argeo.cms.auth,\ +org.argeo.cms,\ +org.argeo.cms.ui,\ +org.argeo.eclipse.spring,\ +org.argeo.eclipse.ui.utils,\ +org.eclipse.core.runtime.jobs,\ +org.eclipse.jface.window,\ +org.eclipse.swt,\ +org.eclipse.swt.widgets,\ +org.eclipse.ui.services,\ +org.osgi.*;version=0.0.0,\ +org.springframework.core,\ +org.springframework.beans.factory,\ +org.springframework.core.io.support,\ +!org.eclipse.core.runtime,\ +* + + +# org.argeo.eclipse.ui.workbench;resolution:=optional,\ diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/build.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench/build.properties new file mode 100644 index 000000000..1b9b7bd51 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + icons/,\ + plugin.xml +additional.bundles = org.apache.commons.httpclient diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/keyring.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench/keyring.properties new file mode 100644 index 000000000..0228d47ee --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/keyring.properties @@ -0,0 +1 @@ +argeo.keyring.secreteKeyLength=256 \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/plugin.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench/plugin.xml new file mode 100644 index 000000000..f25331e4a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/plugin.xml @@ -0,0 +1,807 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/pom.xml b/legacy/argeo-commons/org.argeo.cms.ui.workbench/pom.xml new file mode 100644 index 000000000..134a73adf --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.argeo.slc.legacy.commons + argeo-commons-legacy + 2.1.85-SNAPSHOT + .. + + org.argeo.cms.ui.workbench + CMS Workbench + jar + + + org.argeo.commons + org.argeo.cms.ui + ${version.argeo-commons} + + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + provided + + + + + org.argeo.tp.spring + org.springframework.beans + + + org.argeo.tp.spring + org.springframework.core + + + org.argeo.tp.spring + org.springframework.context + + + org.argeo.tp.gemini + org.eclipse.gemini.blueprint.core + + + + + org.argeo.tp + argeo-tp-rap-e3 + ${version.argeo-tp} + pom + provided + + + + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AbstractSystemExecution.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AbstractSystemExecution.java new file mode 100644 index 000000000..ce92c4613 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AbstractSystemExecution.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.spring; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.node.NodeConstants; + +/** Provides base method for executing code with system authorization. */ +abstract class AbstractSystemExecution { + private final static Log log = LogFactory.getLog(AbstractSystemExecution.class); + private final Subject subject = new Subject(); + + /** Authenticate the calling thread */ + protected void authenticateAsSystem() { + ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + try { + LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject); + lc.login(); + } catch (LoginException e) { + throw new CmsException("Cannot login as system", e); + } finally { + Thread.currentThread().setContextClassLoader(origClassLoader); + } + if (log.isTraceEnabled()) + log.trace("System authenticated"); + } + + protected void deauthenticateAsSystem() { + ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + try { + LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject); + lc.logout(); + } catch (LoginException e) { + throw new CmsException("Cannot logout as system", e); + } finally { + Thread.currentThread().setContextClassLoader(origClassLoader); + } + } + + protected Subject getSubject() { + return subject; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AuthenticatedApplicationContextInitialization.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AuthenticatedApplicationContextInitialization.java new file mode 100644 index 000000000..e1af58274 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/AuthenticatedApplicationContextInitialization.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.spring; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.Subject; + +import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.support.AbstractBeanFactory; +import org.springframework.beans.factory.support.SecurityContextProvider; +import org.springframework.beans.factory.support.SimpleSecurityContextProvider; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * Executes with a system authentication the instantiation and initialization + * methods of the application context where it has been defined. + */ +public class AuthenticatedApplicationContextInitialization extends + AbstractSystemExecution implements + DependencyInitializationAwareBeanPostProcessor, ApplicationContextAware { + /** If non empty, restricts to these beans */ + private List beanNames = new ArrayList(); + + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + if (beanNames.size() == 0 || beanNames.contains(beanName)) + authenticateAsSystem(); + return bean; + } + + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (beanNames.size() == 0 || beanNames.contains(beanName)) + deauthenticateAsSystem(); + return bean; + } + + public void setBeanNames(List beanNames) { + this.beanNames = beanNames; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + if (applicationContext.getAutowireCapableBeanFactory() instanceof AbstractBeanFactory) { + final AbstractBeanFactory beanFactory = ((AbstractBeanFactory) applicationContext + .getAutowireCapableBeanFactory()); + // retrieve subject's access control context + // and set it as the bean factory security context + Subject.doAs(getSubject(), new PrivilegedAction() { + @Override + public Void run() { + SecurityContextProvider scp = new SimpleSecurityContextProvider( + AccessController.getContext()); + beanFactory.setSecurityContextProvider(scp); + return null; + } + }); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/SimpleRoleRegistration.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/SimpleRoleRegistration.java new file mode 100644 index 000000000..255ce111c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/SimpleRoleRegistration.java @@ -0,0 +1,89 @@ +package org.argeo.cms.spring; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +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 Log log = LogFactory + .getLog(SimpleRoleRegistration.class); + + private String role; + private List roles = new ArrayList(); + private UserAdmin userAdmin; + private UserTransaction 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 CmsException("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 CmsException("Badly formatted role name " + name, e); + } + } + + public void setRole(String role) { + this.role = role; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + public void setUserAdmin(UserAdmin userAdminService) { + this.userAdmin = userAdminService; + } + + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/osgi/OsgiModuleLabel.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/osgi/OsgiModuleLabel.java new file mode 100644 index 000000000..f085d6a23 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/spring/osgi/OsgiModuleLabel.java @@ -0,0 +1,41 @@ +package org.argeo.cms.spring.osgi; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; + +/** + * Logs the name and version of an OSGi bundle based on its + * {@link BundleContext}. + */ +public class OsgiModuleLabel { + private final static Log log = LogFactory.getLog(OsgiModuleLabel.class); + + private Bundle bundle; + + public OsgiModuleLabel() { + } + + /** Sets without logging. */ + public OsgiModuleLabel(Bundle bundle) { + this.bundle = bundle; + } + + /** + * Retrieved bundle from a bundle context and logs it. Typically to be set + * as a Spring bean. + */ + public void setBundleContext(BundleContext bundleContext) { + this.bundle = bundleContext.getBundle(); + log.info(msg()); + } + + public String msg() { + String name = bundle.getHeaders().get(Constants.BUNDLE_NAME).toString(); + String symbolicName = bundle.getSymbolicName(); + String version = bundle.getVersion().toString(); + return name + " v" + version + " (" + symbolicName + ")"; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/CmsWorkbenchStyles.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/CmsWorkbenchStyles.java new file mode 100644 index 000000000..357bb6807 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/CmsWorkbenchStyles.java @@ -0,0 +1,8 @@ +package org.argeo.cms.ui.workbench; + +/** Centralize the declaration of Workbench specific CSS Styles */ +public interface CmsWorkbenchStyles { + + // Specific People layouting + String WORKBENCH_FORM_TEXT = "workbench_form_text"; +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java new file mode 100644 index 000000000..53a916a15 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.cms.ui.workbench.jcr.NodeFsBrowserView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Base perspective for the Jcr browser */ +public class JcrBrowserPerspective implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(true); + IFolderLayout upperLeft = layout.createFolder(WorkbenchUiPlugin.PLUGIN_ID + ".upperLeft", IPageLayout.LEFT, + 0.4f, layout.getEditorArea()); + upperLeft.addView(JcrBrowserView.ID); + upperLeft.addView(NodeFsBrowserView.ID); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/MaintenancePerspective.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/MaintenancePerspective.java new file mode 100644 index 000000000..9bfcbad18 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/MaintenancePerspective.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.useradmin.AdminLogView; +import org.argeo.cms.ui.workbench.useradmin.UserProfile; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** First draft of a maintenance perspective. Not yet used */ +public class MaintenancePerspective implements IPerspectiveFactory { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".adminMaintenancePerspective"; + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + + IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.50f, editorArea); + bottom.addView(AdminLogView.ID); + + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.30f, editorArea); + left.addView(UserProfile.ID); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/OsgiExplorerPerspective.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/OsgiExplorerPerspective.java new file mode 100644 index 000000000..5534a6126 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/OsgiExplorerPerspective.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench; + +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** OSGi explorer perspective (to be enriched declaratively) */ +public class OsgiExplorerPerspective implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(true); + layout.setFixed(false); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityAdminPerspective.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityAdminPerspective.java new file mode 100644 index 000000000..04b54ee80 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/SecurityAdminPerspective.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.internal.useradmin.parts.GroupsView; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UsersView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Default perspective to manage users and groups */ +public class SecurityAdminPerspective implements IPerspectiveFactory { + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.3f, editorArea); + IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT, 0.5f, editorArea); + left.addView(UsersView.ID); + right.addView(GroupsView.ID); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java new file mode 100644 index 000000000..e5e98170a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench; + +import org.argeo.cms.ui.workbench.jcr.NodeFsBrowserView; +import org.argeo.cms.ui.workbench.useradmin.UserProfile; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Home perspective for the current user */ +public class UserHomePerspective implements IPerspectiveFactory { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".userHomePerspective"; + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.40f, editorArea); + left.addView(NodeFsBrowserView.ID); + left.addView(UserProfile.ID); + // left.addView(LogView.ID); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/WorkbenchUiPlugin.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/WorkbenchUiPlugin.java new file mode 100644 index 000000000..d96daf221 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/WorkbenchUiPlugin.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench; + +import java.io.IOException; +import java.util.ResourceBundle; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.widgets.auth.DefaultLoginDialog; +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** The activator class controls the plug-in life cycle */ +public class WorkbenchUiPlugin extends AbstractUIPlugin implements ILogListener { + private final static Log log = LogFactory.getLog(WorkbenchUiPlugin.class); + + // The plug-in ID + public final static String PLUGIN_ID = "org.argeo.cms.ui.workbench"; //$NON-NLS-1$ + public final static String THEME_PLUGIN_ID = "org.argeo.cms.ui.theme"; //$NON-NLS-1$ + + private ResourceBundle messages; + private static BundleContext bundleContext; + + public static InheritableThreadLocal display = new InheritableThreadLocal() { + + @Override + protected Display initialValue() { + return Display.getCurrent(); + } + }; + + final static String CONTEXT_KEYRING = "KEYRING"; + + private CallbackHandler defaultCallbackHandler; + private ServiceRegistration defaultCallbackHandlerReg; + + // The shared instance + private static WorkbenchUiPlugin plugin; + + public void start(BundleContext context) throws Exception { + super.start(context); + bundleContext = context; + defaultCallbackHandler = new DefaultCallbackHandler(); + defaultCallbackHandlerReg = context.registerService(CallbackHandler.class, defaultCallbackHandler, null); + + plugin = this; + messages = ResourceBundle.getBundle(PLUGIN_ID + ".messages"); + Platform.addLogListener(this); + if (log.isTraceEnabled()) + log.trace("Eclipse logging now directed to standard logging"); + } + + public void stop(BundleContext context) throws Exception { + bundleContext = null; + defaultCallbackHandlerReg.unregister(); + } + + public static BundleContext getBundleContext() { + return bundleContext; + } + + /* + * Returns the shared instance + * + * @return the shared instance + */ + public static WorkbenchUiPlugin getDefault() { + return plugin; + } + + protected class DefaultCallbackHandler implements CallbackHandler { + public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { + + // if (display != null) // RCP + Display displayToUse = display.get(); + if (displayToUse == null)// RCP + displayToUse = Display.getDefault(); + displayToUse.syncExec(new Runnable() { + public void run() { + DefaultLoginDialog dialog = new DefaultLoginDialog(display.get().getActiveShell()); + try { + dialog.handle(callbacks); + } catch (IOException e) { + throw new CmsException("Cannot open dialog", e); + } + } + }); + // else {// RAP + // DefaultLoginDialog dialog = new DefaultLoginDialog(); + // dialog.handle(callbacks); + // } + } + + } + + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(THEME_PLUGIN_ID, path); + } + + /** Returns the internationalized label for the given key */ + public static String getMessage(String key) { + try { + return getDefault().messages.getString(key); + } catch (NullPointerException npe) { + log.warn(key + " not found."); + return key; + } + } + + /** + * Gives access to the internationalization message bundle. Returns null in case + * this UiPlugin is not started (for JUnit tests, by instance) + */ + public static ResourceBundle getMessagesBundle() { + if (getDefault() != null) + // To avoid NPE + return getDefault().messages; + else + return null; + } + + public void logging(IStatus status, String plugin) { + Log pluginLog = LogFactory.getLog(plugin); + Integer severity = status.getSeverity(); + if (severity == IStatus.ERROR) + pluginLog.error(status.getMessage(), status.getException()); + else if (severity == IStatus.WARNING) + pluginLog.warn(status.getMessage(), status.getException()); + else if (severity == IStatus.INFO) + pluginLog.info(status.getMessage(), status.getException()); + else if (severity == IStatus.CANCEL) + if (pluginLog.isDebugEnabled()) + pluginLog.debug(status.getMessage(), status.getException()); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/DoNothing.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/DoNothing.java new file mode 100644 index 000000000..c8a107627 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/DoNothing.java @@ -0,0 +1,15 @@ +package org.argeo.cms.ui.workbench.commands; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** Utilitary command to enable sub menus in various toolbars. Does nothing */ +public class DoNothing extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".doNothing"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenChangePasswordDialog.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenChangePasswordDialog.java new file mode 100644 index 000000000..30836b948 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenChangePasswordDialog.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.commands; + +import static org.argeo.cms.CmsMsg.changePassword; +import static org.argeo.cms.CmsMsg.currentPassword; +import static org.argeo.cms.CmsMsg.newPassword; +import static org.argeo.cms.CmsMsg.passwordChanged; +import static org.argeo.cms.CmsMsg.repeatNewPassword; +import static org.eclipse.jface.dialogs.IMessageProvider.INFORMATION; + +import java.security.AccessController; +import java.util.Arrays; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.node.security.CryptoKeyring; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +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; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Open the change password dialog */ +public class OpenChangePasswordDialog extends AbstractHandler { + private final static Log log = LogFactory.getLog(OpenChangePasswordDialog.class); + private UserAdmin userAdmin; + private UserTransaction userTransaction; + private CryptoKeyring keyring = null; + + public Object execute(ExecutionEvent event) throws ExecutionException { + ChangePasswordDialog dialog = new ChangePasswordDialog(HandlerUtil.getActiveShell(event), userAdmin); + if (dialog.open() == Dialog.OK) { + MessageDialog.openInformation(HandlerUtil.getActiveShell(event), passwordChanged.lead(), + passwordChanged.lead()); + } + return null; + } + + @SuppressWarnings("unchecked") + protected void changePassword(char[] oldPassword, char[] newPassword) { + Subject subject = Subject.getSubject(AccessController.getContext()); + String name = subject.getPrincipals(X500Principal.class).iterator().next().toString(); + LdapName dn; + try { + dn = new LdapName(name); + } catch (InvalidNameException e) { + throw new CmsException("Invalid user dn " + name, e); + } + User user = (User) userAdmin.getRole(dn.toString()); + if (!user.hasCredential(null, oldPassword)) + throw new CmsException("Invalid password"); + if (Arrays.equals(newPassword, new char[0])) + throw new CmsException("New password empty"); + try { + userTransaction.begin(); + user.getCredentials().put(null, newPassword); + if (keyring != null) { + keyring.changePassword(oldPassword, newPassword); + // TODO change secret keys in the CMS session + } + userTransaction.commit(); + } catch (Exception e) { + try { + userTransaction.rollback(); + } catch (Exception e1) { + log.error("Could not roll back", e1); + } + if (e instanceof RuntimeException) + throw (RuntimeException) e; + else + throw new CmsException("Cannot change password", e); + } + } + + class ChangePasswordDialog extends TitleAreaDialog { + private static final long serialVersionUID = -6963970583882720962L; + private Text oldPassword, newPassword1, newPassword2; + + public ChangePasswordDialog(Shell parentShell, UserAdmin securityService) { + super(parentShell); + } + + protected Point getInitialSize() { + return new Point(400, 450); + } + + 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)); + oldPassword = createLP(composite, currentPassword.lead()); + newPassword1 = createLP(composite, newPassword.lead()); + newPassword2 = createLP(composite, repeatNewPassword.lead()); + + setMessage(changePassword.lead(), INFORMATION); + parent.pack(); + oldPassword.setFocus(); + return composite; + } + + @Override + protected void okPressed() { + try { + if (!newPassword1.getText().equals(newPassword2.getText())) + throw new CmsException("New passwords are different"); + changePassword(oldPassword.getTextChars(), newPassword1.getTextChars()); + close(); + } catch (Exception e) { + ErrorFeedback.show("Cannot change password", e); + } + } + + /** Creates label and password. */ + protected Text createLP(Composite parent, String label) { + new Label(parent, SWT.NONE).setText(label); + Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD | SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + return text; + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(changePassword.lead()); + } + } + + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } + + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } + + public void setKeyring(CryptoKeyring keyring) { + this.keyring = keyring; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenEditor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenEditor.java new file mode 100644 index 000000000..ecf84c351 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenEditor.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.commands; + +import javax.jcr.Node; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.JcrQueryEditorInput; +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodeEditorInput; +import org.argeo.cms.ui.workbench.jcr.DefaultNodeEditor; +import org.argeo.cms.ui.workbench.jcr.GenericJcrQueryEditor; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Open a {@link Node} editor of a specific type given the node path */ +public class OpenEditor extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".openEditor"; + + public final static String PARAM_PATH = "param.jcrNodePath"; + public final static String PARAM_EDITOR_ID = "param.editorId"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + String editorId = event.getParameter(PARAM_EDITOR_ID); + try { + IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow( + event).getActivePage(); + if (DefaultNodeEditor.ID.equals(editorId)) { + String path = event.getParameter(PARAM_PATH); + NodeEditorInput nei = new NodeEditorInput(path); + activePage.openEditor(nei, DefaultNodeEditor.ID); + } else if (GenericJcrQueryEditor.ID.equals(editorId)) { + JcrQueryEditorInput editorInput = new JcrQueryEditorInput( + GenericJcrQueryEditor.ID, null); + activePage.openEditor(editorInput, editorId); + } + } catch (PartInitException e) { + throw new EclipseUiException( + "Cannot open editor of ID " + editorId, e); + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenHomePerspective.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenHomePerspective.java new file mode 100644 index 000000000..0e1983234 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/commands/OpenHomePerspective.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.commands; + +import org.argeo.cms.ui.workbench.UserHomePerspective; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Default action of the user menu */ +public class OpenHomePerspective extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + HandlerUtil.getActiveSite(event).getWorkbenchWindow() + .openPage(UserHomePerspective.ID, null); + } catch (WorkbenchException e) { + ErrorFeedback.show("Cannot open home perspective", e); + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/WorkbenchConstants.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/WorkbenchConstants.java new file mode 100644 index 000000000..8cfb0e8f7 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/WorkbenchConstants.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal; + +/** Constants used across the application. */ +@Deprecated +public interface WorkbenchConstants { +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddFolderNode.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddFolderNode.java new file mode 100644 index 000000000..f17fde91d --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddFolderNode.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.eclipse.ui.dialogs.SingleValue; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * 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 extends AbstractHandler { + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".addFolderNode"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + TreeParent treeParentNode = null; + Node jcrParentNode = null; + + 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 null; + + 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")); + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddPrivileges.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddPrivileges.java new file mode 100644 index 000000000..fafd76b72 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddPrivileges.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.AddPrivilegeWizard; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.UserAdmin; + +/** Open a dialog to add privileges on the selected node to a chosen group */ +public class AddPrivileges extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".addPrivileges"; + + /* DEPENDENCY INJECTION */ + private UserAdmin userAdmin; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + TreeParent treeParentNode = null; + Node jcrParentNode = null; + + 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 null; + + try { + String targetPath = jcrParentNode.getPath(); + AddPrivilegeWizard wizard = new AddPrivilegeWizard( + jcrParentNode.getSession(), targetPath, userAdmin); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), wizard); + dialog.open(); + return null; + } catch (RepositoryException re) { + throw new EclipseUiException("Unable to retrieve " + + "path or JCR session to add privilege on " + + jcrParentNode, re); + } + } else { + ErrorFeedback.show("Cannot add privileges"); + } + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java new file mode 100644 index 000000000..3539cacc1 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.net.URI; +import java.util.Hashtable; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryFactory; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +import org.argeo.cms.ArgeoNames; +import org.argeo.cms.ArgeoTypes; +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.cms.ui.workbench.util.CommandUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.jcr.JcrUtils; +import org.argeo.node.NodeConstants; +import org.argeo.node.NodeUtils; +import org.argeo.node.security.Keyring; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +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 extends AbstractHandler implements WorkbenchConstants, ArgeoNames { + + private RepositoryFactory repositoryFactory; + private Repository nodeRepository; + private Keyring keyring; + + public Object execute(ExecutionEvent event) throws ExecutionException { + RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(Display.getDefault().getActiveShell()); + if (dlg.open() == Dialog.OK) { + CommandUtils.callCommand(Refresh.ID); + } + return 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 params = new Hashtable(); + params.put(NodeConstants.LABELED_URI, checkedUriStr); + Repository repository = repositoryFactory.getRepository(params); + if (username.getText().trim().equals("")) {// anonymous + // FIXME make it more generic + session = repository.login("main"); + } 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 = NodeUtils.getUserHome(nodeSession); + + Node remote = home.hasNode(ARGEO_REMOTE) ? home.getNode(ARGEO_REMOTE) : home.addNode(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(ARGEO_URI, uri.getText()); + remoteRepository.setProperty(ARGEO_USER_ID, username.getText()); + nodeSession.save(); + if (saveInKeyring.getSelection()) { + String pwdPath = remoteRepository.getPath() + '/' + 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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/ConfigurableNodeDump.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/ConfigurableNodeDump.java new file mode 100644 index 000000000..60f424433 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/ConfigurableNodeDump.java @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +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.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * First draft of a wizard that enable configurable recursive dump of the + * current selected Node (Only one at a time). Enable among other to export + * children Nodes and to choose to export binaries or not. It is useful to + * retrieve business data from live systems to prepare migration or test locally + */ +public class ConfigurableNodeDump extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".nodeConfigurableDump"; + + private final static DateFormat df = new SimpleDateFormat( + "yyyy-MM-dd_HH-mm"); + + public final static int EXPORT_NODE = 0; + public final static int EXPORT_CHILDREN = 1; + public final static int EXPORT_GRAND_CHILDREN = 2; + + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + Iterator lst = ((IStructuredSelection) selection).iterator(); + if (lst.hasNext()) { + Object element = lst.next(); + if (element instanceof SingleJcrNodeElem) { + SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; + Node node = sjn.getNode(); + + ConfigureDumpWizard wizard = new ConfigureDumpWizard( + HandlerUtil.getActiveShell(event), + "Import Resource CSV"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), wizard); + int result = dialog.open(); + + if (result == Window.OK) { + + String dateVal = df.format(new GregorianCalendar() + .getTime()); + try { + + Path tmpDirPath = Files.createTempDirectory(dateVal + + "-NodeDump-"); + List toExport = retrieveToExportNodes(node, + wizard.currExportType); + + for (Node currNode : toExport) { + FileOutputStream fos; + String fileName = wizard.prefix + + JcrUtils.replaceInvalidChars(currNode + .getName()) + "_" + dateVal + + ".xml"; + File currFile = new File(tmpDirPath.toString() + + "/" + fileName); + currFile.createNewFile(); + fos = new FileOutputStream(currFile); + node.getSession().exportSystemView( + currNode.getPath(), fos, + !wizard.includeBinaries, false); + fos.flush(); + fos.close(); + } + } catch (RepositoryException e) { + throw new EclipseUiException( + "Unable to perform SystemExport on " + node, e); + } catch (IOException e) { + throw new EclipseUiException("Unable to SystemExport " + + node, e); + } + } + } + } + return null; + } + + private List retrieveToExportNodes(Node node, int currExportType) + throws RepositoryException { + List nodes = new ArrayList(); + switch (currExportType) { + case EXPORT_NODE: + nodes.add(node); + return nodes; + case EXPORT_CHILDREN: + return JcrUtils.nodeIteratorToList(node.getNodes()); + case EXPORT_GRAND_CHILDREN: + NodeIterator nit = node.getNodes(); + while (nit.hasNext()) + nodes.addAll(JcrUtils.nodeIteratorToList(nit.nextNode() + .getNodes())); + return nodes; + + default: + return nodes; + } + } + + // private synchronized void openGeneratedFile(String path, String fileName) + // { + // Map params = new HashMap(); + // params.put(OpenFile.PARAM_FILE_NAME, fileName); + // params.put(OpenFile.PARAM_FILE_URI, "file://" + path); + // CommandUtils.callCommand("org.argeo.security.ui.specific.openFile", + // params); + // } + + private class ConfigureDumpWizard extends Wizard { + + // parameters + protected String prefix; + protected int currExportType = EXPORT_NODE; + protected boolean includeBinaries = false; + + // UI Objects + private BasicPage page; + private Text prefixTxt; + private Button includeBinaryBtn; + private Button b1, b2, b3; + + public ConfigureDumpWizard(Shell parentShell, String title) { + setWindowTitle(title); + } + + @Override + public void addPages() { + try { + page = new BasicPage("Main page"); + addPage(page); + } catch (Exception e) { + throw new EclipseUiException("Cannot add page to wizard", e); + } + } + + @Override + public boolean performFinish() { + prefix = prefixTxt.getText(); + if (b1.getSelection()) + currExportType = EXPORT_NODE; + else if (b2.getSelection()) + currExportType = EXPORT_CHILDREN; + else if (b3.getSelection()) + currExportType = EXPORT_GRAND_CHILDREN; + includeBinaries = includeBinaryBtn.getSelection(); + return true; + } + + @Override + public boolean performCancel() { + return true; + } + + @Override + public boolean canFinish() { + String errorMsg = "No prefix defined."; + if ("".equals(prefixTxt.getText().trim())) { + page.setErrorMessage(errorMsg); + return false; + } else { + page.setErrorMessage(null); + return true; + } + } + + protected class BasicPage extends WizardPage { + private static final long serialVersionUID = 1L; + + public BasicPage(String pageName) { + super(pageName); + setTitle("Configure dump before launching"); + setMessage("Define the parameters of the dump to launch"); + } + + public void createControl(Composite parent) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + // Main Layout + Composite mainCmp = new Composite(parent, SWT.NONE); + mainCmp.setLayout(new GridLayout(2, false)); + mainCmp.setLayoutData(EclipseUiUtils.fillAll()); + + // The path + createBoldLabel(mainCmp, "Prefix"); + prefixTxt = new Text(mainCmp, SWT.SINGLE | SWT.BORDER); + prefixTxt.setLayoutData(EclipseUiUtils.fillAll()); + prefixTxt.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = 1L; + + @Override + public void modifyText(ModifyEvent event) { + if (prefixTxt.getText() != null) + getWizard().getContainer().updateButtons(); + } + }); + + new Label(mainCmp, SWT.SEPARATOR | SWT.HORIZONTAL) + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false, 2, 1)); + + // Which node to export + Label typeLbl = new Label(mainCmp, SWT.RIGHT); + typeLbl.setText(" Type"); + typeLbl.setFont(EclipseUiUtils.getBoldFont(mainCmp)); + typeLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, + false, 1, 3)); + + b1 = new Button(mainCmp, SWT.RADIO); + b1.setText("Export this node"); + b1.setSelection(true); + b2 = new Button(mainCmp, SWT.RADIO); + b2.setText("Export children nodes"); + b3 = new Button(mainCmp, SWT.RADIO); + b3.setText("Export grand-children nodes"); + + new Label(mainCmp, SWT.SEPARATOR | SWT.HORIZONTAL) + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false, 2, 1)); + + createBoldLabel(mainCmp, "Files and images"); + includeBinaryBtn = new Button(mainCmp, SWT.CHECK); + includeBinaryBtn.setText("Include binaries"); + + prefixTxt.setFocus(); + setControl(mainCmp); + } + } + } + + private Label createBoldLabel(Composite parent, String value) { + Label label = new Label(parent, SWT.RIGHT); + label.setText(" " + value); + label.setFont(EclipseUiUtils.getBoldFont(parent)); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + return label; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/CreateWorkspace.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/CreateWorkspace.java new file mode 100644 index 000000000..2d6949cd5 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/CreateWorkspace.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.util.Arrays; + +import org.argeo.cms.ui.jcr.model.RepositoryElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.eclipse.ui.dialogs.SingleValue; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Create a new JCR workspace */ +public class CreateWorkspace extends AbstractHandler { + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".addFolderNode"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (!(obj instanceof RepositoryElem)) + return null; + + RepositoryElem repositoryNode = (RepositoryElem) obj; + String workspaceName = SingleValue.ask("Workspace name", + "Enter workspace name"); + if (workspaceName != null) { + if (Arrays.asList(repositoryNode.getAccessibleWorkspaceNames()) + .contains(workspaceName)) { + ErrorFeedback.show("Workspace " + workspaceName + + " already exists."); + } else { + repositoryNode.createWorkspace(workspaceName); + view.nodeAdded(repositoryNode); + } + } + } else { + ErrorFeedback.show("Cannot create workspace"); + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DeleteNodes.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DeleteNodes.java new file mode 100644 index 000000000..a0c677091 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DeleteNodes.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.util.Iterator; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * 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 extends AbstractHandler { + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + // confirmation + StringBuffer buf = new StringBuffer(""); + Iterator lst = ((IStructuredSelection) selection).iterator(); + while (lst.hasNext()) { + SingleJcrNodeElem sjn = ((SingleJcrNodeElem) lst.next()); + buf.append(sjn.getName()).append(' '); + } + Boolean doRemove = MessageDialog.openConfirm( + HandlerUtil.getActiveShell(event), "Confirm deletion", + "Do you want to delete " + buf + "?"); + + // operation + if (doRemove) { + Iterator it = ((IStructuredSelection) selection).iterator(); + Object obj = null; + SingleJcrNodeElem ancestor = null; + WorkspaceElem rootAncestor = null; + try { + while (it.hasNext()) { + obj = it.next(); + 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); + } + } + return null; + } + + 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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DumpNode.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DumpNode.java new file mode 100644 index 000000000..ae23f1d54 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/DumpNode.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import static org.argeo.eclipse.ui.utils.SingleSourcingConstants.FILE_SCHEME; +import static org.argeo.eclipse.ui.utils.SingleSourcingConstants.SCHEME_HOST_SEPARATOR; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.util.CommandUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.specific.OpenFile; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Canonically call JCR Session#exportSystemView() on the first element returned + * by HandlerUtil#getActiveWorkbenchWindow() + * (...getActivePage().getSelection()), if it is a {@link SingleJcrNodeElem}, + * with both skipBinary and noRecurse boolean flags set to false. + * + * Resulting stream is saved in a tmp file and opened via the {@link OpenFile} + * single-sourced command. + */ +public class DumpNode extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".dumpNode"; + + private final static DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH-mm"); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + Iterator lst = ((IStructuredSelection) selection).iterator(); + if (lst.hasNext()) { + Object element = lst.next(); + if (element instanceof SingleJcrNodeElem) { + SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; + Node node = sjn.getNode(); + + // TODO add a dialog to configure the export and ask for + // confirmation + // Boolean ok = MessageDialog.openConfirm( + // HandlerUtil.getActiveShell(event), "Confirm dump", + // "Do you want to dump " + buf + "?"); + + File tmpFile; + FileOutputStream fos; + try { + tmpFile = File.createTempFile("JcrExport", ".xml"); + tmpFile.deleteOnExit(); + fos = new FileOutputStream(tmpFile); + String dateVal = df.format(new GregorianCalendar().getTime()); + node.getSession().exportSystemView(node.getPath(), fos, true, false); + openGeneratedFile(tmpFile.getAbsolutePath(), + "Dump-" + JcrUtils.replaceInvalidChars(node.getName()) + "-" + dateVal + ".xml"); + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to perform SystemExport on " + node, e); + } catch (IOException e) { + throw new EclipseUiException("Unable to SystemExport " + node, e); + } + } + } + return null; + } + + private synchronized void openGeneratedFile(String path, String fileName) { + Map params = new HashMap(); + params.put(OpenFile.PARAM_FILE_NAME, fileName); + params.put(OpenFile.PARAM_FILE_URI, FILE_SCHEME + SCHEME_HOST_SEPARATOR + path); + CommandUtils.callCommand(OpenFile.ID, params); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/EditNode.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/EditNode.java new file mode 100644 index 000000000..67f82380b --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/EditNode.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.Property; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodeEditorInput; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Generic command to open a Node in an editor. */ +public class EditNode extends AbstractHandler { + public final static String PARAM_EDITOR_ID = "editor"; + + private String defaultEditorId; + + private Map nodeTypeToEditor = new HashMap(); + + public Object execute(ExecutionEvent event) throws ExecutionException { + String path = event.getParameter(Property.JCR_PATH); + String type = event.getParameter(NodeType.NT_NODE_TYPE); + if (type == null) + type = NodeType.NT_UNSTRUCTURED; + + String editorId = event.getParameter(PARAM_EDITOR_ID); + if (editorId == null) + editorId = nodeTypeToEditor.containsKey(type) ? nodeTypeToEditor + .get(type) : defaultEditorId; + + NodeEditorInput nei = new NodeEditorInput(path); + try { + HandlerUtil.getActiveWorkbenchWindow(event).getActivePage() + .openEditor(nei, editorId); + } catch (PartInitException e) { + ErrorFeedback.show("Cannot open " + editorId + " with " + path + + " of type " + type, e); + } + return null; + } + + public void setDefaultEditorId(String defaultEditorId) { + this.defaultEditorId = defaultEditorId; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/GetNodeSize.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/GetNodeSize.java new file mode 100644 index 000000000..38d68136f --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/GetNodeSize.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.jcr.Node; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Compute an approximative size for the selected node(s) */ +public class GetNodeSize extends AbstractHandler { + // private final static Log log = LogFactory.getLog(GetNodeSize.class); + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".getNodeSize"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + + long size = 0; + + Iterator it = ((IStructuredSelection) selection).iterator(); + + // TODO enhance this: as the size method is recursive, we keep track + // of nodes for which we already have computed size so that we don't + // count them twice. In a first approximation, we assume that the + // structure selection keep the nodes ordered. + List importedPathes = new ArrayList(); + try { + nodesIt: while (it.hasNext()) { + Object obj = it.next(); + String curPath; + Node node; + if (obj instanceof SingleJcrNodeElem) { + node = ((SingleJcrNodeElem) obj).getNode(); + curPath = node.getSession().getWorkspace().getName(); + curPath += "/" + node.getPath(); + } else if (obj instanceof WorkspaceElem) { + node = ((WorkspaceElem) obj).getRootNode(); + curPath = node.getSession().getWorkspace().getName(); + } else + // non valid object type + continue nodesIt; + + Iterator itPath = importedPathes.iterator(); + while (itPath.hasNext()) { + String refPath = itPath.next(); + if (curPath.startsWith(refPath)) + // Already done : skip node + continue nodesIt; + } + size += JcrUtils.getNodeApproxSize(node); + importedPathes.add(curPath); + } + } catch (Exception e) { + ErrorFeedback.show("Cannot Get size of selected node ", e); + } + + String[] labels = { "OK" }; + Shell shell = HandlerUtil.getActiveWorkbenchWindow(event) + .getShell(); + MessageDialog md = new MessageDialog(shell, "Node size", null, + "Node size is: " + size / 1024 + " KB", + MessageDialog.INFORMATION, labels, 0); + md.open(); + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/Refresh.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/Refresh.java new file mode 100644 index 000000000..1924b63a7 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/Refresh.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.util.Iterator; + +import org.argeo.cms.ui.jcr.JcrBrowserUtils; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.TreeParent; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; + +/** + * Force the selected objects of the active view to be refreshed doing the + * following: + *
    + *
  1. The model objects are recomputed
  2. + *
  3. the view is refreshed
  4. + *
+ */ +public class Refresh extends AbstractHandler { + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".refresh"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + JcrBrowserView view = (JcrBrowserView) WorkbenchUiPlugin.getDefault() + .getWorkbench().getActiveWorkbenchWindow().getActivePage() + .getActivePart();// + + ISelection selection = WorkbenchUiPlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow().getActivePage().getSelection(); + + if (selection != null && selection instanceof IStructuredSelection + && !selection.isEmpty()) { + Iterator it = ((IStructuredSelection) selection).iterator(); + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof TreeParent) { + TreeParent tp = (TreeParent) obj; + JcrBrowserUtils.forceRefreshIfNeeded(tp); + view.refresh(obj); + } + } + } else if (view instanceof JcrBrowserView) + ((JcrBrowserView) view).refresh(null); // force full refresh + + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemovePrivileges.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemovePrivileges.java new file mode 100644 index 000000000..cd2618d5f --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemovePrivileges.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.security.Principal; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.security.AccessControlEntry; +import javax.jcr.security.AccessControlList; +import javax.jcr.security.AccessControlManager; +import javax.jcr.security.Privilege; + +import org.argeo.cms.ui.jcr.JcrImages; +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +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.jface.viewers.ISelection; +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.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.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Open a dialog to remove privileges from the selected node */ +public class RemovePrivileges extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".removePrivileges"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + TreeParent uiNode = null; + Node jcrNode = null; + + if (obj instanceof SingleJcrNodeElem) { + uiNode = (TreeParent) obj; + jcrNode = ((SingleJcrNodeElem) uiNode).getNode(); + } else if (obj instanceof WorkspaceElem) { + uiNode = (TreeParent) obj; + jcrNode = ((WorkspaceElem) uiNode).getRootNode(); + } else + return null; + + try { + String targetPath = jcrNode.getPath(); + Dialog dialog = new RemovePrivDialog( + HandlerUtil.getActiveShell(event), + jcrNode.getSession(), targetPath); + dialog.open(); + return null; + } catch (RepositoryException re) { + throw new EclipseUiException("Unable to retrieve " + + "path or JCR session to add privilege on " + jcrNode, + re); + } + } else { + ErrorFeedback.show("Cannot add privileges"); + } + return null; + } + + private class RemovePrivDialog extends TitleAreaDialog { + private static final long serialVersionUID = 280139710002698692L; + + private Composite body; + + private final String path; + private final Session session; + + public RemovePrivDialog(Shell parentShell, Session session, String path) { + super(parentShell); + this.session = session; + this.path = path; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Remove privileges"); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, + true)); + body = new Composite(dialogarea, SWT.NONE); + body.setLayoutData(EclipseUiUtils.fillAll()); + refreshContent(); + parent.pack(); + return body; + } + + private void refreshContent() { + EclipseUiUtils.clear(body); + try { + AccessControlManager acm = session.getAccessControlManager(); + AccessControlList acl = JcrUtils + .getAccessControlList(acm, path); + if (acl == null || acl.getAccessControlEntries().length <= 0) + setMessage("No privilege are defined on this node", + IMessageProvider.INFORMATION); + else { + body.setLayout(new GridLayout(3, false)); + for (AccessControlEntry ace : acl.getAccessControlEntries()) { + addOnePrivRow(body, ace); + } + setMessage("Remove some of the defined privileges", + IMessageProvider.INFORMATION); + } + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to list privileges on " + + path, e); + } + body.layout(true, true); + } + + private void addOnePrivRow(Composite parent, AccessControlEntry ace) { + Principal currentPrincipal = ace.getPrincipal(); + final String currPrincipalName = currentPrincipal.getName(); + new Label(parent, SWT.WRAP).setText(currPrincipalName); + new Label(parent, SWT.WRAP).setText(privAsString(ace + .getPrivileges())); + final Button rmBtn = new Button(parent, SWT.FLAT); + rmBtn.setImage(JcrImages.REMOVE); + + rmBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 7566938841363890730L; + + @Override + public void widgetSelected(SelectionEvent e) { + + if (MessageDialog.openConfirm(rmBtn.getShell(), + "Confirm deletion", + "Are you sure you want to remove this privilege?")) { + try { + session.save(); + JcrUtils.clearAccessControList(session, path, + currPrincipalName); + session.save(); + refreshContent(); + } catch (RepositoryException re) { + throw new EclipseUiException("Unable to " + + "remove privilege for " + + currPrincipalName + " on " + path, re); + } + } + + super.widgetSelected(e); + } + }); + + } + + private String privAsString(Privilege[] currentPrivileges) { + + StringBuilder builder = new StringBuilder(); + builder.append("[ "); + for (Privilege priv : currentPrivileges) { + builder.append(priv.getName()).append(", "); + } + if (builder.length() > 3) + return builder.substring(0, builder.length() - 2) + " ]"; + else + return "[]"; + + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemoveRemoteRepository.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemoveRemoteRepository.java new file mode 100644 index 000000000..c1be6ceea --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RemoveRemoteRepository.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import org.argeo.cms.ui.jcr.model.RemoteRepositoryElem; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Remove a registered remote repository */ +public class RemoveRemoteRepository extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getSelection(); + + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + + if (selection != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + + if (obj instanceof RemoteRepositoryElem) { + ((RemoteRepositoryElem) obj).remove(); + view.refresh(null); + } + } + return null; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RenameNode.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RenameNode.java new file mode 100644 index 000000000..7f4b55418 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/RenameNode.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import java.util.Iterator; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.dialogs.SingleValue; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * 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 extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".renameNode"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); + + ISelection selection = iwp.getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) + return null; + + Iterator lst = ((IStructuredSelection) selection).iterator(); + if (lst.hasNext()) { + Object element = lst.next(); + 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 + if (iwp.getActivePart() instanceof JcrBrowserView) + ((JcrBrowserView) iwp.getActivePart()).refresh(sjn); + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to rename " + node + " to " + newName, e); + } + } + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/SortChildNodes.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/SortChildNodes.java new file mode 100644 index 000000000..4b3d6f308 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/SortChildNodes.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.State; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Change isSorted state of the DataExplorer Browser */ +public class SortChildNodes extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".sortChildNodes"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + JcrBrowserView view = (JcrBrowserView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(JcrBrowserView.ID); + + ICommandService service = (ICommandService) PlatformUI.getWorkbench() + .getService(ICommandService.class); + Command command = service.getCommand(ID); + State state = command.getState(ID + ".toggleState"); + + boolean wasSorted = (Boolean) state.getValue(); + view.setSortChildNodes(!wasSorted); + state.setValue(!wasSorted); + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/UploadFiles.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/UploadFiles.java new file mode 100644 index 000000000..42d4b301b --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/UploadFiles.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.commands; + +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 javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.jcr.model.WorkspaceElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.JcrBrowserView; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Upload local file(s) under the currently selected node */ +public class UploadFiles extends AbstractHandler { + // private final static Log log = LogFactory.getLog(ImportFileSystem.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection(); + JcrBrowserView view = (JcrBrowserView) HandlerUtil.getActiveWorkbenchWindow(event).getActivePage() + .findView(HandlerUtil.getActivePartId(event)); + if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + try { + Node folder = null; + if (obj instanceof SingleJcrNodeElem) { + folder = ((SingleJcrNodeElem) obj).getNode(); + } else if (obj instanceof WorkspaceElem) { + folder = ((WorkspaceElem) obj).getRootNode(); + } else { + ErrorFeedback.show(WorkbenchUiPlugin.getMessage("warningInvalidNodeToImport")); + } + if (folder != null) { + FileDialog dialog = new FileDialog(HandlerUtil.getActiveShell(event), 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 null; + else { + loop: for (String name : names) { + Path path = Paths.get(name); + if (parPath != null) + path = parPath.resolve(path); + if (Files.exists(path)) { + URI uri = path.toUri(); + String uriStr = uri.toString(); + System.out.println(uriStr); + + if (Files.isDirectory(path)) { + MessageDialog.openError(HandlerUtil.getActiveShell(event), + "Unimplemented directory import", + "Upload of directories in the system is not yet implemented"); + continue loop; + } + Node fileNode = folder.addNode(path.getFileName().toString(), NodeType.NT_FILE); + Node resNode = fileNode.addNode(Property.JCR_CONTENT, NodeType.NT_RESOURCE); + Binary binary = null; + try (InputStream is = Files.newInputStream(path)) { + binary = folder.getSession().getValueFactory().createBinary(is); + resNode.setProperty(Property.JCR_DATA, binary); + } + folder.getSession().save(); + } else { + String msg = "Cannot upload file at " + path.toString(); + if (parPath != null) + msg += "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS"; + MessageDialog.openError(HandlerUtil.getActiveShell(event), "Missing file", msg); + continue loop; + } + } + view.nodeAdded((TreeParent) obj); + return true; + } + } + } + } catch (Exception e) { + ErrorFeedback.show("Cannot import files to " + obj, e); + } + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java new file mode 100644 index 000000000..3839a81c6 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AbstractJcrQueryEditor.java @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.query.QueryResult; +import javax.jcr.query.Row; +import javax.jcr.query.RowIterator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.GenericTableComparator; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +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.SashForm; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +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.TableColumn; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.EditorPart; + +/** Executes any JCR query. */ +public abstract class AbstractJcrQueryEditor extends EditorPart { + private final static Log log = LogFactory.getLog(AbstractJcrQueryEditor.class); + + protected String initialQuery; + protected String initialQueryType; + + /* DEPENDENCY INJECTION */ + private Session session; + + // Widgets + private TableViewer viewer; + private List tableViewerColumns = new ArrayList(); + private GenericTableComparator comparator; + + /** Override to layout a form enabling the end user to build his query */ + protected abstract void createQueryForm(Composite parent); + + @Override + public void init(IEditorSite site, IEditorInput input) throws PartInitException { + JcrQueryEditorInput editorInput = (JcrQueryEditorInput) input; + initialQuery = editorInput.getQuery(); + initialQueryType = editorInput.getQueryType(); + setSite(site); + setInput(editorInput); + } + + @Override + public final void createPartControl(final Composite parent) { + parent.setLayout(new FillLayout()); + + SashForm sashForm = new SashForm(parent, SWT.VERTICAL); + sashForm.setSashWidth(4); + sashForm.setLayout(new FillLayout()); + + Composite top = new Composite(sashForm, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + top.setLayout(gl); + + createQueryForm(top); + + Composite bottom = new Composite(sashForm, SWT.NONE); + bottom.setLayout(new GridLayout(1, false)); + sashForm.setWeights(getWeights()); + + viewer = new TableViewer(bottom); + viewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + viewer.getTable().setHeaderVisible(true); + viewer.setContentProvider(getQueryResultContentProvider()); + viewer.setInput(getEditorSite()); + + if (getComparator() != null) { + comparator = getComparator(); + viewer.setComparator(comparator); + } + if (getTableDoubleClickListener() != null) + viewer.addDoubleClickListener(getTableDoubleClickListener()); + + } + + protected void executeQuery(String statement) { + try { + if (log.isDebugEnabled()) + log.debug("Query : " + statement); + + QueryResult qr = session.getWorkspace().getQueryManager().createQuery(statement, initialQueryType) + .execute(); + + // remove previous columns + for (TableViewerColumn tvc : tableViewerColumns) + tvc.getColumn().dispose(); + + int i = 0; + for (final String columnName : qr.getColumnNames()) { + TableViewerColumn tvc = new TableViewerColumn(viewer, SWT.NONE); + configureColumn(columnName, tvc, i); + tvc.setLabelProvider(getLabelProvider(columnName)); + tableViewerColumns.add(tvc); + i++; + } + + // Must create a local list: QueryResults can only be read once. + try { + List rows = new ArrayList(); + RowIterator rit = qr.getRows(); + while (rit.hasNext()) { + rows.add(rit.nextRow()); + } + viewer.setInput(rows); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot read query result", e); + } + + } catch (RepositoryException e) { + ErrorDialog.openError(null, "Error", "Cannot execute JCR query: " + statement, + new Status(IStatus.ERROR, "org.argeo.eclipse.ui.jcr", e.getMessage())); + } + } + + /** + * To be overidden to adapt size of form and result frames. + * + * @return + */ + protected int[] getWeights() { + return new int[] { 30, 70 }; + } + + /** + * To be overidden to implement a doubleclick Listener on one of the rows of + * the table. + * + * @return + */ + protected IDoubleClickListener getTableDoubleClickListener() { + return null; + } + + /** + * To be overiden in order to implement a specific + * QueryResultContentProvider + */ + protected IStructuredContentProvider getQueryResultContentProvider() { + return new QueryResultContentProvider(); + } + + /** + * Enable specific implementation for columns + */ + protected List getTableViewerColumns() { + return tableViewerColumns; + } + + /** + * Enable specific implementation for columns + */ + protected TableViewer getTableViewer() { + return viewer; + } + + /** + * To be overridden in order to configure column label providers . + */ + protected ColumnLabelProvider getLabelProvider(final String columnName) { + return new ColumnLabelProvider() { + private static final long serialVersionUID = -3539689333250152606L; + + public String getText(Object element) { + Row row = (Row) element; + try { + return row.getValue(columnName).getString(); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot display row " + row, e); + } + } + + public Image getImage(Object element) { + return null; + } + }; + } + + /** + * To be overridden in order to configure the columns. + * + * @deprecated use + * {@link AbstractJcrQueryEditor#configureColumn(String, TableViewerColumn , int )} + * instead + */ + protected void configureColumn(String jcrColumnName, TableViewerColumn column) { + column.getColumn().setWidth(50); + column.getColumn().setText(jcrColumnName); + } + + /** To be overridden in order to configure the columns. */ + protected void configureColumn(String jcrColumnName, TableViewerColumn column, int columnIndex) { + column.getColumn().setWidth(50); + column.getColumn().setText(jcrColumnName); + } + + private class QueryResultContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -5421095459600554741L; + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object[] getElements(Object inputElement) { + + if (inputElement instanceof List) + return ((List) inputElement).toArray(); + + // Never reached might be deleted in future release + if (!(inputElement instanceof QueryResult)) + return new String[] {}; + + try { + QueryResult queryResult = (QueryResult) inputElement; + List rows = new ArrayList(); + RowIterator rit = queryResult.getRows(); + while (rit.hasNext()) { + rows.add(rit.nextRow()); + } + + // List elems = new ArrayList(); + // NodeIterator nit = queryResult.getNodes(); + // while (nit.hasNext()) { + // elems.add(nit.nextNode()); + // } + return rows.toArray(); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot read query result", e); + } + } + + } + + /** + * Might be used by children classes to sort columns. + * + * @param column + * @param index + * @return + */ + protected SelectionAdapter getSelectionAdapter(final TableColumn column, final int index) { + + // A comparator must be define + if (comparator == null) + return null; + + SelectionAdapter selectionAdapter = new SelectionAdapter() { + private static final long serialVersionUID = 239829307927778349L; + + @Override + public void widgetSelected(SelectionEvent e) { + + try { + + comparator.setColumn(index); + int dir = viewer.getTable().getSortDirection(); + if (viewer.getTable().getSortColumn() == column) { + dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; + } else { + + dir = SWT.DOWN; + } + viewer.getTable().setSortDirection(dir); + viewer.getTable().setSortColumn(column); + viewer.refresh(); + } catch (Exception exc) { + exc.printStackTrace(); + } + } + }; + return selectionAdapter; + } + + /** + * To be overridden to enable sorting. + */ + protected GenericTableComparator getComparator() { + return null; + } + + @Override + public boolean isDirty() { + return false; + } + + @Override + public void doSave(IProgressMonitor monitor) { + // TODO save the query in JCR? + } + + @Override + public void doSaveAs() { + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + /** Returns the injected current session */ + protected Session getSession() { + return session; + } + + /* DEPENDENCY INJECTION */ + public void setSession(Session session) { + this.session = session; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java new file mode 100644 index 000000000..6837a7d2a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/AddPrivilegeWizard.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.security.Privilege; + +import org.argeo.cms.ui.useradmin.PickUpUserDialog; +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.Wizard; +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.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.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Add JCR privileges to the chosen user group on a given node */ +public class AddPrivilegeWizard extends Wizard { + + // Context + private UserAdmin userAdmin; + private Session currentSession; + private String targetPath; + // Chosen parameters + private String chosenDn; + private User chosenUser; + private String jcrPrivilege; + + // UI Object + private DefinePrivilegePage page; + + // TODO enable external definition of possible values and corresponding + // description + protected static final Map AUTH_TYPE_LABELS; + static { + Map tmpMap = new HashMap(); + tmpMap.put(Privilege.JCR_READ, "jcr:read"); + tmpMap.put(Privilege.JCR_WRITE, "jcr:write"); + tmpMap.put(Privilege.JCR_ALL, "jcr:all"); + AUTH_TYPE_LABELS = Collections.unmodifiableMap(tmpMap); + } + + protected static final Map AUTH_TYPE_DESC; + static { + Map tmpMap = new HashMap(); + tmpMap.put(Privilege.JCR_READ, "The privilege to retrieve a node and get its properties and their values."); + tmpMap.put(Privilege.JCR_WRITE, "An aggregate privilege that " + + "contains: jcr:modifyProperties, jcr:addChildNodes, " + "jcr:removeNode, jcr:removeChildNodes"); + tmpMap.put(Privilege.JCR_ALL, "An aggregate privilege that " + "contains all JCR predefined privileges, " + + "plus all implementation-defined privileges. "); + AUTH_TYPE_DESC = Collections.unmodifiableMap(tmpMap); + } + + public AddPrivilegeWizard(Session currentSession, String path, UserAdmin userAdmin) { + super(); + this.userAdmin = userAdmin; + this.currentSession = currentSession; + this.targetPath = path; + } + + @Override + public void addPages() { + try { + setWindowTitle("Add privilege on " + targetPath); + page = new DefinePrivilegePage(userAdmin, targetPath); + addPage(page); + } catch (Exception e) { + throw new EclipseUiException("Cannot add page to wizard ", e); + } + } + + @Override + public boolean performFinish() { + if (!canFinish()) + return false; + try { + String username = chosenUser.getName(); + if (EclipseUiUtils.notEmpty(chosenDn) && chosenDn.equalsIgnoreCase(username)) + // Enable forcing the username case. TODO clean once this issue + // has been generally addressed + username = chosenDn; + JcrUtils.addPrivilege(currentSession, targetPath, username, jcrPrivilege); + } catch (RepositoryException re) { + throw new EclipseUiException( + "Cannot set " + jcrPrivilege + " for " + chosenUser.getName() + " on " + targetPath, re); + } + return true; + } + + private class DefinePrivilegePage extends WizardPage implements ModifyListener { + private static final long serialVersionUID = 8084431378762283920L; + + // Context + final private UserAdmin userAdmin; + + public DefinePrivilegePage(UserAdmin userAdmin, String path) { + super("Main"); + this.userAdmin = userAdmin; + setTitle("Define the privilege to apply to " + path); + setMessage("Please choose a user or a group and relevant JCR Privilege."); + } + + public void createControl(Composite parent) { + final Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(3, false)); + + // specify subject + createBoldLabel(composite, "User or group name"); + final Label userNameLbl = new Label(composite, SWT.LEAD); + userNameLbl.setLayoutData(EclipseUiUtils.fillWidth()); + + Link pickUpLk = new Link(composite, SWT.LEFT); + pickUpLk.setText(" Change "); + + createBoldLabel(composite, "User or group DN"); + final Text userNameTxt = new Text(composite, SWT.LEAD | SWT.BORDER); + userNameTxt.setLayoutData(EclipseUiUtils.fillWidth(2)); + + pickUpLk.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + PickUpUserDialog dialog = new PickUpUserDialog(getShell(), "Choose a group or a user", userAdmin); + if (dialog.open() == Window.OK) { + chosenUser = dialog.getSelected(); + userNameLbl.setText(UserAdminUtils.getCommonName(chosenUser)); + userNameTxt.setText(chosenUser.getName()); + } + } + }); + + userNameTxt.addFocusListener(new FocusListener() { + private static final long serialVersionUID = 1965498600105667738L; + + @Override + public void focusLost(FocusEvent event) { + String dn = userNameTxt.getText(); + if (EclipseUiUtils.isEmpty(dn)) + return; + + User newChosen = null; + try { + newChosen = (User) userAdmin.getRole(dn); + } catch (Exception e) { + boolean tryAgain = MessageDialog.openQuestion(getShell(), "Unvalid DN", + "DN " + dn + " is not valid.\nError message: " + e.getMessage() + + "\n\t\tDo you want to try again?"); + if (tryAgain) + userNameTxt.setFocus(); + else + resetOnFail(); + } + + if (userAdmin.getRole(dn) == null) { + boolean tryAgain = MessageDialog.openQuestion(getShell(), "Unexisting role", + "User/group " + dn + " does not exist. " + "Do you want to try again?"); + if (tryAgain) + userNameTxt.setFocus(); + else + resetOnFail(); + } else { + chosenUser = newChosen; + chosenDn = dn; + userNameLbl.setText(UserAdminUtils.getCommonName(chosenUser)); + } + } + + private void resetOnFail() { + String oldDn = chosenUser == null ? "" : chosenUser.getName(); + userNameTxt.setText(oldDn); + } + + @Override + public void focusGained(FocusEvent event) { + } + }); + + // JCR Privileges + createBoldLabel(composite, "Privilege type"); + Combo authorizationCmb = new Combo(composite, SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL); + authorizationCmb.setItems(AUTH_TYPE_LABELS.values().toArray(new String[0])); + authorizationCmb.setLayoutData(EclipseUiUtils.fillWidth(2)); + createBoldLabel(composite, ""); // empty cell + final Label descLbl = new Label(composite, SWT.WRAP); + descLbl.setLayoutData(EclipseUiUtils.fillWidth(2)); + + authorizationCmb.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + String chosenPrivStr = ((Combo) e.getSource()).getText(); + if (AUTH_TYPE_LABELS.containsValue(chosenPrivStr)) { + loop: for (String key : AUTH_TYPE_LABELS.keySet()) { + if (AUTH_TYPE_LABELS.get(key).equals(chosenPrivStr)) { + jcrPrivilege = key; + break loop; + } + } + } + + if (jcrPrivilege != null) { + descLbl.setText(AUTH_TYPE_DESC.get(jcrPrivilege)); + composite.layout(true, true); + } + } + }); + + // Compulsory + setControl(composite); + } + + public void modifyText(ModifyEvent event) { + String message = checkComplete(); + if (message != null) + setMessage(message, WizardPage.ERROR); + else { + setMessage("Complete", WizardPage.INFORMATION); + setPageComplete(true); + } + } + + /** @return error message or null if complete */ + protected String checkComplete() { + if (chosenUser == null) + return "Please choose a relevant group or user"; + else if (userAdmin.getRole(chosenUser.getName()) == null) + return "Please choose a relevant group or user"; + else if (jcrPrivilege == null) + return "Please choose a relevant JCR privilege"; + return null; + } + } + + private Label createBoldLabel(Composite parent, String value) { + Label label = new Label(parent, SWT.RIGHT); + label.setText(" " + value); + label.setFont(EclipseUiUtils.getBoldFont(parent)); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + return label; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChildNodesPage.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChildNodesPage.java new file mode 100644 index 000000000..eb8629278 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChildNodesPage.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import javax.jcr.Node; + +import org.argeo.cms.ui.jcr.JcrTreeContentProvider; +import org.argeo.cms.ui.jcr.NodeLabelProvider; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.jcr.DefaultNodeEditor; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** List all children of the current node */ +public class ChildNodesPage extends FormPage { + // private final static Log log = LogFactory.getLog(ChildNodesPage.class); + + private Node currentNode; + + private JcrTreeContentProvider nodeContentProvider; + private TreeViewer nodesViewer; + + public ChildNodesPage(FormEditor editor, String title, Node currentNode) { + super(editor, "ChildNodesPage", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + try { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin.getMessage("childNodesPageTitle")); + Composite innerBox = form.getBody(); + // Composite innerBox = new Composite(body, SWT.NO_FOCUS); + GridLayout twt = new GridLayout(1, false); + twt.marginWidth = twt.marginHeight = 5; + innerBox.setLayout(twt); + if (!currentNode.hasNodes()) { + managedForm.getToolkit().createLabel(innerBox, WorkbenchUiPlugin.getMessage("warningNoChildNode")); + } else { + nodeContentProvider = new JcrTreeContentProvider(); + nodesViewer = createNodeViewer(innerBox, nodeContentProvider); + nodesViewer.setInput(currentNode); + } + } catch (Exception e) { + throw new EclipseUiException("Cannot create children page for " + currentNode, e); + } + } + + protected TreeViewer createNodeViewer(Composite parent, final ITreeContentProvider nodeContentProvider) { + + final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.BORDER); + Tree tree = tmpNodeViewer.getTree(); + tree.setLinesVisible(true); + tmpNodeViewer.getTree().setLayoutData(EclipseUiUtils.fillAll()); + tmpNodeViewer.setContentProvider(nodeContentProvider); + tmpNodeViewer.setLabelProvider(new NodeLabelProvider()); + tmpNodeViewer.addDoubleClickListener(new DClickListener()); + return tmpNodeViewer; + } + + public class DClickListener implements IDoubleClickListener { + + public void doubleClick(DoubleClickEvent event) { + if (event.getSelection() == null || event.getSelection().isEmpty()) + return; + Object obj = ((IStructuredSelection) event.getSelection()).getFirstElement(); + if (obj instanceof Node) { + Node node = (Node) obj; + try { + GenericNodeEditorInput gnei = new GenericNodeEditorInput(node); + WorkbenchUiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage() + .openEditor(gnei, DefaultNodeEditor.ID); + } catch (PartInitException pie) { + throw new EclipseUiException("Cannot open editor for " + node, pie); + } + } + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChooseNameDialog.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChooseNameDialog.java new file mode 100644 index 000000000..080ea9485 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/ChooseNameDialog.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +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; +import org.eclipse.swt.widgets.Text; + +/** Ask end user for a name */ +public class ChooseNameDialog extends TitleAreaDialog { + private static final long serialVersionUID = 280139710002698692L; + private Text nameTxt; + + public ChooseNameDialog(Shell parentShell) { + super(parentShell); + setTitle("Choose name"); + } + + protected Point getInitialSize() { + return new Point(300, 250); + } + + 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)); + nameTxt = createLT(composite, "Name"); + setMessage("Choose name", IMessageProvider.INFORMATION); + parent.pack(); + nameTxt.setFocus(); + return composite; + } + + /** Creates label and text. */ + protected Text createLT(Composite parent, String label) { + 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, false)); + return text; + } + + public String getName() { + return nameTxt.getText(); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java new file mode 100644 index 000000000..43866945c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodeEditorInput.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** Editor input for {@link Node} editors */ +public class GenericNodeEditorInput implements IEditorInput { + private final Node currentNode; + + // Caches key properties at creation time to avoid Exception at recovering + // time when the session has been closed + private String path; + private String uid; + private String name; + + public GenericNodeEditorInput(Node currentNode) { + this.currentNode = currentNode; + try { + name = currentNode.getName(); + uid = currentNode.getIdentifier(); + path = currentNode.getPath(); + } catch (RepositoryException re) { + throw new EclipseUiException("Cannot cache the key properties for " + currentNode, re); + } + } + + public Node getCurrentNode() { + return currentNode; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return name; + } + + public String getUid() { + return uid; + } + + public String getToolTipText() { + return path; + } + + public String getPath() { + return path; + } + + public IPersistableElement getPersistable() { + return null; + } + + /** + * Equals method based on UID that is unique within a workspace and path of + * the node, thus 2 shared node that have same UID as defined in the spec + * but 2 different paths will open two distinct editors. + * + * TODO enhance this method to support multi repository and multi workspace + * environments + */ + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + GenericNodeEditorInput other = (GenericNodeEditorInput) obj; + if (!getUid().equals(other.getUid())) + return false; + if (!getPath().equals(other.getPath())) + return false; + return true; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodePage.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodePage.java new file mode 100644 index 000000000..2f2ec899a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericNodePage.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.ListIterator; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.CmsConstants; +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +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.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +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; + +/** + * Work-In-Progress Node editor page: provides edition feature on String + * properties for power users. TODO implement manual modification of all + * property types. + */ + +public class GenericNodePage extends FormPage implements WorkbenchConstants { + // private final static Log log = LogFactory.getLog(GenericNodePage.class); + + // local constants + private final static String JCR_PROPERTY_NAME = "jcr:name"; + + // Utils + protected DateFormat timeFormatter = new SimpleDateFormat(CmsConstants.DATE_TIME_FORMAT); + + // Main business Objects + private Node currentNode; + + // This page widgets + private FormToolkit tk; + private List modifyableProperties = new ArrayList(); + + public GenericNodePage(FormEditor editor, String title, Node currentNode) { + super(editor, "id", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + tk = managedForm.getToolkit(); + ScrolledForm form = managedForm.getForm(); + Composite innerBox = form.getBody(); + // Composite innerBox = new Composite(form.getBody(), SWT.NO_FOCUS); + GridLayout twt = new GridLayout(3, false); + innerBox.setLayout(twt); + createPropertiesPart(innerBox); + } + + private void createPropertiesPart(Composite parent) { + try { + AbstractFormPart part = new AbstractFormPart() { + public void commit(boolean onSave) { + try { + if (onSave) { + ListIterator it = modifyableProperties.listIterator(); + while (it.hasNext()) { + // we only support Text controls + Text curControl = (Text) it.next(); + String value = curControl.getText(); + currentNode.setProperty((String) curControl.getData(JCR_PROPERTY_NAME), value); + } + + // We only commit when onSave = true, + // thus it is still possible to save after a tab + // change. + if (currentNode.getSession().hasPendingChanges()) + currentNode.getSession().save(); + super.commit(onSave); + } + } catch (RepositoryException re) { + throw new EclipseUiException("Cannot save properties on " + currentNode, re); + } + } + }; + + PropertyIterator pi = currentNode.getProperties(); + while (pi.hasNext()) { + Property prop = pi.nextProperty(); + addPropertyLine(parent, part, prop); + } + getManagedForm().addPart(part); + } catch (RepositoryException re) { + throw new EclipseUiException("Cannot display properties for " + currentNode, re); + } + } + + private void addPropertyLine(Composite parent, AbstractFormPart part, Property prop) { + try { + tk.createLabel(parent, prop.getName()); + tk.createLabel(parent, "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]"); + + if (prop.getDefinition().isProtected()) { + tk.createLabel(parent, formatReadOnlyPropertyValue(prop)); + } else + addModifyableValueWidget(parent, part, prop); + } catch (RepositoryException re) { + throw new EclipseUiException("Cannot display property " + prop, re); + } + } + + private String formatReadOnlyPropertyValue(Property prop) throws RepositoryException { + String strValue; + if (prop.getType() == PropertyType.BINARY) + strValue = ""; + else if (prop.isMultiple()) + strValue = Arrays.asList(prop.getValues()).toString(); + else if (prop.getType() == PropertyType.DATE) + strValue = timeFormatter.format(prop.getValue().getDate().getTime()); + else + strValue = prop.getValue().getString(); + return strValue; + } + + private Control addModifyableValueWidget(Composite parent, AbstractFormPart part, Property prop) + throws RepositoryException { + GridData gd; + if (prop.getType() == PropertyType.STRING && !prop.isMultiple()) { + Text txt = tk.createText(parent, prop.getString(), SWT.WRAP | SWT.MULTI); + gd = new GridData(GridData.FILL_HORIZONTAL); + txt.setLayoutData(gd); + txt.addModifyListener(new ModifiedFieldListener(part)); + txt.setData(JCR_PROPERTY_NAME, prop.getName()); + modifyableProperties.add(txt); + } else { + // unsupported property type for editing, we create a read only + // label. + return tk.createLabel(parent, formatReadOnlyPropertyValue(prop)); + } + return null; + } + + private class ModifiedFieldListener implements ModifyListener { + private static final long serialVersionUID = 2117484480773434646L; + private AbstractFormPart formPart; + + public ModifiedFieldListener(AbstractFormPart generalPart) { + this.formPart = generalPart; + } + + public void modifyText(ModifyEvent e) { + formPart.markDirty(); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericPropertyPage.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericPropertyPage.java new file mode 100644 index 000000000..50f89625a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/GenericPropertyPage.java @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +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.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.layout.TreeColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +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.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** + * Generic editor property page. Lists all properties of current node as a + * complex tree. TODO: enable editing + */ +public class GenericPropertyPage extends FormPage implements WorkbenchConstants { + // private final static Log log = + // LogFactory.getLog(GenericPropertyPage.class); + + // Main business Objects + private Node currentNode; + + public GenericPropertyPage(FormEditor editor, String title, Node currentNode) { + super(editor, "id", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin.getMessage("genericNodePageTitle")); + Composite innerBox = form.getBody(); + //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(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 propList = new ArrayList(); + 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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java new file mode 100644 index 000000000..11256fe75 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/JcrQueryEditorInput.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import javax.jcr.query.Query; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +public class JcrQueryEditorInput implements IEditorInput { + private final String query; + private final String queryType; + + public JcrQueryEditorInput(String query, String queryType) { + this.query = query; + if (queryType == null) + this.queryType = Query.JCR_SQL2; + else + this.queryType = queryType; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return query; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return query; + } + + public String getQuery() { + return query; + } + + public String getQueryType() { + return queryType; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeEditorInput.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeEditorInput.java new file mode 100644 index 000000000..d51aeb3f2 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeEditorInput.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * A canonical editor input based on a path to a node. In a multirepository + * environment, path can be enriched with Repository Alias and workspace + */ + +public class NodeEditorInput implements IEditorInput { + private final String path; + + public NodeEditorInput(String path) { + this.path = path; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return path; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return path; + } + + public String getPath() { + return path; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java new file mode 100644 index 000000000..5aee1f351 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodePrivilegesPage.java @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Value; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +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.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +/** + * Display and edit a given node privilege. For the time being it is completely + * JackRabbit specific (and hard coded for this) and will display an empty page + * if using any other implementation + */ +public class NodePrivilegesPage extends FormPage { + + private Node context; + + private TableViewer viewer; + + public NodePrivilegesPage(FormEditor editor, String title, Node context) { + super(editor, "NodePrivilegesPage", title); + this.context = context; + } + + protected void createFormContent(IManagedForm managedForm) { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin.getMessage("nodeRightsManagementPageTitle")); + FillLayout layout = new FillLayout(); + layout.marginHeight = 5; + layout.marginWidth = 5; + form.getBody().setLayout(layout); + if (isJackRabbit()) + createRightsPart(form.getBody()); + } + + /** Creates the authorization part */ + protected void createRightsPart(Composite parent) { + Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + table.setLinesVisible(true); + table.setHeaderVisible(true); + viewer = new TableViewer(table); + + // Group / user name + TableViewerColumn column = createTableViewerColumn(viewer, "User/Group Name", 280); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -2290781173498395973L; + + public String getText(Object element) { + Node node = (Node) element; + try { + if (node.hasProperty("rep:principalName")) + return node.getProperty("rep:principalName").getString(); + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to retrieve " + "principal name on " + node, e); + } + return ""; + } + + public Image getImage(Object element) { + return null; + } + }); + + // Privileges + column = createTableViewerColumn(viewer, "Assigned privileges", 300); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -2290781173498395973L; + private String propertyName = "rep:privileges"; + + public String getText(Object element) { + Node node = (Node) element; + try { + if (node.hasProperty(propertyName)) { + String separator = ", "; + Value[] langs = node.getProperty(propertyName).getValues(); + StringBuilder builder = new StringBuilder(); + for (Value val : langs) { + String currStr = val.getString(); + builder.append(currStr).append(separator); + } + if (builder.lastIndexOf(separator) >= 0) + return builder.substring(0, builder.length() - separator.length()); + else + return builder.toString(); + + } + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to retrieve " + "privileges on " + node, e); + } + return ""; + } + + public Image getImage(Object element) { + return null; + } + }); + + // Relevant node + column = createTableViewerColumn(viewer, "Relevant node", 300); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = 4245522992038244849L; + + public String getText(Object element) { + Node node = (Node) element; + try { + return node.getParent().getParent().getPath(); + } catch (RepositoryException e) { + throw new EclipseUiException("Unable get path for " + node, e); + } + } + + public Image getImage(Object element) { + return null; + } + }); + + viewer.setContentProvider(new RightsContentProvider()); + viewer.setInput(getEditorSite()); + } + + protected TableViewerColumn createTableViewerColumn(TableViewer viewer, String title, int bound) { + TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE); + TableColumn column = viewerColumn.getColumn(); + column.setText(title); + column.setWidth(bound); + column.setResizable(true); + column.setMoveable(true); + return viewerColumn; + } + + private class RightsContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -7631476348552802706L; + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + // TODO JackRabbit specific retrieval of authorization. Clean and + // generalize + public Object[] getElements(Object inputElement) { + try { + List privs = new ArrayList(); + + Node currNode = context; + String currPath = currNode.getPath(); + + loop: while (true) { + if (currNode.hasNode("rep:policy")) { + NodeIterator nit = currNode.getNode("rep:policy").getNodes(); + while (nit.hasNext()) { + Node currPrivNode = nit.nextNode(); + if (currPrivNode.getName().startsWith("allow")) + privs.add(currPrivNode); + } + } + if ("/".equals(currPath)) + break loop; + else { + currNode = currNode.getParent(); + currPath = currNode.getPath(); + } + } + + // AccessControlManager acm = context.getSession() + // .getAccessControlManager(); + // AccessControlPolicyIterator acpi = acm + // .getApplicablePolicies(context.getPath()); + // + // List acps = new + // ArrayList(); + // try { + // while (true) { + // Object obj = acpi.next(); + // acps.add((AccessControlPolicy) obj); + // } + // } catch (Exception e) { + // // No more elements + // } + // + // AccessControlList acl = ((AccessControlList) acps.get(0)); + // AccessControlEntry[] entries = acl.getAccessControlEntries(); + + return privs.toArray(); + } catch (Exception e) { + throw new EclipseUiException("Cannot retrieve authorization for " + context, e); + } + } + } + + /** + * Simply checks if we are using jackrabbit without adding code dependencies + */ + private boolean isJackRabbit() { + try { + String cname = context.getSession().getClass().getName(); + return cname.startsWith("org.apache.jackrabbit"); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot check JCR implementation used on " + context, e); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java new file mode 100644 index 000000000..166ece9d8 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.jcr.Value; +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.cms.ui.CmsConstants; +import org.argeo.cms.ui.jcr.FullVersioningTreeContentProvider; +import org.argeo.cms.ui.jcr.JcrDClickListener; +import org.argeo.cms.ui.jcr.VersionLabelProvider; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.WorkbenchConstants; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +import org.argeo.jcr.PropertyDiff; +import org.argeo.jcr.VersionDiff; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +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.Text; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +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.eclipse.ui.forms.widgets.TableWrapData; +import org.eclipse.ui.forms.widgets.TableWrapLayout; + +/** + * Offers two main sections : one to display a text area with a summary of all + * variations between a version and its predecessor and one tree view that + * enable browsing + */ +public class NodeVersionHistoryPage extends FormPage implements WorkbenchConstants { + // private final static Log log = LogFactory + // .getLog(NodeVersionHistoryPage.class); + + // Utils + protected DateFormat timeFormatter = new SimpleDateFormat(CmsConstants.DATE_TIME_FORMAT); + + // business objects + private Node currentNode; + + // this page UI components + private FullVersioningTreeContentProvider nodeContentProvider; + private TreeViewer nodesViewer; + private FormToolkit tk; + + public NodeVersionHistoryPage(FormEditor editor, String title, Node currentNode) { + super(editor, "NodeVersionHistoryPage", title); + this.currentNode = currentNode; + } + + protected void createFormContent(IManagedForm managedForm) { + ScrolledForm form = managedForm.getForm(); + form.setText(WorkbenchUiPlugin.getMessage("nodeVersionHistoryPageTitle")); + tk = managedForm.getToolkit(); + Composite innerBox = form.getBody(); + // Composite innerBox = new Composite(body, SWT.NO_FOCUS); + GridLayout twt = new GridLayout(1, false); + twt.marginWidth = twt.marginHeight = 5; + innerBox.setLayout(twt); + try { + if (!currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) { + tk.createLabel(innerBox, WorkbenchUiPlugin.getMessage("warningUnversionableNode")); + } else { + createHistorySection(innerBox); + createTreeSection(innerBox); + } + } catch (RepositoryException e) { + throw new EclipseUiException("Unable to check if node is versionable", e); + } + } + + protected void createTreeSection(Composite parent) { + Section section = tk.createSection(parent, Section.TWISTIE); + section.setLayoutData(new GridData(GridData.FILL_BOTH)); + section.setText(WorkbenchUiPlugin.getMessage("versionTreeSectionTitle")); + + Composite body = tk.createComposite(section, SWT.FILL); + section.setClient(body); + section.setExpanded(true); + body.setLayoutData(new GridData(GridData.FILL_BOTH)); + body.setLayout(new GridLayout()); + + nodeContentProvider = new FullVersioningTreeContentProvider(); + nodesViewer = createNodeViewer(body, nodeContentProvider); + nodesViewer.setInput(currentNode); + } + + 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(new VersionLabelProvider()); + tmpNodeViewer.addDoubleClickListener(new JcrDClickListener(tmpNodeViewer)); + return tmpNodeViewer; + } + + protected void createHistorySection(Composite parent) { + + // Section Layout + Section section = tk.createSection(parent, Section.TWISTIE); + section.setLayoutData(new GridData(TableWrapData.FILL_GRAB)); + TableWrapLayout twt = new TableWrapLayout(); + section.setLayout(twt); + + // Set title of the section + section.setText(WorkbenchUiPlugin.getMessage("versionHistorySectionTitle")); + + final Text styledText = tk.createText(section, "", + SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); + section.setClient(styledText); + styledText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB)); + refreshHistory(styledText); + styledText.setEditable(false); + section.setExpanded(false); + + AbstractFormPart part = new AbstractFormPart() { + public void commit(boolean onSave) { + } + + public void refresh() { + super.refresh(); + refreshHistory(styledText); + } + }; + getManagedForm().addPart(part); + } + + protected void refreshHistory(Text styledText) { + try { + List lst = listHistoryDiff(); + StringBuffer main = new StringBuffer(""); + + for (int i = lst.size() - 1; i >= 0; i--) { + if (i == 0) + main.append("Creation ("); + else + main.append("Update " + i + " ("); + + if (lst.get(i).getUserId() != null) + main.append("UserId : " + lst.get(i).getUserId()); + + if (lst.get(i).getUserId() != null && lst.get(i).getUpdateTime() != null) + main.append(", "); + + if (lst.get(i).getUpdateTime() != null) + main.append("Date : " + timeFormatter.format(lst.get(i).getUpdateTime().getTime()) + ")\n"); + + StringBuffer buf = new StringBuffer(""); + Map diffs = lst.get(i).getDiffs(); + for (String prop : diffs.keySet()) { + PropertyDiff pd = diffs.get(prop); + // String propName = pd.getRelPath(); + Value refValue = pd.getReferenceValue(); + Value newValue = pd.getNewValue(); + String refValueStr = ""; + String newValueStr = ""; + + if (refValue != null) { + if (refValue.getType() == PropertyType.DATE) { + refValueStr = timeFormatter.format(refValue.getDate().getTime()); + } else + refValueStr = refValue.getString(); + } + if (newValue != null) { + if (newValue.getType() == PropertyType.DATE) { + newValueStr = timeFormatter.format(newValue.getDate().getTime()); + } else + newValueStr = newValue.getString(); + } + + if (pd.getType() == PropertyDiff.MODIFIED) { + buf.append(prop).append(": "); + buf.append(refValueStr); + buf.append(" > "); + buf.append(newValueStr); + buf.append("\n"); + } else if (pd.getType() == PropertyDiff.ADDED && !"".equals(newValueStr)) { + // we don't list property that have been added with an + // empty string as value + buf.append(prop).append(": "); + buf.append(" + "); + buf.append(newValueStr); + buf.append("\n"); + } else if (pd.getType() == PropertyDiff.REMOVED) { + buf.append(prop).append(": "); + buf.append(" - "); + buf.append(refValueStr); + buf.append("\n"); + } + } + buf.append("\n"); + main.append(buf); + } + styledText.setText(main.toString()); + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot generate history for node", e); + } + } + + public List listHistoryDiff() { + try { + List res = new ArrayList(); + VersionManager versionManager = currentNode.getSession().getWorkspace().getVersionManager(); + VersionHistory versionHistory = versionManager.getVersionHistory(currentNode.getPath()); + + VersionIterator vit = versionHistory.getAllLinearVersions(); + while (vit.hasNext()) { + Version version = vit.nextVersion(); + Node node = version.getFrozenNode(); + Version predecessor = null; + try { + predecessor = version.getLinearPredecessor(); + } catch (Exception e) { + // no predecessor seems to throw an exception even if it + // shouldn't... + } + if (predecessor == null) {// original + } else { + Map diffs = JcrUtils.diffProperties(predecessor.getFrozenNode(), node); + if (!diffs.isEmpty()) { + String lastUserName = null; + Calendar lastUpdate = null; + try { + if (currentNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) { + lastUserName = node.getProperty(Property.JCR_LAST_MODIFIED_BY).getString(); + lastUpdate = node.getProperty(Property.JCR_LAST_MODIFIED).getDate(); + } else + lastUpdate = version.getProperty(Property.JCR_CREATED).getDate(); + + } catch (Exception e) { + // Silent that info is optional + } + VersionDiff vd = new VersionDiff(lastUserName, lastUpdate, diffs); + res.add(vd); + } + } + } + return res; + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot generate history for node "); + } + + } + + @Override + public void setActive(boolean active) { + super.setActive(active); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java new file mode 100644 index 000000000..6aae94c28 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/StringNodeEditorInput.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.jcr.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * An editor input based on three strings define a node : + *
    + *
  • complete path to the node
  • + *
  • the workspace name
  • + *
  • the repository alias
  • + *
+ * In a single workspace and/or repository environment, name and alias can be + * null. + * + * Note : unused for the time being. + */ + +public class StringNodeEditorInput implements IEditorInput { + private final String path; + private final String repositoryAlias; + private final String workspaceName; + + /** + * In order to implement a generic explorer that supports remote and multi + * workspaces repositories, node path can be detailed by these strings. + * + * @param repositoryAlias + * : can be null + * @param workspaceName + * : can be null + * @param path + */ + public StringNodeEditorInput(String repositoryAlias, String workspaceName, + String path) { + this.path = path; + this.repositoryAlias = repositoryAlias; + this.workspaceName = workspaceName; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return path; + } + + public String getRepositoryAlias() { + return repositoryAlias; + } + + public String getWorkspaceName() { + return workspaceName; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return path; + } + + public String getPath() { + return path; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + StringNodeEditorInput other = (StringNodeEditorInput) obj; + + if (!path.equals(other.getPath())) + return false; + + String own = other.getWorkspaceName(); + if ((workspaceName == null && own != null) + || (workspaceName != null && (own == null || !workspaceName + .equals(own)))) + return false; + + String ora = other.getRepositoryAlias(); + if ((repositoryAlias == null && ora != null) + || (repositoryAlias != null && (ora == null || !repositoryAlias + .equals(ora)))) + return false; + + return true; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/PartStateChanged.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/PartStateChanged.java new file mode 100644 index 000000000..28e82c5d7 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/PartStateChanged.java @@ -0,0 +1,58 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import org.argeo.cms.CmsException; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IStartup; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; + +/** Manage transaction and part refresh while updating the security model */ +public class PartStateChanged implements IPartListener, IStartup { + // private final static Log log = LogFactory.getLog(PartStateChanged.class); + // private IContextActivation contextActivation; + + @Override + public void earlyStartup() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + try { + IWorkbenchPage iwp = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + if (iwp != null) + iwp.addPartListener(new PartStateChanged()); + } catch (Exception e) { + throw new CmsException( + "Error while registering the PartStateChangedListener", + e); + } + } + }); + } + + @Override + public void partActivated(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partClosed(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partOpened(IWorkbenchPart part) { + // Nothing to do + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/SecurityAdminImages.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/SecurityAdminImages.java new file mode 100644 index 000000000..816dead6e --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/SecurityAdminImages.java @@ -0,0 +1,46 @@ +/* + * Argeo Connect - Data management and communications + * Copyright (C) 2012 Argeo GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining it + * with software covered by the terms of the Eclipse Public License, the + * licensors of this Program grant you additional permission to convey the + * resulting work. Corresponding Source for a non-source form of such a + * combination shall include the source code for the parts of such software + * which are used as well as that of the covered work. + */ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import static org.argeo.cms.ui.workbench.WorkbenchUiPlugin.getImageDescriptor; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; + +/** Shared icons that must be declared programmatically . */ +public class SecurityAdminImages { + private final static String PREFIX = "icons/"; + + public final static ImageDescriptor ICON_REMOVE_DESC = getImageDescriptor(PREFIX + "delete.png"); + public final static ImageDescriptor ICON_USER_DESC = getImageDescriptor(PREFIX + "person.png"); + + public final static Image ICON_USER = ICON_USER_DESC.createImage(); + public final static Image ICON_GROUP = getImageDescriptor(PREFIX + "group.png").createImage(); + public final static Image ICON_WORKGROUP = getImageDescriptor(PREFIX + "workgroup.png").createImage(); + public final static Image ICON_ROLE = getImageDescriptor(PREFIX + "role.gif").createImage(); + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiAdminUtils.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiAdminUtils.java new file mode 100644 index 000000000..8f5588b76 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiAdminUtils.java @@ -0,0 +1,40 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import javax.transaction.UserTransaction; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTransactionProvider; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.services.ISourceProviderService; + +/** 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( + UserTransaction 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 this tip. + */ + 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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiUserAdminListener.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiUserAdminListener.java new file mode 100644 index 000000000..e51d69048 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UiUserAdminListener.java @@ -0,0 +1,27 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UserAdminWrapper.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UserAdminWrapper.java new file mode 100644 index 000000000..e4efcc72a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/UserAdminWrapper.java @@ -0,0 +1,127 @@ +package org.argeo.cms.ui.workbench.internal.useradmin; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.transaction.Status; +import javax.transaction.UserTransaction; + +import org.argeo.cms.CmsException; +import org.argeo.node.NodeConstants; +import org.argeo.osgi.useradmin.UserAdminConf; +import org.osgi.framework.ServiceReference; +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 userAdminServiceReference; + private UserTransaction userTransaction; + + // First effort to simplify UX while managing users and groups + public final static boolean COMMIT_ON_SAVE = true; + + // Registered listeners + List listeners = new ArrayList(); + + /** + * Starts a transaction if necessary. Should always been called together + * with {@link UserAdminWrapper#commitOrNotifyTransactionStateChange()} once + * the security model changes have been performed. + */ + public UserTransaction beginTransactionIfNeeded() { + try { + // UserTransaction userTransaction = getUserTransaction(); + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) { + 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.getStatus() == Status.STATUS_NO_TRANSACTION) + 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 getKnownBaseDns(boolean onlyWritable) { + Map dns = new HashMap(); + for (String uri : userAdminServiceReference.getPropertyKeys()) { + if (!uri.startsWith("/")) + continue; + Dictionary 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; + dns.put(baseDn, uri); + } + return dns; + } + + public UserAdmin getUserAdmin() { + return userAdmin; + } + + public UserTransaction getUserTransaction() { + return userTransaction; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } + + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } + + public void setUserAdminServiceReference( + ServiceReference userAdminServiceReference) { + this.userAdminServiceReference = userAdminServiceReference; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteGroups.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteGroups.java new file mode 100644 index 000000000..3e8d12fc2 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteGroups.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditorInput; +import org.argeo.cms.util.UserAdminUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; +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 extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".deleteGroups"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + @SuppressWarnings("unchecked") + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection.isEmpty()) + return null; + + List groups = new ArrayList(); + Iterator it = ((IStructuredSelection) selection).iterator(); + StringBuilder builder = new StringBuilder(); + while (it.hasNext()) { + Group currGroup = it.next(); + String groupName = UserAdminUtils.getUserLocalId(currGroup.getName()); + // TODO add checks + builder.append(groupName).append("; "); + groups.add(currGroup); + } + + if (!MessageDialog.openQuestion(HandlerUtil.getActiveShell(event), "Delete Groups", "Are you sure that you " + + "want to delete these groups?\n" + builder.substring(0, builder.length() - 2))) + return null; + + userAdminWrapper.beginTransactionIfNeeded(); + UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); + IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); + for (Group group : groups) { + 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 : groups) { + userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, group)); + } + + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteUsers.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteUsers.java new file mode 100644 index 000000000..ee366483a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/DeleteUsers.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditorInput; +import org.argeo.cms.util.UserAdminUtils; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; +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 extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".deleteUsers"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + @SuppressWarnings("unchecked") + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection.isEmpty()) + return null; + + Iterator it = ((IStructuredSelection) selection).iterator(); + List users = new ArrayList(); + StringBuilder builder = new StringBuilder(); + + while (it.hasNext()) { + User currUser = it.next(); + String userName = UserAdminUtils.getUserLocalId(currUser.getName()); + if (UserAdminUtils.isCurrentUser(currUser)) { + MessageDialog.openError(HandlerUtil.getActiveShell(event), "Deletion forbidden", + "You cannot delete your own user this way."); + return null; + } + builder.append(userName).append("; "); + users.add(currUser); + } + + if (!MessageDialog.openQuestion(HandlerUtil.getActiveShell(event), "Delete Users", + "Are you sure that you want to delete these users?\n" + builder.substring(0, builder.length() - 2))) + return null; + + userAdminWrapper.beginTransactionIfNeeded(); + UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); + IWorkbenchPage iwp = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); + + for (User user : users) { + 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 : users) { + userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, user)); + } + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/ForceRefresh.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/ForceRefresh.java new file mode 100644 index 000000000..86a2eedef --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/ForceRefresh.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import org.argeo.cms.ui.workbench.internal.useradmin.parts.GroupsView; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UsersView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Retrieve the active view or editor and call forceRefresh method if defined */ +public class ForceRefresh extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow iww = HandlerUtil.getActiveWorkbenchWindow(event); + if (iww == null) + return null; + IWorkbenchPage activePage = iww.getActivePage(); + IWorkbenchPart part = activePage.getActivePart(); + if (part instanceof UsersView) + ((UsersView) part).refresh(); + else if (part instanceof GroupsView) + ((GroupsView) part).refresh(); + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewGroup.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewGroup.java new file mode 100644 index 000000000..51a14fcbd --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewGroup.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import java.util.Dictionary; +import java.util.Map; + +import org.argeo.cms.ArgeoNames; +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.naming.LdapAttrs; +import org.argeo.osgi.useradmin.UserAdminConf; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +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.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; +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 extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newGroup"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + NewGroupWizard newGroupWizard = new NewGroupWizard(); + newGroupWizard.setWindowTitle("Group creation"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), 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, ArgeoNames { + 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 getDns() { + return userAdminWrapper.getKnownBaseDns(true); + } + + private String getDn(String cn) { + Map dns = getDns(); + String bdn = baseDnCmb.getText(); + if (EclipseUiUtils.notEmpty(bdn)) { + Dictionary props = UserAdminConf.uriAsProperties(dns + .get(bdn)); + String dn = LdapAttrs.cn.name() + "=" + cn + "," + + UserAdminConf.groupBase.getValue(props) + "," + bdn; + return dn; + } + return null; + } + + private void initialiseDnCmb(Combo combo) { + Map 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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewUser.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewUser.java new file mode 100644 index 000000000..94aa6352c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/NewUser.java @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import java.util.Dictionary; +import java.util.List; +import java.util.Map; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.argeo.cms.ArgeoNames; +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UiAdminUtils; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.naming.LdapAttrs; +import org.argeo.osgi.useradmin.UserAdminConf; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +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.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; +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 extends AbstractHandler { + // private final static Log log = LogFactory.getLog(NewUser.class); + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newUser"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + NewUserWizard newUserWizard = new NewUserWizard(); + newUserWizard.setWindowTitle("User creation"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), 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, ArgeoNames { + 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 getDns() { + return userAdminWrapper.getKnownBaseDns(true); + } + + private String getDn(String uid) { + Map dns = getDns(); + String bdn = baseDnCmb.getText(); + if (EclipseUiUtils.notEmpty(bdn)) { + Dictionary props = UserAdminConf.uriAsProperties(dns + .get(bdn)); + String dn = LdapAttrs.uid.name() + "=" + uid + "," + + UserAdminConf.userBase.getValue(props) + "," + bdn; + return dn; + } + return null; + } + + private void initialiseDnCmb(Combo combo) { + Map 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 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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/SaveArgeoUser.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/SaveArgeoUser.java new file mode 100644 index 000000000..ef1ddbdbd --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/SaveArgeoUser.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Save the currently edited Argeo user. */ +public class SaveArgeoUser extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".saveArgeoUser"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + IWorkbenchPart iwp = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage().getActivePart(); + if (!(iwp instanceof IEditorPart)) + return null; + IEditorPart editor = (IEditorPart) iwp; + editor.doSave(null); + } catch (Exception e) { + MessageDialog.openError(Display.getDefault().getActiveShell(), + "Error", "Cannot save user: " + e.getMessage()); + } + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserBatchUpdate.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserBatchUpdate.java new file mode 100644 index 000000000..7d29e8f5a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserBatchUpdate.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserBatchUpdateWizard; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Launch a wizard to perform batch process on users */ +public class UserBatchUpdate extends AbstractHandler { + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper uaWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + UserBatchUpdateWizard wizard = new UserBatchUpdateWizard(uaWrapper); + wizard.setWindowTitle("User batch processing"); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(event), wizard); + dialog.open(); + return null; + } + + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.uaWrapper = userAdminWrapper; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserTransactionHandler.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserTransactionHandler.java new file mode 100644 index 000000000..69fd0711a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/commands/UserTransactionHandler.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.commands; + +import javax.transaction.Status; +import javax.transaction.UserTransaction; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.UiAdminUtils; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Manage the transaction that is bound to the current perspective */ +public class UserTransactionHandler extends AbstractHandler { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".userTransactionHandler"; + + public final static String PARAM_COMMAND_ID = "param.commandId"; + + public final static String TRANSACTION_BEGIN = "transaction.begin"; + public final static String TRANSACTION_COMMIT = "transaction.commit"; + public final static String TRANSACTION_ROLLBACK = "transaction.rollback"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + public Object execute(ExecutionEvent event) throws ExecutionException { + String commandId = event.getParameter(PARAM_COMMAND_ID); + final UserTransaction userTransaction = userAdminWrapper + .getUserTransaction(); + try { + if (TRANSACTION_BEGIN.equals(commandId)) { + if (userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION) + throw new CmsException("A transaction already exists"); + else + userTransaction.begin(); + } else if (TRANSACTION_COMMIT.equals(commandId)) { + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + throw new CmsException("No transaction."); + else + userTransaction.commit(); + } else if (TRANSACTION_ROLLBACK.equals(commandId)) { + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + throw new CmsException("No transaction to rollback."); + else { + userTransaction.rollback(); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, + UserAdminEvent.ROLE_CHANGED, null)); + } + } + + UiAdminUtils.notifyTransactionStateChange(userTransaction); + // Try to remove invalid thread access errors when managing users. + // HandlerUtil.getActivePart(event).getSite().getShell().getDisplay() + // .asyncExec(new Runnable() { + // @Override + // public void run() { + // UiAdminUtils + // .notifyTransactionStateChange(userTransaction); + // } + // }); + + } catch (CmsException e) { + throw e; + } catch (Exception e) { + throw new CmsException("Unable to call " + commandId + " on " + + userTransaction, e); + } + return null; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/ArgeoUserEditorInput.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/ArgeoUserEditorInput.java new file mode 100644 index 000000000..71089f690 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/ArgeoUserEditorInput.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** Editor input for an Argeo user. */ +public class ArgeoUserEditorInput implements IEditorInput { + private final String username; + + public ArgeoUserEditorInput(String username) { + this.username = username; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return username != null; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return username != null ? username : ""; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return username != null ? username : ""; + } + + public boolean equals(Object obj) { + if (!(obj instanceof ArgeoUserEditorInput)) + return false; + if (((ArgeoUserEditorInput) obj).getUsername() == null) + return false; + return ((ArgeoUserEditorInput) obj).getUsername().equals(username); + } + + public String getUsername() { + return username; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupMainPage.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupMainPage.java new file mode 100644 index 000000000..6987a217d --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupMainPage.java @@ -0,0 +1,523 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.parts; + +import static org.argeo.cms.util.UserAdminUtils.setProperty; +import static org.argeo.naming.LdapAttrs.businessCategory; +import static org.argeo.naming.LdapAttrs.description; +import static org.argeo.node.NodeInstance.WORKGROUP; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.transaction.UserTransaction; + +import org.argeo.cms.ArgeoNames; +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.CmsWorkbenchStyles; +import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.GroupChangeListener; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.MainInfoListener; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.MailLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.RoleIconLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserFilter; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener; +import org.argeo.cms.util.CmsUtils; +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.jcr.JcrUtils; +import org.argeo.naming.LdapAttrs; +import org.argeo.node.NodeInstance; +import org.argeo.node.NodeUtils; +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.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +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.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.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 main properties of a given group */ +public class GroupMainPage extends FormPage implements ArgeoNames { + final static String ID = "GroupEditor.mainPage"; + + private final UserEditor editor; + private final NodeInstance nodeInstance; + private final UserAdminWrapper userAdminWrapper; + private final Session session; + + 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 + public void dispose() { + JcrUtils.logoutQuietly(session); + super.dispose(); + } + + /** Creates the general section */ + protected void appendOverviewPart(final Composite parent, final Group group) { + FormToolkit tk = getManagedForm().getToolkit(); + Composite body = addSection(tk, parent); + // GridLayout layout = new GridLayout(5, false); + GridLayout layout = new GridLayout(2, false); + body.setLayout(layout); + + String cn = UserAdminUtils.getProperty(group, LdapAttrs.cn.name()); + createReadOnlyLT(body, "Name", cn); + // Text dnTxt = 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, false, false, 2, 1)); + final Text descTxt = new Text(body, SWT.LEAD | SWT.MULTI | SWT.WRAP | SWT.BORDER); + GridData gd = EclipseUiUtils.fillAll(); + 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 SectionPart((Section) body.getParent()) { + + private MainInfoListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.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 = NodeUtils.getGroupHome(session, cn); + if (workgroupHome == null) + markAsWorkgroupLk.setText("Mark as workgroup"); + 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 = NodeUtils.getGroupHome(session, cn); + if (workgroupHome != null) + return; // already marked as workgroup, do nothing + else + try { + // improve transaction management + userAdminWrapper.beginTransactionIfNeeded(); + nodeInstance.createWorkgroup(new LdapName(group.getName())); + setProperty(group, businessCategory, WORKGROUP); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + userAdminWrapper + .notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group)); + part.refresh(); + } catch (InvalidNameException e1) { + throw new CmsException("Cannot create Workgroup for " + group.toString(), e1); + } + + } + } + }); + + ModifyListener defaultListener = editor.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) { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = tk.createSection(parent, Section.TITLE_BAR); + section.setText("Members"); + section.setLayoutData(EclipseUiUtils.fillAll()); + + Composite body = new Composite(section, SWT.NO_FOCUS); + section.setClient(body); + body.setLayoutData(EclipseUiUtils.fillAll()); + + LdifUsersTable userTableViewerCmp = createMemberPart(body, group); + + SectionPart part = new GroupMembersPart(section, userTableViewerCmp); + getManagedForm().addPart(part); + addRemoveAbitily(part, userTableViewerCmp.getTableViewer(), group); + } + + public LdifUsersTable createMemberPart(Composite parent, Group group) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + // Define the displayed columns + List columnDefs = new ArrayList(); + 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()); + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + userViewer.addDropSupport(operations, tt, + new GroupDropListener(userAdminWrapper, userViewerCmp, (Group) editor.getDisplayedUser())); + + 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 listFilteredElements(String filter) { + // reload user and set it in the editor + Group group = (Group) editor.getDisplayedUser(); + Role[] roles = group.getMembers(); + List users = new ArrayList(); + 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 addRemoveAbitily(SectionPart sectionPart, TableViewer userViewer, Group group) { + Section section = sectionPart.getSection(); + ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); + ToolBar toolbar = toolBarManager.createControl(section); + final Cursor handCursor = new Cursor(section.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 it = ((IStructuredSelection) selection).iterator(); + List users = new ArrayList(); + 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 SectionPart { + private final LdifUsersTable userViewer; + // private final Group group; + + private GroupChangeListener listener; + + public GroupMembersPart(Section section, LdifUsersTable userViewer) { + super(section); + this.userViewer = userViewer; + // this.group = group; + } + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.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 myMemberships = editor.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 newGroupMemberships = editor.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 + UserTransaction transaction = userAdminWrapper.beginTransactionIfNeeded(); + User user = (User) role; + myGroup.addMember(user); + if (UserAdminWrapper.COMMIT_ON_SAVE) + try { + transaction.commit(); + } catch (Exception e) { + throw new CmsException("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)); + // CmsUtils.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); + CmsUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT); + return text; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupsView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupsView.java new file mode 100644 index 000000000..453fa7d55 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/GroupsView.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.ArgeoNames; +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.CurrentUser; +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.naming.LdapAttrs; +import org.argeo.naming.LdapObjs; +import org.argeo.node.NodeConstants; +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 extends ViewPart implements ArgeoNames { + private final static Log log = LogFactory.getLog(GroupsView.class); + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".groupsView"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + // UI Objects + private LdifUsersTable groupTableViewerCmp; + private TableViewer userViewer; + private List columnDefs = new ArrayList(); + + private UserAdminListener listener; + + @Override + public void createPartControl(Composite parent) { + 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()); + getViewSite().setSelectionProvider(userViewer); + + // 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(NodeConstants.ROLE_ADMIN); + } + + protected void populateStaticFilters(Composite staticFilterCmp) { + staticFilterCmp.setLayout(new GridLayout()); + final Button showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); + showSystemRoleBtn.setText("Show system roles"); + showSystemRoles = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); + 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 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(")"); + if (!showSystemRoles) + builder.append("(!(").append(LdapAttrs.DN).append("=*").append(NodeConstants.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(NodeConstants.ROLES_BASEDN).append(")))"); + else + builder.append("(").append(LdapAttrs.objectClass.name()).append("=") + .append(LdapObjs.groupOfNames.name()).append(")"); + + } + roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString()); + } catch (InvalidSyntaxException e) { + throw new CmsException("Unable to get roles with filter: " + filter, e); + } + List users = new ArrayList(); + 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(); + } + + // Override generic view methods + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @Override + public void setFocus() { + groupTableViewerCmp.setFocus(); + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserBatchUpdateWizard.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserBatchUpdateWizard.java new file mode 100644 index 000000000..7e3540f76 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserBatchUpdateWizard.java @@ -0,0 +1,627 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.transaction.SystemException; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.workbench.internal.useradmin.UiAdminUtils; +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.MailLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserNameLP; +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.naming.LdapAttrs; +import org.argeo.naming.LdapObjs; +import org.argeo.node.NodeConstants; +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 Log log = LogFactory.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 commands = new HashMap() { + 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; + UserTransaction ut = userAdminWrapper.getUserTransaction(); + try { + if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION + && !MessageDialog.openConfirm(getShell(), "Existing Transaction", + "A user transaction is already existing, " + "are you sure you want to proceed ?")) + return false; + } catch (SystemException e) { + throw new CmsException("Cannot get user transaction state " + "before user batch update", e); + } + + // 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 usersToUpdate; + + public ResetPassword(UserAdminWrapper userAdminWrapper, List 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 { + 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(); + } + } + } + } + + private class ResetEmail { + private String newEmail; + private UserAdminWrapper userAdminWrapper; + private List usersToUpdate; + + public ResetEmail(UserAdminWrapper userAdminWrapper, List 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 { + 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 block, the system might be in a dirty state"); + e.printStackTrace(); + } + } + } + } + + // @SuppressWarnings("unused") + // private class AddToGroup extends UpdateJob { + // private String groupID; + // private Session session; + // + // public AddToGroup(Session session, List 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 usersToUpdate; + // + // protected abstract void doUpdate(User user); + // + // public UpdateJob(UserAdminWrapper userAdminWrapper, + // List 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 columnDefs = new ArrayList(); + 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(NodeConstants.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 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 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 users = new ArrayList(); + 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 columnDefs = new ArrayList(); + 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(NodeConstants.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 listFilteredElements(String filter) { + return userListPage.getSelectedUsers(); + } + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditor.java new file mode 100644 index 000000000..a1e5c627f --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditor.java @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Repository; + +import org.argeo.cms.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.util.UserAdminUtils; +import org.argeo.naming.LdapAttrs; +import org.argeo.node.NodeInstance; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.editor.FormEditor; +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 class UserEditor extends FormEditor { + private static final long serialVersionUID = 8357851520380820241L; + + public final static String USER_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID + ".userEditor"; + public final static String GROUP_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID + ".groupEditor"; + + /* DEPENDENCY INJECTION */ + private Repository repository; + private UserAdminWrapper userAdminWrapper; + private UserAdmin userAdmin; + private NodeInstance nodeInstance; + + // Context + private User user; + private String username; + + private NameChangeListener listener; + + public void init(IEditorSite site, IEditorInput input) throws PartInitException { + super.init(site, input); + this.userAdmin = userAdminWrapper.getUserAdmin(); + username = ((UserEditorInput) getEditorInput()).getUsername(); + user = (User) userAdmin.getRole(username); + + listener = new NameChangeListener(site.getShell().getDisplay()); + userAdminWrapper.addListener(listener); + updateEditorTitle(null); + } + + /** + * returns the list of all authorization for the given user or of the current + * displayed user if parameter is null + */ + protected List getFlatGroups(User aUser) { + Authorization currAuth; + if (aUser == null) + currAuth = userAdmin.getAuthorization(this.user); + else + currAuth = userAdmin.getAuthorization(aUser); + + String[] roles = currAuth.getRoles(); + + List groups = new ArrayList(); + for (String roleStr : roles) { + User currRole = (User) userAdmin.getRole(roleStr); + if (currRole != null && !groups.contains(currRole)) + groups.add(currRole); + } + return groups; + } + + /** 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 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); + } + } + + @Override + public void doSave(IProgressMonitor monitor) { + userAdminWrapper.beginTransactionIfNeeded(); + commitPages(true); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + firePropertyChange(PROP_DIRTY); + userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, user)); + } + + @Override + public void doSaveAs() { + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + // CONTROLERS FOR THIS EDITOR AND ITS PAGES + + private 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; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setNodeInstance(NodeInstance nodeInstance) { + this.nodeInstance = nodeInstance; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditorInput.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditorInput.java new file mode 100644 index 000000000..1e7ee4b10 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserEditorInput.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.parts; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * Editor input for an user defined by unique name (usually a distinguished + * name). + */ +public class UserEditorInput implements IEditorInput { + private final String username; + + public UserEditorInput(String username) { + this.username = username; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return username != null; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return username != null ? username : ""; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return username != null ? username : ""; + } + + public boolean equals(Object obj) { + if (!(obj instanceof UserEditorInput)) + return false; + if (((UserEditorInput) obj).getUsername() == null) + return false; + return ((UserEditorInput) obj).getUsername().equals(username); + } + + public String getUsername() { + return username; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserMainPage.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserMainPage.java new file mode 100644 index 000000000..04111c4a8 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UserMainPage.java @@ -0,0 +1,571 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.parts; + +import static org.argeo.cms.util.UserAdminUtils.getProperty; +import static org.argeo.naming.LdapAttrs.cn; +import static org.argeo.naming.LdapAttrs.givenName; +import static org.argeo.naming.LdapAttrs.mail; +import static org.argeo.naming.LdapAttrs.sn; +import static org.argeo.naming.LdapAttrs.uid; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.argeo.cms.ArgeoNames; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.workbench.CmsWorkbenchStyles; +import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages; +import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.GroupChangeListener; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor.MainInfoListener; +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.UserFilter; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener; +import org.argeo.cms.util.CmsUtils; +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.naming.LdapAttrs; +import org.argeo.node.NodeConstants; +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.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +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.graphics.Cursor; +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.Link; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +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.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 UserMainPage extends FormPage implements ArgeoNames { + final static String ID = "UserEditor.mainPage"; + + 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); + } + + /** 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 = tk.createComposite(section, SWT.WRAP); + body.setLayoutData(EclipseUiUtils.fillAll()); + section.setClient(body); + // body.setLayout(new GridLayout(6, false)); + body.setLayout(new GridLayout(2, false)); + + Text commonName = createReadOnlyLT(tk, body, "Name", getProperty(user, cn)); + Text distinguishedName = createReadOnlyLT(tk, body, "Login", getProperty(user, uid)); + Text firstName = createLT(tk, body, "First name", getProperty(user, givenName)); + Text lastName = createLT(tk, body, "Last name", getProperty(user, sn)); + Text email = createLT(tk, body, "Email", getProperty(user, mail)); + + Link resetPwdLk = new Link(body, SWT.NONE); + if (!UserAdminUtils.isCurrentUser(user)) { + resetPwdLk.setText("Reset password"); + } + resetPwdLk.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); + + // create form part (controller) + AbstractFormPart part = new SectionPart((Section) body.getParent()) { + private MainInfoListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.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); + editor.updateEditorTitle(cn); + } + }; + firstName.addModifyListener(cnML); + lastName.addModifyListener(cnML); + + ModifyListener defaultListener = editor.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(tk, 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(FormToolkit tk, 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(tk, body, "New password", ""); + password2 = createLP(tk, 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) { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = addSection(tk, parent, "Roles"); + Composite body = (Composite) section.getClient(); + body.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + // boolean isAdmin = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); + + // Displayed columns + List columnDefs = new ArrayList(); + 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()); + 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); + + SectionPart part = new SectionPart((Section) body.getParent()) { + + private GroupChangeListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = editor.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(part, userViewer, user); + 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(NodeConstants.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 listFilteredElements(String filter) { + List users = (List) editor.getFlatGroups(null); + List filteredUsers = new ArrayList(); + 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 addRemoveAbitily(SectionPart sectionPart, TableViewer userViewer, User user) { + Section section = sectionPart.getSection(); + ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); + ToolBar toolbar = toolBarManager.createControl(section); + final Cursor handCursor = new Cursor(section.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(); + } + } + }); + + 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 it = ((IStructuredSelection) selection).iterator(); + List groups = new ArrayList(); + 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; + } + + /** Creates label and multiline text. */ + Text createLMT(FormToolkit toolkit, Composite body, String label, String value) { + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + return text; + } + + /** Creates label and password. */ + Text createLP(FormToolkit toolkit, Composite body, String label, String value) { + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + /** Creates label and text. */ + Text createLT(FormToolkit toolkit, Composite parent, String label, String value) { + 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)); + CmsUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT); + return text; + } + + Text createReadOnlyLT(FormToolkit toolkit, Composite parent, String label, String value) { + 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); + CmsUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT); + return text; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UsersView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UsersView.java new file mode 100644 index 000000000..4a3b1572e --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/parts/UsersView.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.internal.useradmin.parts; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.cms.ArgeoNames; +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.CurrentUser; +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.MailLP; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserDragListener; +import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserNameLP; +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.naming.LdapAttrs; +import org.argeo.naming.LdapObjs; +import org.argeo.node.NodeConstants; +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.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 users with filter - based on Ldif userAdmin */ +public class UsersView extends ViewPart implements ArgeoNames { + // private final static Log log = LogFactory.getLog(UsersView.class); + + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".usersView"; + + /* DEPENDENCY INJECTION */ + private UserAdminWrapper userAdminWrapper; + + // UI Objects + private LdifUsersTable userTableViewerCmp; + private TableViewer userViewer; + private List columnDefs = new ArrayList(); + + private UserAdminListener listener; + + @Override + public void createPartControl(Composite parent) { + + 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(NodeConstants.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()); + 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 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 users = new ArrayList(); + 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 + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @Override + public void setFocus() { + userTableViewerCmp.setFocus(); + } + + /* DEPENDENCY INJECTION */ + public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { + this.userAdminWrapper = userAdminWrapper; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/CommonNameLP.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/CommonNameLP.java new file mode 100644 index 000000000..cbe6b6a1c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/CommonNameLP.java @@ -0,0 +1,21 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/DomainNameLP.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/DomainNameLP.java new file mode 100644 index 000000000..eee16fb54 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/DomainNameLP.java @@ -0,0 +1,14 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.util.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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/MailLP.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/MailLP.java new file mode 100644 index 000000000..3e4ff2c2f --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/MailLP.java @@ -0,0 +1,15 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/RoleIconLP.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/RoleIconLP.java new file mode 100644 index 000000000..d7e25c645 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/RoleIconLP.java @@ -0,0 +1,35 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages; +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.naming.LdapAttrs; +import org.argeo.node.NodeConstants; +import org.argeo.node.NodeInstance; +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(NodeConstants.ROLES_BASEDN)) + return SecurityAdminImages.ICON_ROLE; + else if (user.getType() == Role.GROUP) { + String businessCategory = UserAdminUtils.getProperty(user, LdapAttrs.businessCategory); + if (businessCategory != null && businessCategory.equals(NodeInstance.WORKGROUP)) + return SecurityAdminImages.ICON_WORKGROUP; + return SecurityAdminImages.ICON_GROUP; + } else + return SecurityAdminImages.ICON_USER; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserAdminAbstractLP.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserAdminAbstractLP.java new file mode 100644 index 000000000..45c053635 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserAdminAbstractLP.java @@ -0,0 +1,66 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; + +import org.argeo.cms.CmsException; +import org.argeo.cms.util.UserAdminUtils; +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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserDragListener.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserDragListener.java new file mode 100644 index 000000000..46b9d1594 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserDragListener.java @@ -0,0 +1,40 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserFilter.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserFilter.java new file mode 100644 index 000000000..46bce8d76 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserFilter.java @@ -0,0 +1,58 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; + +import org.argeo.cms.util.UserAdminUtils; +import org.argeo.naming.LdapAttrs; +import org.argeo.node.NodeConstants; +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(".*(" + NodeConstants.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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserNameLP.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserNameLP.java new file mode 100644 index 000000000..0d8e8505b --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserNameLP.java @@ -0,0 +1,13 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.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/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTableDefaultDClickListener.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTableDefaultDClickListener.java new file mode 100644 index 000000000..a25163b15 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTableDefaultDClickListener.java @@ -0,0 +1,43 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditor; +import org.argeo.cms.ui.workbench.internal.useradmin.parts.UserEditorInput; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +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 { + public void doubleClick(DoubleClickEvent evt) { + if (evt.getSelection().isEmpty()) + return; + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + User user = (User) obj; + IWorkbenchWindow iww = WorkbenchUiPlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow(); + IWorkbenchPage iwp = iww.getActivePage(); + UserEditorInput uei = new UserEditorInput(user.getName()); + + try { + // Works around the fact that dynamic setting of the editor icon + // causes NPE after a login/logout on RAP + if (user instanceof Group) + iwp.openEditor(uei, UserEditor.GROUP_EDITOR_ID); + else + iwp.openEditor(uei, UserEditor.USER_EDITOR_ID); + } catch (PartInitException pie) { + throw new CmsException("Unable to open UserEditor for " + user, pie); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTransactionProvider.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTransactionProvider.java new file mode 100644 index 000000000..a53cfb2df --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/useradmin/providers/UserTransactionProvider.java @@ -0,0 +1,74 @@ +package org.argeo.cms.ui.workbench.internal.useradmin.providers; + +import java.util.HashMap; +import java.util.Map; + +import javax.transaction.Status; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.ui.AbstractSourceProvider; +import org.eclipse.ui.ISources; + +/** Observe and notify UI on UserTransaction state changes */ +public class UserTransactionProvider extends AbstractSourceProvider { + private final static Log log = LogFactory + .getLog(UserTransactionProvider.class); + + public final static String TRANSACTION_STATE = WorkbenchUiPlugin.PLUGIN_ID + + ".userTransactionState"; + public final static String STATUS_ACTIVE = "status.active"; + public final static String STATUS_NO_TRANSACTION = "status.noTransaction"; + + /* DEPENDENCY INJECTION */ + private UserTransaction userTransaction; + + @Override + public String[] getProvidedSourceNames() { + return new String[] { TRANSACTION_STATE }; + } + + @Override + public Map getCurrentState() { + Map currentState = new HashMap(1); + currentState.put(TRANSACTION_STATE, getInternalCurrentState()); + return currentState; + } + + @Override + public void dispose() { + } + + private String getInternalCurrentState() { + try { + String transactionState; + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + transactionState = STATUS_NO_TRANSACTION; + else + // if (userTransaction.getStatus() == Status.STATUS_ACTIVE) + transactionState = STATUS_ACTIVE; + return transactionState; + } catch (Exception e) { + throw new CmsException("Unable to begin transaction", e); + } + } + + /** Publishes the ability to notify a state change */ + public void fireTransactionStateChange() { + try { + fireSourceChanged(ISources.WORKBENCH, TRANSACTION_STATE, + getInternalCurrentState()); + } catch (Exception e) { + log.warn("Cannot fire transaction state change event. Caught exception: " + + e.getClass().getCanonicalName() + " - " + e.getMessage()); + } + } + + /* DEPENDENCY INJECTION */ + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/DefaultNodeEditor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/DefaultNodeEditor.java new file mode 100644 index 000000000..e502dd462 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/DefaultNodeEditor.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.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.security.AccessControlManager; +import javax.jcr.security.Privilege; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.ChildNodesPage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericNodeEditorInput; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericNodePage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericPropertyPage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodePrivilegesPage; +import org.argeo.cms.ui.workbench.internal.jcr.parts.NodeVersionHistoryPage; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.editor.FormEditor; + +/** Default form editor for a Jcr {@link Node} */ +public class DefaultNodeEditor extends FormEditor { + private static final long serialVersionUID = 8322127770921612239L; + + // private final static Log log = + // LogFactory.getLog(GenericNodeEditor.class); + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".defaultNodeEditor"; + + private Node currentNode; + + private GenericNodePage genericNodePage; + private GenericPropertyPage genericPropertyPage; + private ChildNodesPage childNodesPage; + private NodePrivilegesPage nodeRightsManagementPage; + private NodeVersionHistoryPage nodeVersionHistoryPage; + + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + super.init(site, input); + GenericNodeEditorInput nei = (GenericNodeEditorInput) getEditorInput(); + currentNode = nei.getCurrentNode(); + this.setPartName(JcrUtils.lastPathElement(nei.getPath())); + } + + @Override + protected void addPages() { + try { + genericPropertyPage = new GenericPropertyPage(this, + WorkbenchUiPlugin.getMessage("genericNodePageTitle"), + currentNode); + addPage(genericPropertyPage); + + childNodesPage = new ChildNodesPage(this, + WorkbenchUiPlugin.getMessage("childNodesPageTitle"), + currentNode); + addPage(childNodesPage); + + AccessControlManager accessControlManager = currentNode + .getSession().getAccessControlManager(); + List privileges = new ArrayList(); + privileges.add(accessControlManager + .privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL)); + if (accessControlManager.hasPrivileges(currentNode.getPath(), + privileges.toArray(new Privilege[0]))) { + nodeRightsManagementPage = new NodePrivilegesPage(this, + WorkbenchUiPlugin + .getMessage("nodeRightsManagementPageTitle"), + currentNode); + addPage(nodeRightsManagementPage); + } + if (currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) { + nodeVersionHistoryPage = new NodeVersionHistoryPage(this, + WorkbenchUiPlugin + .getMessage("nodeVersionHistoryPageTitle"), + currentNode); + addPage(nodeVersionHistoryPage); + } + + privileges = new ArrayList(); + privileges.add(accessControlManager + .privilegeFromName(Privilege.JCR_ALL)); + if (accessControlManager.hasPrivileges(currentNode.getPath(), + privileges.toArray(new Privilege[0]))) { + genericNodePage = new GenericNodePage( + this, + WorkbenchUiPlugin.getMessage("propertyEditorPageTitle"), + currentNode); + addPage(genericNodePage); + } + + } catch (RepositoryException e) { + throw new EclipseUiException("Cannot get node info for " + + currentNode, e); + } catch (PartInitException e) { + throw new EclipseUiException("Cannot add page " + + "on node editor for " + currentNode, e); + } + } + + @Override + public void doSaveAs() { + // unused compulsory method + } + + @Override + public void doSave(IProgressMonitor monitor) { + try { + // Automatically commit all pages of the editor + commitPages(true); + firePropertyChange(PROP_DIRTY); + } catch (Exception e) { + throw new EclipseUiException("Error while saving node", e); + } + + } + + @Override + public boolean isSaveAsAllowed() { + return true; + } + + Node getCurrentNode() { + return currentNode; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/GenericJcrQueryEditor.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/GenericJcrQueryEditor.java new file mode 100644 index 000000000..7c7f2b97b --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/GenericJcrQueryEditor.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.jcr; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.AbstractJcrQueryEditor; +import org.eclipse.swt.SWT; +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.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +/** Enables end user to type and execute any JCR query. */ +public class GenericJcrQueryEditor extends AbstractJcrQueryEditor { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + ".genericJcrQueryEditor"; + + private Text queryField; + + @Override + public void createQueryForm(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + + queryField = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.WRAP); + queryField.setText(initialQuery); + queryField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Button execute = new Button(parent, SWT.PUSH); + execute.setText("Execute"); + + Listener executeListener = new Listener() { + private static final long serialVersionUID = -918256291554301699L; + + public void handleEvent(Event event) { + executeQuery(queryField.getText()); + } + }; + + execute.addListener(SWT.Selection, executeListener); + // queryField.addListener(SWT.DefaultSelection, executeListener); + } + + @Override + public void setFocus() { + queryField.setFocus(); + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrBrowserView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrBrowserView.java new file mode 100644 index 000000000..f84950b91 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/JcrBrowserView.java @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.jcr; + +import java.util.List; + +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.cms.ui.jcr.DefaultRepositoryRegister; +import org.argeo.cms.ui.jcr.JcrBrowserUtils; +import org.argeo.cms.ui.jcr.JcrDClickListener; +import org.argeo.cms.ui.jcr.NodeContentProvider; +import org.argeo.cms.ui.jcr.NodeLabelProvider; +import org.argeo.cms.ui.jcr.PropertiesContentProvider; +import org.argeo.cms.ui.jcr.RepositoryRegister; +import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.eclipse.ui.jcr.AsyncUiEventListener; +import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer; +import org.argeo.node.security.Keyring; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ColumnLabelProvider; +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.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.part.ViewPart; + +/** + * Basic View to display a sash form to browse a JCR compliant multiple + * repository environment + */ +public class JcrBrowserView extends ViewPart { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".jcrBrowserView"; + private boolean sortChildNodes = true; + + /* DEPENDENCY INJECTION */ + private Keyring keyring; + private RepositoryRegister repositoryRegister = new DefaultRepositoryRegister(); + private RepositoryFactory repositoryFactory; + private Repository nodeRepository; + + // Current user session on the "Argeo node" default workspace + private Session userSession; + + // This page widgets + private TreeViewer nodesViewer; + private NodeContentProvider nodeContentProvider; + private TableViewer propertiesViewer; + private EventListener resultsObserver; + + @Override + public void createPartControl(Composite parent) { + 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(gl); + + try { + this.userSession = this.nodeRepository.login(); + } catch (RepositoryException e) { + throw new EclipseUiException("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); + getSite().registerContextMenu(menuManager, nodesViewer); + getSite().setSelectionProvider(nodesViewer); + + nodesViewer.setInput(getViewSite()); + + // Create the property viewer on the bottom + Composite bottom = new Composite(sashForm, SWT.NONE); + bottom.setLayout(new GridLayout(1, false)); + propertiesViewer = createPropertiesViewer(bottom); + + sashForm.setWeights(getWeights()); + nodesViewer.setComparer(new NodeViewerComparer()); + } + + 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(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(getViewSite()); + } + } + }); + + 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); + 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 ""; + 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(getViewSite()); + return propertiesViewer; + } + + @Override + public void dispose() { + super.dispose(); + } + + 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(getViewSite()); + } + + /** 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 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 events) throws RepositoryException { + if (getLog().isTraceEnabled()) + getLog().trace("Refresh result list"); + nodesViewer.refresh(); + } + + } + + public boolean getSortChildNodes() { + return sortChildNodes; + } + + @Override + public void setFocus() { + getNodeViewer().getTree().setFocus(); + } + + /* DEPENDENCY INJECTION */ + public void setRepositoryRegister(RepositoryRegister repositoryRegister) { + this.repositoryRegister = repositoryRegister; + } + + public void setKeyring(Keyring keyring) { + this.keyring = keyring; + } + + public void setRepositoryFactory(RepositoryFactory repositoryFactory) { + this.repositoryFactory = repositoryFactory; + } + + public void setNodeRepository(Repository nodeRepository) { + this.nodeRepository = nodeRepository; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java new file mode 100644 index 000000000..cba228f2d --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.jcr; + +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.Path; +import java.nio.file.spi.FileSystemProvider; + +import org.argeo.cms.CmsException; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.fs.SimpleFsBrowser; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +/** Browse the node file system. */ +public class NodeFsBrowserView extends ViewPart { + public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".nodeFsBrowserView"; + + private FileSystemProvider nodeFileSystemProvider; + + @Override + public void createPartControl(Composite parent) { + try { + URI uri = new URI("node:///"); + FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri); + if (fileSystem == null) + fileSystem = nodeFileSystemProvider.newFileSystem(uri, null); + Path nodePath = fileSystem.getPath("~"); + SimpleFsBrowser browser = new SimpleFsBrowser(parent, SWT.NO_FOCUS); + browser.setInput(nodePath); + } catch (Exception e) { + throw new CmsException("Cannot open file system browser", e); + } + } + + @Override + public void setFocus() { + } + + public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) { + this.nodeFileSystemProvider = nodeFileSystemProvider; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/WorkbenchJcrDClickListener.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/WorkbenchJcrDClickListener.java new file mode 100644 index 000000000..37feeb7c3 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/WorkbenchJcrDClickListener.java @@ -0,0 +1,101 @@ +package org.argeo.cms.ui.workbench.jcr; + +import static javax.jcr.Node.JCR_CONTENT; +import static javax.jcr.Property.JCR_DATA; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.apache.commons.io.IOUtils; +import org.argeo.cms.ui.jcr.JcrDClickListener; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.cms.ui.workbench.internal.jcr.parts.GenericNodeEditorInput; +import org.argeo.cms.ui.workbench.util.CommandUtils; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.specific.OpenFile; +import org.argeo.eclipse.ui.specific.SingleSourcingException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.jface.viewers.TreeViewer; + +public class WorkbenchJcrDClickListener extends JcrDClickListener { + + public WorkbenchJcrDClickListener(TreeViewer nodeViewer) { + super(nodeViewer); + } + + @Override + protected void openNode(Node node) { + try { + if (node.isNodeType(NodeType.NT_FILE)) { + // Also open it + + String name = node.getName(); + Map params = new HashMap(); + params.put(OpenFile.PARAM_FILE_NAME, name); + + // TODO rather directly transmit the path to the node, once + // we have defined convention to provide an Absolute URI to + // a node in a multi repo / workspace / user context + // params.put(OpenFile.PARAM_FILE_URI, + // OpenFileService.JCR_SCHEME + node.getPath()); + + // we copy the node to a tmp file to be opened as a dirty + // workaround + File tmpFile = null; + // OutputStream os = null; + // InputStream is = null; + int i = name.lastIndexOf('.'); + String prefix, suffix; + if (i == -1) { + prefix = name; + suffix = null; + } else { + prefix = name.substring(0, i); + suffix = name.substring(i); + } + Binary binary = null; + try { + tmpFile = File.createTempFile(prefix, suffix); + tmpFile.deleteOnExit(); + } catch (IOException e1) { + throw new EclipseUiException("Cannot create temp file", e1); + } + try (OutputStream os = new FileOutputStream(tmpFile)) { + binary = node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary(); + try (InputStream is = binary.getStream();) { + IOUtils.copy(is, os); + } + } catch (IOException e) { + throw new SingleSourcingException("Cannot open file " + prefix + "." + suffix, e); + } finally { + // IOUtils.closeQuietly(is); + // IOUtils.closeQuietly(os); + JcrUtils.closeQuietly(binary); + } + Path path = Paths.get(tmpFile.getAbsolutePath()); + String uri = path.toUri().toString(); + params.put(OpenFile.PARAM_FILE_URI, uri); + CommandUtils.callCommand(OpenFile.ID, params); + } + GenericNodeEditorInput gnei = new GenericNodeEditorInput(node); + WorkbenchUiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(gnei, + DefaultNodeEditor.ID); + } catch (RepositoryException re) { + throw new EclipseUiException("Repository error while getting node info", re); + } catch (Exception pie) { + throw new EclipseUiException("Unexpected exception while opening node editor", pie); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/messages.properties b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/messages.properties new file mode 100644 index 000000000..9994a5a1e --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/messages.properties @@ -0,0 +1,29 @@ +## English labels for Agreo JCR UI application + +## Generic labels + +## Errors & warnings +errorUnvalidNtFolderNodeType= Error: folder can only be created on a Jcr Node +warningInvalidNodeToImport=Can only import to a node +warningInvalidMultipleSelection=This functionality is implemented only on a single node for the time being. +warningUnversionableNode= Current node is not versionable. +warningNoChildNode= Current node has no child. + +## Commands +getNodeSizeCmdLbl= Get approx. size +addFolderNodeCmdLbl= Add Folder + +## GenericNodeEditor +nodeEditorLbl=Generic node editor +genericNodePageTitle=Properties +childNodesPageTitle=Children +nodeRightsManagementPageTitle=Effective privileges +nodeVersionHistoryPageTitle=History +propertyEditorPageTitle=Properties Editor (Experimental) + +# History +versionTreeSectionTitle=Version list +versionHistorySectionTitle=History + +## Dummy ones +testLbl=Internationalizations of messages seems to work properly. diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundleNode.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundleNode.java new file mode 100644 index 000000000..6dd9ac423 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundleNode.java @@ -0,0 +1,46 @@ +package org.argeo.cms.ui.workbench.osgi; + +import org.argeo.eclipse.ui.TreeParent; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +/** A tree element representing a {@link Bundle} */ +class BundleNode extends TreeParent { + private final Bundle bundle; + + public BundleNode(Bundle bundle) { + this(bundle, false); + } + + @SuppressWarnings("rawtypes") + public BundleNode(Bundle bundle, boolean hasChildren) { + super(bundle.getSymbolicName()); + this.bundle = bundle; + + if (hasChildren) { + // REFERENCES + ServiceReference[] usedServices = bundle.getServicesInUse(); + if (usedServices != null) { + for (ServiceReference sr : usedServices) { + if (sr != null) + addChild(new ServiceReferenceNode(sr, false)); + } + } + + // SERVICES + ServiceReference[] registeredServices = bundle + .getRegisteredServices(); + if (registeredServices != null) { + for (ServiceReference sr : registeredServices) { + if (sr != null) + addChild(new ServiceReferenceNode(sr, true)); + } + } + } + + } + + Bundle getBundle() { + return bundle; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundlesView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundlesView.java new file mode 100644 index 000000000..4032e785c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/BundlesView.java @@ -0,0 +1,126 @@ +//package org.argeo.eclipse.ui.workbench.osgi; +//public class BundlesView {} + +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.osgi; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.ColumnViewerComparator; +import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +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.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Overview of the bundles as a table. Equivalent to Equinox 'ss' console + * command. + */ +public class BundlesView extends ViewPart { + private TableViewer viewer; + + @Override + public void createPartControl(Composite parent) { + viewer = new TableViewer(parent); + viewer.setContentProvider(new BundleContentProvider()); + viewer.getTable().setHeaderVisible(true); + + EclipseUiSpecificUtils.enableToolTipSupport(viewer); + + // ID + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(30); + column.getColumn().setText("ID"); + column.getColumn().setAlignment(SWT.RIGHT); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -3122136344359358605L; + + public String getText(Object element) { + return Long.toString(((Bundle) element).getBundleId()); + } + }); + new ColumnViewerComparator(column); + + // State + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(18); + column.getColumn().setText("State"); + column.setLabelProvider(new StateLabelProvider()); + new ColumnViewerComparator(column); + + // Symbolic name + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(250); + column.getColumn().setText("Symbolic Name"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -4280840684440451080L; + + public String getText(Object element) { + return ((Bundle) element).getSymbolicName(); + } + }); + new ColumnViewerComparator(column); + + // Version + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(150); + column.getColumn().setText("Version"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = 6871926308708629989L; + + public String getText(Object element) { + Bundle bundle = (org.osgi.framework.Bundle) element; + return bundle.getVersion().toString(); + } + }); + new ColumnViewerComparator(column); + + viewer.setInput(WorkbenchUiPlugin.getDefault().getBundle().getBundleContext()); + + } + + @Override + public void setFocus() { + if (viewer != null) + viewer.getControl().setFocus(); + } + + /** Content provider managing the array of bundles */ + private static class BundleContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -8533792785725875977L; + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof BundleContext) { + BundleContext bc = (BundleContext) inputElement; + return bc.getBundles(); + } + return null; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/CmsSessionsView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/CmsSessionsView.java new file mode 100644 index 000000000..44b554ed1 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/CmsSessionsView.java @@ -0,0 +1,186 @@ +//package org.argeo.eclipse.ui.workbench.osgi; +//public class BundlesView {} + +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.osgi; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.naming.ldap.LdapName; + +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.CmsSession; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.ColumnViewerComparator; +import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; +import org.argeo.util.LangUtils; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +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.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +/** + * Overview of the active CMS sessions. + */ +public class CmsSessionsView extends ViewPart { + private TableViewer viewer; + + @Override + public void createPartControl(Composite parent) { + viewer = new TableViewer(parent); + viewer.setContentProvider(new CmsSessionContentProvider()); + viewer.getTable().setHeaderVisible(true); + + EclipseUiSpecificUtils.enableToolTipSupport(viewer); + + int longColWidth = 150; + int smallColWidth = 100; + + // Display name + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(longColWidth); + column.getColumn().setText("User"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return ((CmsSession) element).getAuthorization().toString(); + } + + public String getToolTipText(Object element) { + return ((CmsSession) element).getUserDn().toString(); + } + }); + new ColumnViewerComparator(column); + + // Creation time + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("Since"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return LangUtils.since(((CmsSession) element).getCreationTime()); + } + + public String getToolTipText(Object element) { + return ((CmsSession) element).getCreationTime().toString(); + } + }); + new ColumnViewerComparator(column); + + // Username + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("Username"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + LdapName userDn = ((CmsSession) element).getUserDn(); + return userDn.getRdn(userDn.size() - 1).getValue().toString(); + } + + public String getToolTipText(Object element) { + return ((CmsSession) element).getUserDn().toString(); + } + }); + new ColumnViewerComparator(column); + + // UUID + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("UUID"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return ((CmsSession) element).getUuid().toString(); + } + + public String getToolTipText(Object element) { + return getText(element); + } + }); + new ColumnViewerComparator(column); + + // Local ID + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("Local ID"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return ((CmsSession) element).getLocalId(); + } + + public String getToolTipText(Object element) { + return getText(element); + } + }); + new ColumnViewerComparator(column); + + viewer.setInput(WorkbenchUiPlugin.getDefault().getBundle().getBundleContext()); + + } + + @Override + public void setFocus() { + if (viewer != null) + viewer.getControl().setFocus(); + } + + /** Content provider managing the array of bundles */ + private static class CmsSessionContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -8533792785725875977L; + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof BundleContext) { + BundleContext bc = (BundleContext) inputElement; + Collection> srs; + try { + srs = bc.getServiceReferences(CmsSession.class, null); + } catch (InvalidSyntaxException e) { + throw new CmsException("Cannot retrieve CMS sessions", e); + } + List res = new ArrayList<>(); + for (ServiceReference sr : srs) { + res.add(bc.getService(sr)); + } + return res.toArray(); + } + return null; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ModulesView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ModulesView.java new file mode 100644 index 000000000..235261a58 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ModulesView.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.osgi; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.TreeParent; +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.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** The OSGi runtime from a module perspective. */ +public class ModulesView extends ViewPart { + private TreeViewer viewer; + + @Override + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(new ModulesContentProvider()); + viewer.setLabelProvider(new ModulesLabelProvider()); + viewer.setInput(WorkbenchUiPlugin.getDefault().getBundle() + .getBundleContext()); + } + + @Override + public void setFocus() { + viewer.getTree().setFocus(); + } + + private class ModulesContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = 3819934804640641721L; + + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof BundleContext) { + BundleContext bundleContext = (BundleContext) parentElement; + Bundle[] bundles = bundleContext.getBundles(); + + List modules = new ArrayList(); + for (Bundle bundle : bundles) { + if (bundle.getState() == Bundle.ACTIVE) + modules.add(new BundleNode(bundle, true)); + } + return modules.toArray(); + } else if (parentElement instanceof TreeParent) { + return ((TreeParent) parentElement).getChildren(); + } else { + return null; + } + } + + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof TreeParent) { + return ((TreeParent) element).hasChildren(); + } + return false; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + private class ModulesLabelProvider extends StateLabelProvider { + private static final long serialVersionUID = 5290046145534824722L; + + @Override + public String getText(Object element) { + if (element instanceof BundleNode) + return element.toString() + " [" + + ((BundleNode) element).getBundle().getBundleId() + + "]"; + return element.toString(); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/MultiplePackagesView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/MultiplePackagesView.java new file mode 100644 index 000000000..a7f9a5335 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/MultiplePackagesView.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.osgi; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.TreeParent; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.packageadmin.ExportedPackage; +import org.osgi.service.packageadmin.PackageAdmin; + +/** Experimental The OSGi runtime from a module perspective. */ +@SuppressWarnings({ "deprecation", "rawtypes", "unchecked" }) +public class MultiplePackagesView extends ViewPart { + private TreeViewer viewer; + private PackageAdmin packageAdmin; + private Comparator epc = new Comparator() { + public int compare(ExportedPackage o1, ExportedPackage o2) { + if (!o1.getName().equals(o2.getName())) + return o1.getName().compareTo(o2.getName()); + else + return o1.getVersion().compareTo(o2.getVersion()); + } + }; + + @Override + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(new ModulesContentProvider()); + viewer.setLabelProvider(new LabelProvider()); + viewer.setInput(WorkbenchUiPlugin.getDefault().getBundle() + .getBundleContext()); + } + + @Override + public void setFocus() { + viewer.getTree().setFocus(); + } + + private class ModulesContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = 3819934804640641721L; + + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof BundleContext) { + BundleContext bundleContext = (BundleContext) parentElement; + Bundle[] bundles = bundleContext.getBundles(); + + // scan packages + ServiceReference paSr = bundleContext + .getServiceReference(PackageAdmin.class.getName()); + // TODO: make a cleaner referencing + packageAdmin = (PackageAdmin) bundleContext.getService(paSr); + + Map> imported = new HashMap>(); + Map> packages = new TreeMap>(); + for (Bundle bundle : bundles) { + processBundle(bundle, imported, packages); + } + + List multiplePackages = new ArrayList(); + for (String packageName : packages.keySet()) { + Set pkgs = packages.get(packageName); + if (pkgs.size() > 1) { + MultiplePackagesNode mpn = new MultiplePackagesNode( + packageName, pkgs); + multiplePackages.add(mpn); + } + } + + return multiplePackages.toArray(); + } else if (parentElement instanceof TreeParent) { + return ((TreeParent) parentElement).getChildren(); + } else { + return null; + } + } + + protected void processBundle(Bundle bundle, + Map> imported, + Map> packages) { + ExportedPackage[] pkgs = packageAdmin.getExportedPackages(bundle); + if (pkgs == null) + return; + for (ExportedPackage pkg : pkgs) { + if (!packages.containsKey(pkg.getName())) + packages.put(pkg.getName(), new TreeSet( + epc)); + Set expPackages = packages.get(pkg.getName()); + expPackages.add(pkg); + + // imported + for (Bundle b : pkg.getImportingBundles()) { + if (bundle.getBundleId() != b.getBundleId()) { + if (!imported.containsKey(b)) { + imported.put(b, new TreeSet(epc)); + } + Set impPackages = imported.get(b); + impPackages.add(pkg); + } + } + } + } + + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof TreeParent) { + return ((TreeParent) element).hasChildren(); + } + return false; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + private class MultiplePackagesNode extends TreeParent { + public MultiplePackagesNode(String packageName, + Set exportedPackages) { + super(packageName); + for (ExportedPackage pkg : exportedPackages) { + addChild(new ExportedPackageNode(pkg)); + } + } + } + + private class ExportedPackageNode extends TreeParent { + public ExportedPackageNode(ExportedPackage exportedPackage) { + super(exportedPackage.getName() + " - " + + exportedPackage.getVersion() + " (" + + exportedPackage.getExportingBundle() + ")"); + for (Bundle bundle : exportedPackage.getImportingBundles()) { + addChild(new BundleNode(bundle, true)); + } + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/OsgiExplorerImages.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/OsgiExplorerImages.java new file mode 100644 index 000000000..1233e11e6 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/OsgiExplorerImages.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.osgi; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.swt.graphics.Image; + +/** Shared icons. */ +public class OsgiExplorerImages { + public final static Image INSTALLED = WorkbenchUiPlugin.getImageDescriptor( + "icons/installed.gif").createImage(); + public final static Image RESOLVED = WorkbenchUiPlugin.getImageDescriptor( + "icons/resolved.gif").createImage(); + public final static Image STARTING = WorkbenchUiPlugin.getImageDescriptor( + "icons/starting.gif").createImage(); + public final static Image ACTIVE = WorkbenchUiPlugin.getImageDescriptor( + "icons/active.gif").createImage(); + public final static Image SERVICE_PUBLISHED = WorkbenchUiPlugin + .getImageDescriptor("icons/service_published.gif").createImage(); + public final static Image SERVICE_REFERENCED = WorkbenchUiPlugin + .getImageDescriptor("icons/service_referenced.gif").createImage(); +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ServiceReferenceNode.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ServiceReferenceNode.java new file mode 100644 index 000000000..6b4972d6d --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/ServiceReferenceNode.java @@ -0,0 +1,46 @@ +package org.argeo.cms.ui.workbench.osgi; + +import org.argeo.eclipse.ui.TreeParent; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +/** A tree element representing a {@link ServiceReference} */ +@SuppressWarnings({ "rawtypes" }) +class ServiceReferenceNode extends TreeParent { + private final ServiceReference serviceReference; + private final boolean published; + + public ServiceReferenceNode(ServiceReference serviceReference, + boolean published) { + super(serviceReference.toString()); + this.serviceReference = serviceReference; + this.published = published; + + if (isPublished()) { + Bundle[] usedBundles = serviceReference.getUsingBundles(); + if (usedBundles != null) { + for (Bundle b : usedBundles) { + if (b != null) + addChild(new BundleNode(b)); + } + } + } else { + Bundle provider = serviceReference.getBundle(); + addChild(new BundleNode(provider)); + } + + for (String key : serviceReference.getPropertyKeys()) { + addChild(new TreeParent(key + "=" + + serviceReference.getProperty(key))); + } + + } + + public ServiceReference getServiceReference() { + return serviceReference; + } + + public boolean isPublished() { + return published; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/StateLabelProvider.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/StateLabelProvider.java new file mode 100644 index 000000000..86b67c396 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/osgi/StateLabelProvider.java @@ -0,0 +1,82 @@ +package org.argeo.cms.ui.workbench.osgi; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.graphics.Image; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; + +/** Label provider showing the sate of bundles */ +class StateLabelProvider extends ColumnLabelProvider { + private static final long serialVersionUID = -7885583135316000733L; + + @Override + public Image getImage(Object element) { + int state; + if (element instanceof Bundle) + state = ((Bundle) element).getState(); + else if (element instanceof BundleNode) + state = ((BundleNode) element).getBundle().getState(); + else if (element instanceof ServiceReferenceNode) + if (((ServiceReferenceNode) element).isPublished()) + return OsgiExplorerImages.SERVICE_PUBLISHED; + else + return OsgiExplorerImages.SERVICE_REFERENCED; + else + return null; + + switch (state) { + case Bundle.UNINSTALLED: + return OsgiExplorerImages.INSTALLED; + case Bundle.INSTALLED: + return OsgiExplorerImages.INSTALLED; + case Bundle.RESOLVED: + return OsgiExplorerImages.RESOLVED; + case Bundle.STARTING: + return OsgiExplorerImages.STARTING; + case Bundle.STOPPING: + return OsgiExplorerImages.STARTING; + case Bundle.ACTIVE: + return OsgiExplorerImages.ACTIVE; + default: + return null; + } + } + + @Override + public String getText(Object element) { + return null; + } + + @Override + public String getToolTipText(Object element) { + Bundle bundle = (Bundle) element; + Integer state = bundle.getState(); + switch (state) { + case Bundle.UNINSTALLED: + return "UNINSTALLED"; + case Bundle.INSTALLED: + return "INSTALLED"; + case Bundle.RESOLVED: + return "RESOLVED"; + case Bundle.STARTING: + String activationPolicy = bundle.getHeaders() + .get(Constants.BUNDLE_ACTIVATIONPOLICY).toString(); + + // .get("Bundle-ActivationPolicy").toString(); + // FIXME constant triggers the compilation failure + if (activationPolicy != null + && activationPolicy.equals(Constants.ACTIVATION_LAZY)) + // && activationPolicy.equals("lazy")) + // FIXME constant triggers the compilation failure + // && activationPolicy.equals(Constants.ACTIVATION_LAZY)) + return "<>"; + return "STARTING"; + case Bundle.STOPPING: + return "STOPPING"; + case Bundle.ACTIVE: + return "ACTIVE"; + default: + return null; + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/AdminLogView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/AdminLogView.java new file mode 100644 index 000000000..c76b8903a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/AdminLogView.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.useradmin; + +import java.util.ArrayList; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.node.ArgeoLogger; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +/** + * Display log lines for all users with a virtual table. + */ +public class AdminLogView extends ViewPart { + public static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".adminLogView"; + + private TableViewer viewer; + + private LogContentProvider logContentProvider; + private ArgeoLogger argeoLogger; + + @Override + public void createPartControl(Composite parent) { + // FIXME doesn't return a monospace font in RAP + Font font = JFaceResources.getTextFont(); + Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + table.setFont(font); + + viewer = new TableViewer(table); + viewer.setLabelProvider(new LabelProvider()); + logContentProvider = new LogContentProvider(viewer) { + private static final long serialVersionUID = -3401776448301180724L; + + @Override + protected StringBuffer prefix(String username, Long timestamp, + String level, String category, String thread) { + return super + .prefix(username, timestamp, level, category, thread) + .append(norm(level, 5)) + .append(' ') + .append(norm(username != null ? username + : "", 16)).append(' '); + } + }; + viewer.setContentProvider(logContentProvider); + // viewer.setUseHashlookup(true); + viewer.setInput(new ArrayList()); + + if (argeoLogger != null) + argeoLogger.registerForAll(logContentProvider, 1000, true); + } + + @Override + public void setFocus() { + viewer.getTable().setFocus(); + } + + @Override + public void dispose() { + if (argeoLogger != null) + argeoLogger.unregisterForAll(logContentProvider); + } + + public void setArgeoLogger(ArgeoLogger argeoLogger) { + this.argeoLogger = argeoLogger; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogContentProvider.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogContentProvider.java new file mode 100644 index 000000000..24f3ca1bc --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogContentProvider.java @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.useradmin; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +import org.argeo.node.ArgeoLogListener; +import org.eclipse.jface.viewers.ILazyContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; + +/** A content provider maintaining an array of lines */ +class LogContentProvider implements ILazyContentProvider, ArgeoLogListener { + private static final long serialVersionUID = -2084872367738339721L; + + private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + private final Long start; + /** current - start = line number. first line is number '1' */ + private Long current; + + // TODO make it configurable + private final Integer maxLineBufferSize = 10 * 1000; + + private final TableViewer viewer; + private LinkedList lines; + + public LogContentProvider(TableViewer viewer) { + this.viewer = viewer; + start = System.currentTimeMillis(); + lines = new LinkedList(); + current = start; + } + + public synchronized void dispose() { + lines.clear(); + lines = null; + } + + @SuppressWarnings("unchecked") + public synchronized void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + List lin = (List) newInput; + if (lin == null) + return; + for (String line : lin) { + addLine(line); + } + this.viewer.setItemCount(lines.size()); + } + + public void updateElement(int index) { + viewer.replace(lines.get(index), index); + } + + public synchronized void appendLog(String username, Long timestamp, + String level, String category, String thread, Object msg, + String[] exception) { + // check if valid + if (lines == null) + return; + + String message = msg.toString(); + int count = 0; + String prefix = prefix(username, timestamp, level, category, thread) + .toString(); + // String suffix = suffix(username, timestamp, level, category, thread); + for (String line : message.split("\n")) { + addLine(count == 0 ? prefix + line : line); + count++; + } + + if (exception != null) { + for (String ste : exception) { + addLine(ste); + } + } + + viewer.getTable().getDisplay().asyncExec(new Runnable() { + public void run() { + if (lines == null) + return; + viewer.setItemCount(lines.size()); + // doesn't work with syncExec + scrollToLastLine(); + } + }); + } + + protected StringBuffer prefix(String username, Long timestamp, + String level, String category, String thread) { + StringBuffer buf = new StringBuffer(""); + buf.append(dateFormat.format(new Date(timestamp))).append(" "); + // buf.append(level).append(" "); + return buf; + } + + /** Normalize string to the given size */ + protected String norm(String str, Integer size) { + int length = str.length(); + if (length == size) + return str; + else if (length > size) + return str.substring(0, size); + else { + char[] arr = new char[size - length]; + Arrays.fill(arr, ' '); + return str + new String(arr); + } + } + + // protected String suffix(String username, Long timestamp, String level, + // String category, String thread) { + // return ""; + // } + + /** Scroll to the last line */ + protected synchronized void scrollToLastLine() { + // we try to show last line with two methods + // viewer.reveal(lines.peekLast()); + + Table table = viewer.getTable(); + TableItem ti = table.getItem(table.getItemCount() - 1); + table.showItem(ti); + } + + protected synchronized LogLine addLine(String line) { + // check for maximal size and purge if necessary + while (lines.size() >= maxLineBufferSize) { + for (int i = 0; i < maxLineBufferSize / 10; i++) { + lines.poll(); + } + } + + current++; + LogLine logLine = new LogLine(current, line); + lines.add(logLine); + return logLine; + } + + private class LogLine { + private Long linenumber; + private String message; + + public LogLine(Long linenumber, String message) { + this.linenumber = linenumber; + this.message = message; + } + + @Override + public int hashCode() { + return linenumber.intValue(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LogLine) + return ((LogLine) obj).linenumber.equals(linenumber); + else + return false; + } + + @Override + public String toString() { + return message; + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogView.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogView.java new file mode 100644 index 000000000..07c808d3e --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/LogView.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.useradmin; + +import java.util.ArrayList; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.node.ArgeoLogListener; +import org.argeo.node.ArgeoLogger; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +/** + * Display log lines with a virtual table. Register and unregisters a + * {@link ArgeoLogListener} via OSGi services. + */ +public class LogView extends ViewPart { + public static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".logView"; + + private TableViewer viewer; + + private LogContentProvider logContentProvider; + private ArgeoLogger argeoLogger; + + @Override + public void createPartControl(Composite parent) { + Font font = JFaceResources.getTextFont(); + Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + table.setFont(font); + + viewer = new TableViewer(table); + viewer.setLabelProvider(new LabelProvider()); + logContentProvider = new LogContentProvider(viewer); + viewer.setContentProvider(logContentProvider); + // viewer.setUseHashlookup(true); + viewer.setInput(new ArrayList()); + + if (argeoLogger != null) + argeoLogger.register(logContentProvider, 1000); + } + + @Override + public void setFocus() { + viewer.getTable().setFocus(); + } + + @Override + public void dispose() { + if (argeoLogger != null) + argeoLogger.unregister(logContentProvider); + } + + public void setArgeoLogger(ArgeoLogger argeoLogger) { + this.argeoLogger = argeoLogger; + } + +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserProfile.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserProfile.java new file mode 100644 index 000000000..c86e9a08e --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/useradmin/UserProfile.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.useradmin; + +import java.util.TreeSet; + +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +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.Table; +import org.eclipse.ui.part.ViewPart; + +/** Information about the currently logged in user */ +public class UserProfile extends ViewPart { + public static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".userProfile"; + + private TableViewer viewer; + + @Override + public void createPartControl(Composite parent) { + parent.setLayout(new GridLayout(2, false)); + + // Authentication authentication = CurrentUser.getAuthentication(); + // EclipseUiUtils.createGridLL(parent, "Name", authentication + // .getPrincipal().toString()); + EclipseUiUtils.createGridLL(parent, "User ID", + CurrentUser.getUsername()); + + // roles table + Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); + table.setLinesVisible(false); + table.setHeaderVisible(false); + viewer = new TableViewer(table); + viewer.setContentProvider(new RolesContentProvider()); + viewer.setLabelProvider(new LabelProvider()); + getViewSite().setSelectionProvider(viewer); + viewer.setInput(getViewSite()); + } + + @Override + public void setFocus() { + viewer.getTable(); + } + + private class RolesContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -4576917440167866233L; + + public Object[] getElements(Object inputElement) { + return new TreeSet(CurrentUser.roles()).toArray(); + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/CommandUtils.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/CommandUtils.java new file mode 100644 index 000000000..b05ba0746 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/CommandUtils.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.services.IServiceLocator; + +/** + * Centralises useful and generic methods when dealing with commands in an + * Eclipse Workbench context + */ +public class CommandUtils { + + /** + * Commodities the refresh of a single command with no parameter in a + * Menu.aboutToShow method to simplify further development + * + * Note: that this method should be called with a false show command flag to + * remove a contribution that have been previously contributed + */ + public static void refreshCommand(IMenuManager menuManager, IServiceLocator locator, String cmdId, String label, + ImageDescriptor icon, boolean showCommand) { + refreshParameterizedCommand(menuManager, locator, cmdId, label, icon, showCommand, null); + } + + /** + * Commodities the refresh the contribution of a command with a map of + * parameters in a context menu + * + * The command ID is used has contribution item ID + */ + public static void refreshParameterizedCommand(IMenuManager menuManager, IServiceLocator locator, String cmdId, + String label, ImageDescriptor icon, boolean showCommand, Map params) { + refreshParameterizedCommand(menuManager, locator, cmdId, cmdId, label, icon, showCommand, params); + } + + /** + * Commodities the refresh the contribution of a command with a map of + * parameters in a context menu + * + * @param menuManager + * @param locator + * @param contributionId + * @param commandId + * @param label + * @param icon + * @param showCommand + * @param params + */ + public static void refreshParameterizedCommand(IMenuManager menuManager, IServiceLocator locator, + String contributionId, String commandId, String label, ImageDescriptor icon, boolean showCommand, + Map params) { + IContributionItem ici = menuManager.find(contributionId); + if (ici != null) + menuManager.remove(ici); + if (showCommand) { + CommandContributionItemParameter contributionItemParameter = new CommandContributionItemParameter(locator, + null, commandId, SWT.PUSH); + + // Set Params + contributionItemParameter.label = label; + contributionItemParameter.icon = icon; + + if (params != null) + contributionItemParameter.parameters = params; + + CommandContributionItem cci = new CommandContributionItem(contributionItemParameter); + cci.setId(contributionId); + menuManager.add(cci); + } + } + + /** Helper to call a command without parameter easily */ + public static void callCommand(String commandID) { + callCommand(commandID, null); + } + + /** Helper to call a command with a single parameter easily */ + public static void callCommand(String commandID, String parameterID, String parameterValue) { + Map params = new HashMap(); + params.put(parameterID, parameterValue); + callCommand(commandID, params); + } + + /** + * Helper to call a command with a map of parameters easily + * + * @param paramMap + * a map that links various command IDs with corresponding String + * values. + */ + public static void callCommand(String commandID, Map paramMap) { + try { + IWorkbench iw = WorkbenchUiPlugin.getDefault().getWorkbench(); + IHandlerService handlerService = (IHandlerService) iw.getService(IHandlerService.class); + ICommandService cmdService = (ICommandService) iw.getActiveWorkbenchWindow() + .getService(ICommandService.class); + Command cmd = cmdService.getCommand(commandID); + + ArrayList parameters = null; + ParameterizedCommand pc; + + if (paramMap != null) { + // Set parameters of the command to launch : + parameters = new ArrayList(); + Parameterization parameterization; + + for (String id : paramMap.keySet()) { + parameterization = new Parameterization(cmd.getParameter(id), paramMap.get(id)); + parameters.add(parameterization); + } + pc = new ParameterizedCommand(cmd, parameters.toArray(new Parameterization[parameters.size()])); + } else + pc = new ParameterizedCommand(cmd, null); + + // execute the command + handlerService.executeCommand(pc, null); + } catch (Exception e) { + throw new EclipseUiException("Unexpected error while" + " calling the command " + commandID, e); + } + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/PrivilegedJob.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/PrivilegedJob.java new file mode 100644 index 000000000..414fcbacb --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/PrivilegedJob.java @@ -0,0 +1,49 @@ +package org.argeo.cms.ui.workbench.util; + +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.security.auth.Subject; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.Job; + +/** + * Propagate authentication to an eclipse job. Typically to execute a privileged + * action outside the UI thread + */ +public abstract class PrivilegedJob extends Job { + private final Subject subject; + + public PrivilegedJob(String jobName) { + this(jobName, AccessController.getContext()); + } + + public PrivilegedJob(String jobName, + AccessControlContext accessControlContext) { + super(jobName); + subject = Subject.getSubject(accessControlContext); + + // Must be called *before* the job is scheduled, + // it is required for the progress window to appear + setUser(true); + } + + @Override + protected IStatus run(final IProgressMonitor progressMonitor) { + PrivilegedAction privilegedAction = new PrivilegedAction() { + public IStatus run() { + return doRun(progressMonitor); + } + }; + return Subject.doAs(subject, privilegedAction); + } + + /** + * Implement here what should be executed with default context + * authentication + */ + protected abstract IStatus doRun(IProgressMonitor progressMonitor); +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/RolesSourceProvider.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/RolesSourceProvider.java new file mode 100644 index 000000000..f71c13d6c --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/util/RolesSourceProvider.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.cms.ui.workbench.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.argeo.cms.auth.CurrentUser; +import org.eclipse.ui.AbstractSourceProvider; + +/** + * Provides the roles of the current user as a variable to be used for activity + * binding + */ +public class RolesSourceProvider extends AbstractSourceProvider { + public final static String ROLES_VARIABLE = "roles"; + private final static String[] PROVIDED_SOURCE_NAMES = new String[] { ROLES_VARIABLE }; + + public Map> getCurrentState() { + Map> stateMap = new HashMap>(); + stateMap.put(ROLES_VARIABLE, CurrentUser.roles()); + return stateMap; + } + + public String[] getProvidedSourceNames() { + return PROVIDED_SOURCE_NAMES; + } + + public void updateRoles() { + fireSourceChanged(0, getCurrentState()); + } + + public void dispose() { + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/ApplicationContextTracker.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/ApplicationContextTracker.java new file mode 100644 index 000000000..1d3df4304 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/ApplicationContextTracker.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.eclipse.spring; + +import static java.text.MessageFormat.format; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.util.tracker.ServiceTracker; +import org.springframework.context.ApplicationContext; + +/** + * Tracks Spring application context published as services. + * + * @author Heiko Seeberger + * @author Mathieu Baudier + */ +class ApplicationContextTracker { + private final static Log log = LogFactory + .getLog(ApplicationContextTracker.class); + + private static final String FILTER = "(&(objectClass=org.springframework.context.ApplicationContext)" //$NON-NLS-1$ + + "(org.springframework.context.service.name={0}))"; //$NON-NLS-1$ + + public final static String APPLICATION_CONTEXT_TRACKER_TIMEOUT = "org.argeo.eclipse.spring.applicationContextTrackerTimeout"; + + private static Long defaultTimeout = Long.parseLong(System.getProperty( + APPLICATION_CONTEXT_TRACKER_TIMEOUT, "30000")); + + @SuppressWarnings("rawtypes") + private ServiceTracker applicationContextServiceTracker; + + /** + * @param contributorBundle + * OSGi bundle for which the Spring application context is to be + * tracked. Must not be null! + * @param factoryBundleContext + * BundleContext object which can be used to track services + * @throws IllegalArgumentException + * if the given bundle is null. + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public ApplicationContextTracker(final Bundle contributorBundle, + final BundleContext factoryBundleContext) { + final String filter = format(FILTER, + contributorBundle.getSymbolicName()); + try { + applicationContextServiceTracker = new ServiceTracker( + factoryBundleContext, FrameworkUtil.createFilter(filter), + null); + // applicationContextServiceTracker.open(); + } catch (final InvalidSyntaxException e) { + e.printStackTrace(); + } + } + + public void open() { + if (applicationContextServiceTracker != null) { + applicationContextServiceTracker.open(); + } + } + + public void close() { + if (applicationContextServiceTracker != null) { + applicationContextServiceTracker.close(); + } + } + + public ApplicationContext getApplicationContext() { + ApplicationContext applicationContext = null; + if (applicationContextServiceTracker != null) { + try { + applicationContext = (ApplicationContext) applicationContextServiceTracker + .waitForService(defaultTimeout); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return applicationContext; + } + + @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + + static ApplicationContext getApplicationContext(String bundleSymbolicName) { + Bundle contributorBundle = Platform.getBundle(bundleSymbolicName); + return getApplicationContext(contributorBundle); + } + + static ApplicationContext getApplicationContext( + final Bundle contributorBundle) { + if (log.isTraceEnabled()) + log.trace("Get application context for bundle " + contributorBundle); + + // Start if not yet started (also if in STARTING state, may be lazy) + if (contributorBundle.getState() != Bundle.ACTIVE) { + if (log.isTraceEnabled()) + log.trace("Starting bundle: " + + contributorBundle.getSymbolicName()); + // Thread startBundle = new Thread("Start bundle " + // + contributorBundle.getSymbolicName()) { + // public void run() { + try { + contributorBundle.start(); + } catch (BundleException e) { + log.error("Cannot start bundle " + contributorBundle, e); + } + // } + // }; + // startBundle.start(); + // try { + // startBundle.join(10 * 1000l); + // } catch (InterruptedException e) { + // // silent + // } + } + + final ApplicationContextTracker applicationContextTracker = new ApplicationContextTracker( + contributorBundle, contributorBundle.getBundleContext()); + ApplicationContext applicationContext = null; + try { + applicationContextTracker.open(); + applicationContext = applicationContextTracker + .getApplicationContext(); + } finally { + applicationContextTracker.close(); + } + return applicationContext; + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringCommandHandler.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringCommandHandler.java new file mode 100644 index 000000000..698b93741 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringCommandHandler.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.eclipse.spring; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.commands.IHandlerListener; +import org.springframework.context.ApplicationContext; + +/** Allows to declare Eclipse commands as Spring beans */ +public class SpringCommandHandler implements IHandler { + private final static Log log = LogFactory + .getLog(SpringCommandHandler.class); + + public void addHandlerListener(IHandlerListener handlerListener) { + } + + public void dispose() { + } + + public Object execute(ExecutionEvent event) throws ExecutionException { + String commandId = event.getCommand().getId(); + String bundleSymbolicName = commandId.substring(0, + commandId.lastIndexOf('.')); + try { + if (log.isTraceEnabled()) + log.trace("Execute " + event + " via spring command handler " + + this); + // TODO: make it more flexible and robust + ApplicationContext applicationContext = ApplicationContextTracker + .getApplicationContext(bundleSymbolicName); + if (applicationContext == null) + throw new EclipseUiException( + "No application context found for " + + bundleSymbolicName); + + // retrieve the command via its id + String beanName = event.getCommand().getId(); + + if (!applicationContext.containsBean(beanName)) { + if (beanName.startsWith(bundleSymbolicName)) + beanName = beanName + .substring(bundleSymbolicName.length() + 1); + } + + if (!applicationContext.containsBean(beanName)) + throw new ExecutionException("No bean found with name " + + beanName + " in bundle " + bundleSymbolicName); + Object bean = applicationContext.getBean(beanName); + + if (!(bean instanceof IHandler)) + throw new ExecutionException("Bean with name " + beanName + + " and class " + bean.getClass() + + " does not implement the IHandler interface."); + + IHandler handler = (IHandler) bean; + return handler.execute(event); + } catch (Exception e) { + // TODO: use eclipse error management + // log.error(e); + throw new ExecutionException("Cannot execute Spring command " + + commandId + " in bundle " + bundleSymbolicName, e); + } + } + + public boolean isEnabled() { + return true; + } + + public boolean isHandled() { + return true; + } + + public void removeHandlerListener(IHandlerListener handlerListener) { + } +} diff --git a/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringExtensionFactory.java b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringExtensionFactory.java new file mode 100644 index 000000000..ab1e8caf6 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/SpringExtensionFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.eclipse.spring; + +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.core.runtime.IExecutableExtensionFactory; +import org.eclipse.core.runtime.IExtension; +import org.springframework.context.ApplicationContext; + +/** + * The Spring Extension Factory builds a bridge between the Eclipse Extension + * Registry and the Spring Framework (especially Spring Dynamic Modules). + * + * It allows you to define your extension as a spring bean within the spring + * application context of your bundle. If you would like to use this bean as an + * instance of an extension (an Eclipse RCP view, for example) you define the + * extension with this spring extension factory as the class to be created. + * + * To let the spring extension factory pick the right bean from your application + * context you need to set the bean id to the same value as the id of the view + * within the view definition, for example. This is important if your extension + * definition contains more than one element, where each element has its own id. + * + * If the extension definition elements themselves have no id attribute the + * spring extension factory uses the id of the extension itself to identify the + * bean. + * + * original code from: Blog entry + * + * @author Martin Lippert + * @author mbaudier + */ +public class SpringExtensionFactory implements IExecutableExtensionFactory, + IExecutableExtension { + + private Object bean; + + public Object create() throws CoreException { + if (bean == null) + throw new EclipseUiException("No underlying bean for extension"); + return bean; + } + + public void setInitializationData(IConfigurationElement config, + String propertyName, Object data) throws CoreException { + String bundleSymbolicName = config.getContributor().getName(); + ApplicationContext applicationContext = ApplicationContextTracker + .getApplicationContext(bundleSymbolicName); + if (applicationContext == null) + throw new EclipseUiException( + "Cannot find application context for bundle " + + bundleSymbolicName); + + String beanName = getBeanName(data, config); + if (beanName == null) + throw new EclipseUiException("Cannot find bean name for extension " + + config); + + if (!applicationContext.containsBean(beanName)) { + if (beanName.startsWith(bundleSymbolicName)) + beanName = beanName.substring(bundleSymbolicName.length() + 1); + } + + if (!applicationContext.containsBean(beanName)) + throw new EclipseUiException("No bean with name '" + beanName + "'"); + + this.bean = applicationContext.getBean(beanName); + if (this.bean instanceof IExecutableExtension) { + ((IExecutableExtension) this.bean).setInitializationData(config, + propertyName, data); + } + } + + private String getBeanName(Object data, IConfigurationElement config) { + + // try the specific bean id the extension defines + if (data != null && data.toString().length() > 0) { + return data.toString(); + } + + // try the id of the config element + if (config.getAttribute("id") != null) { + return config.getAttribute("id"); + } + + // try the id of the extension element itself + if (config.getParent() != null + && config.getParent() instanceof IExtension) { + IExtension extensionDefinition = (IExtension) config.getParent(); + return extensionDefinition.getSimpleIdentifier(); + } + + return null; + } +} diff --git a/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.gitignore b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.project b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.project new file mode 100644 index 000000000..2795baf53 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/.project @@ -0,0 +1,20 @@ + + + org.argeo.ext.rap.ui.workbench + + + + + + org.eclipse.pde.ManifestBuilder + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.PluginNature + + diff --git a/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/.gitignore b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/.gitignore new file mode 100644 index 000000000..4854a41b9 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/spring/osgi.xml b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/spring/osgi.xml new file mode 100644 index 000000000..206a72ad2 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/META-INF/spring/osgi.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/bnd.bnd b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/bnd.bnd new file mode 100644 index 000000000..48c602a93 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/bnd.bnd @@ -0,0 +1,4 @@ +Bundle-SymbolicName: org.argeo.ext.rap.ui.workbench;singleton:=true +Bundle-ActivationPolicy: lazy + +Fragment-Host: org.eclipse.rap.ui.workbench diff --git a/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/build.properties b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/build.properties new file mode 100644 index 000000000..485b2667a --- /dev/null +++ b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/build.properties @@ -0,0 +1,2 @@ +source.. = src/,\ + ext/test/ diff --git a/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/pom.xml b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/pom.xml new file mode 100644 index 000000000..fe372e2d3 --- /dev/null +++ b/legacy/argeo-commons/org.argeo.ext.rap.ui.workbench/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + + org.argeo.slc.legacy.commons + argeo-commons-legacy + 2.1.85-SNAPSHOT + .. + + org.argeo.ext.rap.ui.workbench + Extension RAP Workbench + diff --git a/legacy/argeo-commons/pom.xml b/legacy/argeo-commons/pom.xml new file mode 100644 index 000000000..e9524b347 --- /dev/null +++ b/legacy/argeo-commons/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + org.argeo.commons + argeo-commons + 2.1.84 + + org.argeo.slc.legacy.commons + argeo-commons-legacy + 2.1.85-SNAPSHOT + Commons Legacy + pom + + 2.1.13 + + + org.argeo.cms.ui.workbench + org.argeo.cms.ui.workbench.rap + org.argeo.ext.rap.ui.workbench + dep + + + + + org.argeo.tp.extras + argeo-tp-extras + ${version.argeo-tp-extras} + pom + import + + + + + + argeo + http://repo.argeo.org/data/java/argeo-2.1/ + + true + daily + warn + + + false + + + + argeo-extras + http://repo.argeo.org/data/java/argeo-extras-2.1/ + + true + daily + warn + + + + + + localrepo + + + argeo-extras + http://localhost:7080/data/java/argeo-extras-2.1 + + true + daily + warn + + + + + + + \ No newline at end of file diff --git a/legacy/pom.xml b/legacy/pom.xml new file mode 100644 index 000000000..9d9318320 --- /dev/null +++ b/legacy/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + org.argeo.slc + argeo-slc + 2.1.17-SNAPSHOT + .. + + legacy + pom + SLC Legacy Argeo Software + + argeo-commons + + \ No newline at end of file diff --git a/org.argeo.slc.client.rap/pom.xml b/org.argeo.slc.client.rap/pom.xml index b077f5d37..5f376d0a6 100644 --- a/org.argeo.slc.client.rap/pom.xml +++ b/org.argeo.slc.client.rap/pom.xml @@ -1,4 +1,6 @@ - + 4.0.0 org.argeo.slc @@ -19,9 +21,9 @@ - org.argeo.commons + org.argeo.slc.legacy.commons org.argeo.cms.ui.workbench.rap - ${version.argeo-commons} + ${version.argeo-commons-legacy} diff --git a/org.argeo.slc.client.ui.dist/pom.xml b/org.argeo.slc.client.ui.dist/pom.xml index 0883e0c19..369f41c7a 100644 --- a/org.argeo.slc.client.ui.dist/pom.xml +++ b/org.argeo.slc.client.ui.dist/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 org.argeo.slc @@ -18,9 +20,9 @@ ${version.argeo-commons}
- org.argeo.commons + org.argeo.slc.legacy.commons org.argeo.cms.ui.workbench - ${version.argeo-commons} + ${version.argeo-commons-legacy} @@ -41,7 +43,7 @@ 2.1.17-SNAPSHOT - + org.argeo.commons org.argeo.util @@ -56,6 +58,6 @@ pom provided - + \ No newline at end of file diff --git a/org.argeo.slc.client.ui/pom.xml b/org.argeo.slc.client.ui/pom.xml index 2920911bb..c2ff564df 100644 --- a/org.argeo.slc.client.ui/pom.xml +++ b/org.argeo.slc.client.ui/pom.xml @@ -1,4 +1,6 @@ - + 4.0.0 org.argeo.slc @@ -30,9 +32,9 @@ provided - org.argeo.commons + org.argeo.slc.legacy.commons org.argeo.cms.ui.workbench - ${version.argeo-commons} + ${version.argeo-commons-legacy} diff --git a/org.argeo.slc.e4/SlcMain.java b/org.argeo.slc.e4/SlcMain.java deleted file mode 100644 index a4bf3cd65..000000000 --- a/org.argeo.slc.e4/SlcMain.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed 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.slc.cli; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.UUID; - -import javax.security.auth.Subject; -import javax.security.auth.login.LoginContext; - -import org.argeo.osgi.boot.OsgiBoot; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.launch.Framework; -import org.osgi.framework.launch.FrameworkFactory; - -/** Configures an SLC runtime and runs a process. */ -public class SlcMain implements PrivilegedAction { - public final static String NIX = "NIX"; - public final static String WINDOWS = "WINDOWS"; - public final static String SOLARIS = "SOLARIS"; - - public final static String os; - public final static String slcDirName = ".slc"; - final static File homeDir = new File(System.getProperty("user.home")); - - static { - String osName = System.getProperty("os.name"); - if (osName.startsWith("Win")) - os = WINDOWS; - else if (osName.startsWith("Solaris")) - os = SOLARIS; - else - os = NIX; - } - - private Long timeout = 30 * 1000l; - private final String[] args; - private final File confDir; - private final File dataDir; - private final File modulesDir; - - private final List bundlesToStart = new ArrayList(); - - public SlcMain(String[] args, File confDir, File dataDir, File modulesDir) { - this.args = args; - this.confDir = confDir; - this.dataDir = dataDir; - this.modulesDir = modulesDir; - - bundlesToStart.add("org.eclipse.equinox.cm"); - bundlesToStart.add("org.argeo.cms"); - bundlesToStart.add("org.eclipse.gemini.blueprint.extender"); - bundlesToStart.add("org.argeo.slc.agent"); - bundlesToStart.add("org.argeo.slc.agent.jcr"); - - // bundlesToStart.add("org.springframework.osgi.extender"); - // bundlesToStart.add("org.argeo.node.repo.jackrabbit"); - // bundlesToStart.add("org.argeo.security.dao.os"); - // bundlesToStart.add("org.argeo.slc.node.jackrabbit"); - // bundlesToStart.add("org.argeo.slc.agent"); - // bundlesToStart.add("org.argeo.slc.agent.jcr"); - // if (args.length == 0) - // bundlesToStart.add("org.argeo.slc.support.equinox"); - // bundlesToStart.add("org.argeo.slc.agent.cli"); - } - - public String run() { - long begin = System.currentTimeMillis(); - - Framework framework = null; - try { - info("## Date : " + new Date()); - info("## Data : " + dataDir.getCanonicalPath()); - - // Start Equinox - ServiceLoader ff = ServiceLoader.load(FrameworkFactory.class); - FrameworkFactory frameworkFactory = ff.iterator().next(); - Map configuration = new HashMap(); - configuration.put("osgi.configuration.area", confDir.getCanonicalPath()); - configuration.put("osgi.instance.area", dataDir.getCanonicalPath()); - // Do clean - configuration.put("osgi.clean", "true"); - if (args.length == 0) { - configuration.put("osgi.console", ""); - } - - // Spring configs currently require System properties - System.getProperties().putAll(configuration); - - framework = frameworkFactory.newFramework(configuration); - framework.start(); - BundleContext bundleContext = framework.getBundleContext(); - - // OSGi bootstrap - OsgiBoot osgiBoot = new OsgiBoot(bundleContext); - - // working copy modules - if (modulesDir.exists()) - osgiBoot.installUrls(osgiBoot.getBundlesUrls(modulesDir.getCanonicalPath() + ";in=*;ex=.gitignore")); - - // system modules - if (System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BUNDLES) != null) - osgiBoot.installUrls(osgiBoot.getBundlesUrls(System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BUNDLES))); - else - osgiBoot.installUrls(osgiBoot.getBundlesUrls(System.getProperty("user.home") + "/.slc/modules/;in=**")); - - // Start runtime - osgiBoot.startBundles(bundlesToStart); - - // Find SLC Agent - ServiceReference sr = null; - while (sr == null) { - sr = bundleContext.getServiceReference("org.argeo.slc.execution.SlcAgentCli"); - if (System.currentTimeMillis() - begin > timeout) - throw new RuntimeException("Cannot find SLC agent CLI"); - Thread.sleep(100); - } - Object agentCli = bundleContext.getService(sr); - - // Initialization completed - long duration = System.currentTimeMillis() - begin; - info("[[ Initialized in " + (duration / 1000) + "s " + (duration % 1000) + "ms ]]"); - - if (args.length == 0) - return null;// console mode - - // Subject.doAs(Subject.getSubject(AccessController.getContext()), - // new AgentCliCall(agentCli)); - Class[] parameterTypes = { String[].class }; - Method method = agentCli.getClass().getMethod("process", parameterTypes); - Object[] methodArgs = { args }; - Object ret = method.invoke(agentCli, methodArgs); - - // Shutdown OSGi runtime - framework.stop(); - framework.waitForStop(60 * 1000); - - return ret.toString(); - } catch (Exception e) { - // Shutdown OSGi runtime - if (framework != null) - try { - framework.stop(); - framework.waitForStop(15 * 1000); - } catch (Exception silent) { - } - throw new RuntimeException("Cannot run SLC command line", e); - } finally { - - } - } - - public static void main(String[] args) { - try { - // Prepare directories - File executionDir = new File(System.getProperty("user.dir")); - File slcDir; - Boolean isTransient = false; - if (isTransient) { - File tempDir = new File(System.getProperty("java.io.tmpdir") + "/" + System.getProperty("user.name")); - slcDir = new File(tempDir, "slc-" + UUID.randomUUID().toString()); - slcDir.mkdirs(); - System.setProperty("argeo.node.repo.configuration", "osgibundle:repository-memory.xml"); - } else { - slcDir = findSlcDir(executionDir); - if (slcDir == null) { - slcDir = new File(executionDir, slcDirName); - slcDir.mkdirs(); - info("## Creating an SLC node at " + slcDir + " ..."); - } - } - - File dataDir = new File(slcDir, "data"); - if (!dataDir.exists()) - dataDir.mkdirs(); - - File confDir = new File(slcDir, "conf"); - if (!confDir.exists()) - confDir.mkdirs(); - - File modulesDir = new File(slcDir, "modules"); - - // JAAS - // File jaasFile = new File(confDir, "jaas.config"); - // if (!jaasFile.exists()) - // copyResource("/org/argeo/slc/cli/jaas.config", jaasFile); - // System.setProperty("java.security.auth.login.config", - // jaasFile.getCanonicalPath()); - - // log4j - File log4jFile = new File(confDir, "log4j.properties"); - if (!log4jFile.exists()) - copyResource("/org/argeo/slc/cli/log4j.properties", log4jFile); - System.setProperty("log4j.configuration", "file://" + log4jFile.getCanonicalPath()); - // Run as a privileged action - // LoginContext lc = new LoginContext(os); - // lc.login(); - // - // Subject subject = - // Subject.getSubject(AccessController.getContext()); - // Subject.doAs(subject, new SlcMain(args, confDir, dataDir, - // modulesDir)); - SlcMain slcMain = new SlcMain(args, confDir, dataDir, modulesDir); - slcMain.run(); - if (args.length != 0) - System.exit(0); - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - } - - /** - * Recursively look in parent directories for a directory named - * {@link #slcDirName} - */ - protected static File findSlcDir(File currentDir) { - File slcDir = new File(currentDir, slcDirName); - // covers the use case of running from the home directory - if (slcDir.exists() && slcDir.isDirectory()) - return slcDir; - File parentDir = currentDir.getParentFile(); - if (parentDir == null) - return null; - try { - // ~/.slc reserved for agent - if (parentDir.getCanonicalPath().equals(homeDir.getCanonicalPath())) - return null; - } catch (IOException e) { - throw new RuntimeException("Cannot check home directory", e); - } - return findSlcDir(parentDir); - } - - protected static void copyResource(String resource, File targetFile) { - InputStream input = null; - FileOutputStream output = null; - try { - input = SlcMain.class.getResourceAsStream(resource); - output = new FileOutputStream(targetFile); - byte[] buf = new byte[8192]; - while (true) { - int length = input.read(buf); - if (length < 0) - break; - output.write(buf, 0, length); - } - } catch (Exception e) { - throw new RuntimeException("Cannot write " + resource + " file to " + targetFile, e); - } finally { - try { - input.close(); - } catch (Exception ignore) { - } - try { - output.close(); - } catch (Exception ignore) { - } - } - - } - - protected static void info(Object msg) { - System.out.println(msg); - } - - protected static void err(Object msg) { - System.err.println(msg); - } - - protected static void debug(Object msg) { - System.out.println(msg); - } - -} - -// private String bundlesToInstall = System.getProperty("user.home") -// + -// "/dev/src/slc/dep/org.argeo.slc.dep.minimal/target/dependency;in=*.jar," -// + System.getProperty("user.home") -// + "/dev/src/slc/demo/modules;in=*;ex=pom.xml;ex=.svn"; - -// ServiceTracker agentTracker = new ServiceTracker(bundleContext, -// "org.argeo.slc.execution.SlcAgentCli", null); -// agentTracker.open(); -// final Object agentCli = agentTracker.waitForService(30 * 1000); -// if (agentCli == null) -// throw new RuntimeException("Cannot find SLC agent CLI"); - -// protected class AgentCliCall implements PrivilegedAction { -// private final Object agentCli; -// -// public AgentCliCall(Object agentCli) { -// super(); -// this.agentCli = agentCli; -// } -// -// public String run() { -// try { -// Class[] parameterTypes = { String[].class }; -// Method method = agentCli.getClass().getMethod("process", -// parameterTypes); -// Object[] methodArgs = { args }; -// Object ret = method.invoke(agentCli, methodArgs); -// return ret.toString(); -// } catch (Exception e) { -// throw new RuntimeException("Cannot run " -// + Arrays.toString(args) + " on " + agentCli, e); -// } -// } -// -// } diff --git a/pom.xml b/pom.xml index 4d5512c01..ecc424b64 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.argeo.commons argeo-commons - 2.1.82 + 2.1.85-SNAPSHOT org.argeo.slc argeo-slc @@ -18,6 +18,8 @@ 2.1 2.1.13 + + 2.1.85-SNAPSHOT @@ -37,7 +39,8 @@ org.argeo.slc.e4 - + + legacy org.argeo.slc.client.ui org.argeo.slc.client.ui.dist org.argeo.slc.client.rap -- 2.39.2