Move legacy code and icons to Argeo JCR
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 21 Oct 2022 05:21:05 +0000 (07:21 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 21 Oct 2022 05:21:05 +0000 (07:21 +0200)
112 files changed:
swt/org.argeo.cms.jcr.e4/.project
swt/org.argeo.cms.jcr.e4/OSGI-INF/cmsAdminRap.xml [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/OSGI-INF/homeRepository.xml [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/OSGI-INF/userAdminWrapper.xml [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/bnd.bnd
swt/org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/package-info.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundleNode.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundlesView.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/CmsSessionsView.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ModulesView.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiConfigurationsView.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiExplorerImages.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ServiceReferenceNode.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/StateLabelProvider.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/package-info.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/parts/EgoDashboard.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupEditor.java
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupsView.java
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserEditor.java
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UsersView.java
swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/jcr/e4/rap/CmsE4AdminApp.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/actions/add.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/actions/close-all.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/actions/delete.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/actions/edit.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/actions/save-all.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/actions/save.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/active.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/add.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/add.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/addFolder.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/addPrivileges.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/addRepo.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/addWorkspace.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/adminLog.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/batch.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/begin.gif [new file with mode: 0755]
swt/org.argeo.cms.jcr.ui/icons/binary.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/browser.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/bundles.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/changePassword.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/clear.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/close-all.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/commit.gif [new file with mode: 0755]
swt/org.argeo.cms.jcr.ui/icons/delete.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/dumpNode.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/file.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/folder.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/getSize.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/group.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/home.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/home.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/import_fs.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/installed.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/loading.gif [deleted file]
swt/org.argeo.cms.jcr.ui/icons/log.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/logout.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/maintenance.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png [deleted file]
swt/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png [deleted file]
swt/org.argeo.cms.jcr.ui/icons/node.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/nodes.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/osgi_explorer.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/password.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/person-logged-in.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/person.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/query.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/refresh.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/remote_connected.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/remote_disconnected.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/remove.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/removePrivileges.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/rename.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/repositories.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/repository_connected.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/repository_disconnected.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/resolved.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/role.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/rollback.gif [new file with mode: 0755]
swt/org.argeo.cms.jcr.ui/icons/save-all.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/save.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/save.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/save_security.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/save_security_disabled.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/security.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/service_published.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/service_referenced.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/sort.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/starting.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/sync.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/user.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/users.gif [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/workgroup.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/workgroup.xcf [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/workspace_connected.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/icons/workspace_disconnected.png [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/LdifUsersTable.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UserLP.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UsersImages.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/ViewerUtils.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/package-info.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/CmsImages.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/package-info.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/SingleValue.java [new file with mode: 0644]
swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/package-info.java [new file with mode: 0644]

index 01f8dd213b439d7743ac3d653487a47d680c3270..290b0e6848392bd05fc09c0e30333d78426cd2fa 100644 (file)
                        <arguments>
                        </arguments>
                </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ds.core.builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
        </buildSpec>
        <natures>
                <nature>org.eclipse.pde.PluginNature</nature>
diff --git a/swt/org.argeo.cms.jcr.e4/OSGI-INF/cmsAdminRap.xml b/swt/org.argeo.cms.jcr.e4/OSGI-INF/cmsAdminRap.xml
new file mode 100644 (file)
index 0000000..33dd78d
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" configuration-policy="optional" name="CMS Admin RAP">
+   <implementation class="org.argeo.cms.jcr.e4.rap.CmsE4AdminApp"/>
+   <service>
+      <provide interface="org.eclipse.rap.rwt.application.ApplicationConfiguration"/>
+      <property name="contextName" type="String" value="cms/jcr"/>
+   </service>
+</scr:component>
diff --git a/swt/org.argeo.cms.jcr.e4/OSGI-INF/homeRepository.xml b/swt/org.argeo.cms.jcr.e4/OSGI-INF/homeRepository.xml
new file mode 100644 (file)
index 0000000..2722aab
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="Home Repository">
+   <implementation class="org.argeo.cms.e4.OsgiFilterContextFunction"/>
+   <property name="service.context.key" type="String" value="(cn=ego)"/>
+   <service>
+      <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+   </service>
+</scr:component>
diff --git a/swt/org.argeo.cms.jcr.e4/OSGI-INF/userAdminWrapper.xml b/swt/org.argeo.cms.jcr.e4/OSGI-INF/userAdminWrapper.xml
new file mode 100644 (file)
index 0000000..cc7087b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="User Admin Wrapper">
+   <implementation class="org.argeo.cms.e4.users.UserAdminWrapper"/>
+   <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.util.transaction.WorkTransaction" name="UserTransaction" policy="static"/>
+   <reference bind="setUserAdmin" cardinality="1..1" interface="org.osgi.service.useradmin.UserAdmin" name="UserAdmin" policy="static"/>
+   <service>
+      <provide interface="org.argeo.cms.e4.users.UserAdminWrapper"/>
+   </service>
+   <reference bind="addUserDirectory" cardinality="0..n" interface="org.argeo.osgi.useradmin.UserDirectory" name="UserDirectory" policy="static" unbind="removeUserDirectory"/>
+</scr:component>
index fde6c09e8fddbf0d88a9c5da38327c26700fbad0..906f95996266d6d44280ccfa96c87495036b9e5e 100644 (file)
@@ -1,3 +1,5 @@
+Bundle-ActivationPolicy: lazy
+
 Import-Package: \
 org.eclipse.swt,\
 org.eclipse.swt.widgets;version="0.0.0",\
@@ -9,4 +11,8 @@ javax.jcr.nodetype,\
 org.apache.jackrabbit.*;version="[2,3)",\
 org.argeo.cms,\
 org.argeo.jcr,\
-*
\ No newline at end of file
+*
+
+Service-Component: OSGI-INF/homeRepository.xml,\
+OSGI-INF/userAdminWrapper.xml,\
+OSGI-INF/cmsAdminRap.xml,\
diff --git a/swt/org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi b/swt/org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi
new file mode 100644 (file)
index 0000000..a3d955a
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_XqkCQKknEeObFrG_clJBYA" elementId="">
+  <children xsi:type="basic:TrimmedWindow" xmi:id="_Zdy6cKknEeObFrG_clJBYA" elementId="org.argeo.cms.e4.apps.admin.trimmedwindow.0" label="" x="10" y="10" width="500" height="500">
+    <persistedState key="styleOverride" value="8"/>
+    <tags>shellMaximized</tags>
+    <tags>auth.cn=admin,ou=roles,ou=node</tags>
+    <children xsi:type="advanced:PerspectiveStack" xmi:id="_jXVqsCk4Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.perspectivestack.0" selectedElement="_xOVlsDvOEeiF1foPJZSZkw">
+      <children xsi:type="advanced:Perspective" xmi:id="_xOVlsDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.perspective.users" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png">
+        <tags>auth.cn=admin,ou=roles,ou=node</tags>
+        <children xsi:type="basic:PartSashContainer" xmi:id="_1tQoEDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partsashcontainer.2" horizontal="true">
+          <children xsi:type="basic:PartStack" xmi:id="_vtbKkDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partstack.4" containerData="4000" selectedElement="_9gukYDvOEeiF1foPJZSZkw">
+            <children xsi:type="basic:Part" xmi:id="_9gukYDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.users" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UsersView" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png">
+              <handlers xmi:id="_0mN68DvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.4" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.NewUser" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+              <handlers xmi:id="_ODLdgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.5" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.DeleteUsers" command="_xkcMADvjEeiF1foPJZSZkw"/>
+              <toolbar xmi:id="_jLWmkDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.toolbar.1">
+                <children xsi:type="menu:HandledToolItem" xmi:id="_jy_OUDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.swt/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+                <children xsi:type="menu:HandledToolItem" xmi:id="_9qszMDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
+              </toolbar>
+            </children>
+          </children>
+          <children xsi:type="basic:PartStack" xmi:id="__g1a8DvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partstack.3" containerData="4000">
+            <tags>usersEditorArea</tags>
+          </children>
+          <children xsi:type="basic:PartStack" xmi:id="_-mFn8DvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partstack.5" containerData="2000">
+            <children xsi:type="basic:Part" xmi:id="_6etk4DvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.groups" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupsView" label="Groups" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png">
+              <handlers xmi:id="_cmShoDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.6" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.NewGroup" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+              <handlers xmi:id="_fbYfcDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.7" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.DeleteGroups" command="_xkcMADvjEeiF1foPJZSZkw"/>
+              <toolbar xmi:id="_Us0rADvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.toolbar.2">
+                <children xsi:type="menu:HandledToolItem" xmi:id="_VQTLgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.swt/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+                <children xsi:type="menu:HandledToolItem" xmi:id="_XfME8DvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
+              </toolbar>
+            </children>
+          </children>
+        </children>
+      </children>
+      <children xsi:type="advanced:Perspective" xmi:id="_jvjWYCk4Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.perspective.data" label="Data" iconURI="platform:/plugin/org.argeo.cms.swt/icons/nodes.gif">
+        <children xsi:type="basic:PartSashContainer" xmi:id="_h3tvMCkxEein5vuhpK-Dew" elementId="org.argeo.cms.e4.partsashcontainer.0" selectedElement="_0B9SECkxEein5vuhpK-Dew" horizontal="true">
+          <children xsi:type="basic:PartStack" xmi:id="_0B9SECkxEein5vuhpK-Dew" elementId="org.argeo.cms.e4.partstack.0" containerData="4000" selectedElement="_WAjPkCkTEein5vuhpK-Dew">
+            <children xsi:type="basic:Part" xmi:id="_WAjPkCkTEein5vuhpK-Dew" elementId="org.argeo.cms.e4.jcrbrowser" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrBrowserView" label="JCR" iconURI="platform:/plugin/org.argeo.cms.swt/icons/browser.gif">
+              <menus xsi:type="menu:PopupMenu" xmi:id="_eXiUECqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.popupmenu.nodeViewer">
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_GVeO8CqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.refresh" label="Refresh" iconURI="platform:/plugin/org.argeo.cms.swt/icons/refresh.png" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_fU238CqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.addfoldernode" label="Add folder" iconURI="platform:/plugin/org.argeo.cms.swt/icons/addFolder.gif" command="_RgE5cCqREeidr6NYQH6GbQ"/>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_U4o9cCqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.rename" label="Rename" iconURI="platform:/plugin/org.argeo.cms.swt/icons/rename.gif" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_Ncxo0CqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.remove" label="Remove" iconURI="platform:/plugin/org.argeo.cms.swt/icons/remove.gif" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
+              </menus>
+              <menus xmi:id="_oRg_ACqTEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.menu.0">
+                <tags>ViewMenu</tags>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_yJR8ECqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.refresh" label="Refresh" iconURI="platform:/plugin/org.argeo.cms.swt/icons/refresh.png" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_o6HQECqTEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.addfoldernode" label="Add folder" iconURI="platform:/plugin/org.argeo.cms.swt/icons/addFolder.gif" command="_RgE5cCqREeidr6NYQH6GbQ"/>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_5D7aACqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.rename" label="Rename" iconURI="platform:/plugin/org.argeo.cms.swt/icons/rename.gif" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_7rR2wCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/remove.gif" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
+                <children xsi:type="menu:HandledMenuItem" xmi:id="_XsHLgFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledmenuitem.0" iconURI="platform:/plugin/org.argeo.cms.swt/icons/addRepo.gif" command="_ZWpasFgQEeiknZQLx-vtnA"/>
+              </menus>
+            </children>
+          </children>
+          <children xsi:type="basic:PartStack" xmi:id="_mHrEUCk4Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.partstack.1" containerData="6000">
+            <tags>dataExplorer</tags>
+          </children>
+        </children>
+      </children>
+      <children xsi:type="advanced:Perspective" xmi:id="_u5ZakFhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.perspective.monitoring" label="Monitoring" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif">
+        <children xsi:type="basic:PartStack" xmi:id="_7i7t8FhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.partstack.6">
+          <children xsi:type="basic:Part" xmi:id="_Z-3cMFhbEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.osgiConfigurations" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.OsgiConfigurationsView" label="OSGi Configurations" iconURI="platform:/plugin/org.argeo.cms.swt/icons/node.gif"/>
+          <children xsi:type="basic:Part" xmi:id="_8dM90FhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.cmsSessions" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.CmsSessionsView" label="CMS Sessions" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person-logged-in.png"/>
+          <children xsi:type="basic:Part" xmi:id="_KqRZIFhNEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.modules" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.ModulesView" label="Modules" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif"/>
+          <children xsi:type="basic:Part" xmi:id="_dXtIoFhNEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.bundles" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.BundlesView" label="Bundles" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif"/>
+        </children>
+      </children>
+      <children xsi:type="advanced:Perspective" xmi:id="_ABK2ADsNEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.perspective.files" label="Files" iconURI="platform:/plugin/org.argeo.cms.swt/icons/file.gif">
+        <children xsi:type="basic:PartSashContainer" xmi:id="_FPimEDsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.partsashcontainer.1" horizontal="true">
+          <children xsi:type="basic:PartStack" xmi:id="_H93NgDsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.partstack.2" containerData="4000">
+            <children xsi:type="basic:Part" xmi:id="_Izxh0DsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.part.files" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.files.NodeFsBrowserView" label="Files" iconURI="platform:/plugin/org.argeo.cms.swt/icons/file.gif"/>
+          </children>
+          <children xsi:type="basic:Part" xmi:id="_TMqBMDsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.part.0" containerData="6000"/>
+        </children>
+      </children>
+    </children>
+    <handlers xmi:id="_Vwax0DvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.8" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.handlers.OpenPerspective" command="_AF1UsDvrEeiF1foPJZSZkw"/>
+    <trimBars xmi:id="_euVxMCk2Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.trimbar.0" side="Left">
+      <children xsi:type="menu:ToolBar" xmi:id="_fotHsCk2Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.toolbar.0">
+        <children xsi:type="menu:HandledToolItem" xmi:id="_jCSQgDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.users" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png" command="_AF1UsDvrEeiF1foPJZSZkw">
+          <tags>auth.cn=admin,ou=roles,ou=node</tags>
+          <parameters xmi:id="_lu_uYDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.parameter.2" name="perspectiveId" value="org.argeo.cms.e4.perspective.users"/>
+        </children>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_jfUM4Ck2Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.handledtoolitem.test" label="Data" iconURI="platform:/plugin/org.argeo.cms.swt/icons/nodes.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
+          <parameters xmi:id="_KDlXQDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.parameter.0" name="perspectiveId" value="org.argeo.cms.e4.perspective.data"/>
+        </children>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_dhv80FhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledtoolitem.monitoring" label="Monitoring" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
+          <parameters xmi:id="_kjN0cFhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.parameter.3" name="perspectiveId" value="org.argeo.cms.e4.perspective.monitoring"/>
+        </children>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_b0OHUDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.files" label="Files" iconURI="platform:/plugin/org.argeo.cms.swt/icons/file.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
+          <parameters xmi:id="_fXvRYDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.parameter.1" name="perspectiveId" value="org.argeo.cms.e4.perspective.files"/>
+        </children>
+        <children xsi:type="menu:ToolBarSeparator" xmi:id="_wuoL8FhLEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.toolbarseparator.0"/>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_2v8DkFhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledtoolitem.logout" label="Log out" iconURI="platform:/plugin/org.argeo.cms.swt/icons/logout.png" command="_PsWd0FhLEeiknZQLx-vtnA"/>
+      </children>
+    </trimBars>
+  </children>
+  <handlers xmi:id="_Xp-P4CqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.0" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.AddFolderNode" command="_RgE5cCqREeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_jbnNwCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.1" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.DeleteNodes" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_loxB0CqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.2" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.Refresh" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_omPfkCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.3" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.RenameNode" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
+  <handlers xmi:id="_dUg-cFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handler.9" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.AddRemoteRepository" command="_ZWpasFgQEeiknZQLx-vtnA"/>
+  <handlers xmi:id="_RQyFAFhLEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handler.10" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.handlers.CloseWorkbench" command="_PsWd0FhLEeiknZQLx-vtnA"/>
+  <descriptors xmi:id="_XzfoMCqlEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.partdescriptor.nodeEditor" label="Node Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/node.gif" allowMultiple="true" category="dataExplorer" closeable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrNodeEditor"/>
+  <descriptors xmi:id="_sAdNwDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.userEditor" label="User Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UserEditor"/>
+  <descriptors xmi:id="_5nK7EDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.groupEditor" label="Group Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupEditor"/>
+  <commands xmi:id="_RgE5cCqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.addFolderNode" commandName="Add folder node" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
+  <commands xmi:id="_ChJ-4CqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.deleteNodes" commandName="Delete nodes" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
+  <commands xmi:id="_TOKHsCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.refreshNodes" commandName="Refresh nodes" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
+  <commands xmi:id="_ZrcUMCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.renameNode" commandName="Rename node" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
+  <commands xmi:id="_uL5i4DvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.command.add" commandName="Add"/>
+  <commands xmi:id="_xkcMADvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.command.delete" commandName="Delete"/>
+  <commands xmi:id="_AF1UsDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.command.openPerspective" commandName="Open Perspective">
+    <parameters xmi:id="_F3WAUDvrEeiF1foPJZSZkw" elementId="perspectiveId" name="Perspective Id" optional="false"/>
+  </commands>
+  <commands xmi:id="_ZWpasFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.command.addRemoteRepository" commandName="Add Remote Repository"/>
+  <commands xmi:id="_PsWd0FhLEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.command.logout" commandName="Log out"/>
+  <addons xmi:id="_XqkCQaknEeObFrG_clJBYA" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
+  <addons xmi:id="_XqkCQqknEeObFrG_clJBYA" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
+  <addons xmi:id="_XqkCQ6knEeObFrG_clJBYA" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>
+  <addons xmi:id="_XqkCRKknEeObFrG_clJBYA" elementId="org.eclipse.e4.ui.workbench.commands.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon"/>
+  <addons xmi:id="_XqkCRaknEeObFrG_clJBYA" elementId="org.eclipse.e4.ui.workbench.contexts.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon"/>
+  <addons xmi:id="_XqkCRqknEeObFrG_clJBYA" elementId="org.eclipse.e4.ui.workbench.bindings.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench.swt/org.eclipse.e4.ui.workbench.swt.util.BindingProcessingAddon"/>
+  <addons xmi:id="_XqkCR6knEeObFrG_clJBYA" elementId="org.eclipse.e4.ui.workbench.handler.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon"/>
+  <addons xmi:id="_8VnK8OdKEeijEOqYKRSeoQ" elementId="org.argeo.cms.e4.addon.locale" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.addons.LocaleAddon"/>
+  <addons xmi:id="_-xeJYOdKEeijEOqYKRSeoQ" elementId="org.argeo.cms.e4.addon.auth" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.addons.AuthAddon"/>
+  <categories xmi:id="_MDkwUCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.category.jcrBrowser" name="JCR Browser"/>
+</application:Application>
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java
new file mode 100644 (file)
index 0000000..aabfbf5
--- /dev/null
@@ -0,0 +1,47 @@
+package org.argeo.cms.e4.files;
+
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.spi.FileSystemProvider;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.argeo.eclipse.ui.fs.SimpleFsBrowser;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/** Browse the node file system. */
+public class NodeFsBrowserView {
+       // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID +
+       // ".nodeFsBrowserView";
+
+       @Inject
+       FileSystemProvider nodeFileSystemProvider;
+
+       @PostConstruct
+       public void createPartControl(Composite parent) {
+               try {
+                       // URI uri = new URI("node://root:demo@localhost:7070/");
+                       URI uri = new URI("node:///");
+                       FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri);
+                       if (fileSystem == null)
+                               fileSystem = nodeFileSystemProvider.newFileSystem(uri, null);
+                       Path nodePath = fileSystem.getPath("/");
+
+                       Path localPath = Paths.get(System.getProperty("user.home"));
+
+                       SimpleFsBrowser browser = new SimpleFsBrowser(parent, SWT.NO_FOCUS);
+                       browser.setInput(nodePath, localPath);
+//                     AdvancedFsBrowser browser = new AdvancedFsBrowser();
+//                     browser.createUi(parent, localPath);
+               } catch (Exception e) {
+                       throw new RuntimeException("Cannot open file system browser", e);
+               }
+       }
+
+       public void setFocus() {
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/package-info.java
new file mode 100644 (file)
index 0000000..b481dd4
--- /dev/null
@@ -0,0 +1,2 @@
+/** Files browser perspective. */
+package org.argeo.cms.e4.files;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundleNode.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundleNode.java
new file mode 100644 (file)
index 0000000..e953683
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.cms.e4.monitoring;
+
+import org.argeo.cms.ux.widgets.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/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundlesView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundlesView.java
new file mode 100644 (file)
index 0000000..c639255
--- /dev/null
@@ -0,0 +1,114 @@
+//package org.argeo.eclipse.ui.workbench.osgi;
+//public class BundlesView {}
+
+package org.argeo.cms.e4.monitoring;
+
+import javax.annotation.PostConstruct;
+
+import org.argeo.eclipse.ui.ColumnViewerComparator;
+import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
+import org.eclipse.e4.ui.di.Focus;
+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.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Overview of the bundles as a table. Equivalent to Equinox 'ss' console
+ * command.
+ */
+public class BundlesView {
+       private final static BundleContext bc = FrameworkUtil.getBundle(BundlesView.class).getBundleContext();
+       private TableViewer viewer;
+
+       @PostConstruct
+       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(250);
+               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(bc);
+
+       }
+
+       @Focus
+       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/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/CmsSessionsView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/CmsSessionsView.java
new file mode 100644 (file)
index 0000000..95b1eb2
--- /dev/null
@@ -0,0 +1,173 @@
+//package org.argeo.eclipse.ui.workbench.osgi;
+//public class BundlesView {}
+
+package org.argeo.cms.e4.monitoring;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+
+import org.argeo.api.cms.CmsSession;
+import org.argeo.cms.auth.RoleNameUtils;
+import org.argeo.eclipse.ui.ColumnViewerComparator;
+import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
+import org.argeo.util.LangUtils;
+import org.eclipse.e4.ui.di.Focus;
+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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Overview of the active CMS sessions.
+ */
+public class CmsSessionsView {
+       private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionsView.class).getBundleContext();
+
+       private TableViewer viewer;
+
+       @PostConstruct
+       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).getDisplayName();
+                       }
+
+                       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) {
+                               String userDn = ((CmsSession) element).getUserDn();
+                               return RoleNameUtils.getLastRdnValue(userDn);
+                       }
+
+                       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(bc);
+
+       }
+
+       @Focus
+       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<ServiceReference<CmsSession>> srs;
+                               try {
+                                       srs = bc.getServiceReferences(CmsSession.class, null);
+                               } catch (InvalidSyntaxException e) {
+                                       throw new IllegalArgumentException("Cannot retrieve CMS sessions", e);
+                               }
+                               List<CmsSession> res = new ArrayList<>();
+                               for (ServiceReference<CmsSession> 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/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ModulesView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ModulesView.java
new file mode 100644 (file)
index 0000000..6317882
--- /dev/null
@@ -0,0 +1,91 @@
+package org.argeo.cms.e4.monitoring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+
+import org.argeo.cms.ux.widgets.TreeParent;
+import org.eclipse.e4.ui.di.Focus;
+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.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+/** The OSGi runtime from a module perspective. */
+public class ModulesView {
+       private final static BundleContext bc = FrameworkUtil.getBundle(ModulesView.class).getBundleContext();
+       private TreeViewer viewer;
+
+       @PostConstruct
+       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(bc);
+       }
+
+       @Focus
+       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<BundleNode> modules = new ArrayList<BundleNode>();
+                               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/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiConfigurationsView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiConfigurationsView.java
new file mode 100644 (file)
index 0000000..5db8bd1
--- /dev/null
@@ -0,0 +1,163 @@
+package org.argeo.cms.e4.monitoring;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+
+import org.argeo.cms.swt.CmsException;
+import org.argeo.util.LangUtils;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class OsgiConfigurationsView {
+       private final static BundleContext bc = FrameworkUtil.getBundle(OsgiConfigurationsView.class).getBundleContext();
+
+       @PostConstruct
+       public void createPartControl(Composite parent) {
+               ConfigurationAdmin configurationAdmin = bc.getService(bc.getServiceReference(ConfigurationAdmin.class));
+
+               TreeViewer viewer = new TreeViewer(parent);
+               // viewer.getTree().setHeaderVisible(true);
+
+               TreeViewerColumn tvc = new TreeViewerColumn(viewer, SWT.NONE);
+               tvc.getColumn().setWidth(400);
+               tvc.setLabelProvider(new ColumnLabelProvider() {
+                       private static final long serialVersionUID = 835407996597566763L;
+
+                       @Override
+                       public String getText(Object element) {
+                               if (element instanceof Configuration) {
+                                       return ((Configuration) element).getPid();
+                               } else if (element instanceof Prop) {
+                                       return ((Prop) element).key;
+                               }
+                               return super.getText(element);
+                       }
+
+                       @Override
+                       public Image getImage(Object element) {
+                               if (element instanceof Configuration)
+                                       return OsgiExplorerImages.CONFIGURATION;
+                               return null;
+                       }
+
+               });
+
+               tvc = new TreeViewerColumn(viewer, SWT.NONE);
+               tvc.getColumn().setWidth(400);
+               tvc.setLabelProvider(new ColumnLabelProvider() {
+                       private static final long serialVersionUID = 6999659261190014687L;
+
+                       @Override
+                       public String getText(Object element) {
+                               if (element instanceof Configuration) {
+                                       // return ((Configuration) element).getFactoryPid();
+                                       return null;
+                               } else if (element instanceof Prop) {
+                                       return ((Prop) element).value.toString();
+                               }
+                               return super.getText(element);
+                       }
+               });
+
+               viewer.setContentProvider(new ConfigurationsContentProvider());
+               viewer.setInput(configurationAdmin);
+       }
+
+       static class ConfigurationsContentProvider implements ITreeContentProvider {
+               private static final long serialVersionUID = -4892768279440981042L;
+               private ConfigurationComparator configurationComparator = new ConfigurationComparator();
+
+               @Override
+               public void dispose() {
+               }
+
+               @Override
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               }
+
+               @Override
+               public Object[] getElements(Object inputElement) {
+                       ConfigurationAdmin configurationAdmin = (ConfigurationAdmin) inputElement;
+                       try {
+                               Configuration[] configurations = configurationAdmin.listConfigurations(null);
+                               Arrays.sort(configurations, configurationComparator);
+                               return configurations;
+                       } catch (IOException | InvalidSyntaxException e) {
+                               throw new CmsException("Cannot list configurations", e);
+                       }
+               }
+
+               @Override
+               public Object[] getChildren(Object parentElement) {
+                       if (parentElement instanceof Configuration) {
+                               List<Prop> res = new ArrayList<>();
+                               Configuration configuration = (Configuration) parentElement;
+                               Dictionary<String, Object> props = configuration.getProperties();
+                               keys: for (String key : LangUtils.keys(props)) {
+                                       if (Constants.SERVICE_PID.equals(key))
+                                               continue keys;
+                                       if (ConfigurationAdmin.SERVICE_FACTORYPID.equals(key))
+                                               continue keys;
+                                       res.add(new Prop(configuration, key, props.get(key)));
+                               }
+                               return res.toArray(new Prop[res.size()]);
+                       }
+                       return null;
+               }
+
+               @Override
+               public Object getParent(Object element) {
+                       if (element instanceof Prop)
+                               return ((Prop) element).configuration;
+                       return null;
+               }
+
+               @Override
+               public boolean hasChildren(Object element) {
+                       if (element instanceof Configuration)
+                               return true;
+                       return false;
+               }
+
+       }
+
+       static class Prop {
+               final Configuration configuration;
+               final String key;
+               final Object value;
+
+               public Prop(Configuration configuration, String key, Object value) {
+                       this.configuration = configuration;
+                       this.key = key;
+                       this.value = value;
+               }
+
+       }
+
+       static class ConfigurationComparator implements Comparator<Configuration> {
+
+               @Override
+               public int compare(Configuration o1, Configuration o2) {
+                       return o1.getPid().compareTo(o2.getPid());
+               }
+
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiExplorerImages.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiExplorerImages.java
new file mode 100644 (file)
index 0000000..7217fe6
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.cms.e4.monitoring;
+
+import org.argeo.cms.ui.theme.CmsImages;
+import org.eclipse.swt.graphics.Image;
+
+/** Shared icons. */
+public class OsgiExplorerImages extends CmsImages {
+       public final static Image INSTALLED = createIcon("installed.gif");
+       public final static Image RESOLVED = createIcon("resolved.gif");
+       public final static Image STARTING = createIcon("starting.gif");
+       public final static Image ACTIVE = createIcon("active.gif");
+       public final static Image SERVICE_PUBLISHED = createIcon("service_published.gif");
+       public final static Image SERVICE_REFERENCED = createIcon("service_referenced.gif");
+       public final static Image CONFIGURATION = createIcon("node.gif");
+}
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ServiceReferenceNode.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ServiceReferenceNode.java
new file mode 100644 (file)
index 0000000..1c60811
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.cms.e4.monitoring;
+
+import org.argeo.cms.ux.widgets.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/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/StateLabelProvider.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/StateLabelProvider.java
new file mode 100644 (file)
index 0000000..5cb5b65
--- /dev/null
@@ -0,0 +1,82 @@
+package org.argeo.cms.e4.monitoring;
+
+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 "<<LAZY>>";
+                       return "STARTING";
+               case Bundle.STOPPING:
+                       return "STOPPING";
+               case Bundle.ACTIVE:
+                       return "ACTIVE";
+               default:
+                       return null;
+               }
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/package-info.java
new file mode 100644 (file)
index 0000000..873bf31
--- /dev/null
@@ -0,0 +1,2 @@
+/** Monitoring perspective. */
+package org.argeo.cms.e4.monitoring;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/parts/EgoDashboard.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/parts/EgoDashboard.java
new file mode 100644 (file)
index 0000000..f2a73f2
--- /dev/null
@@ -0,0 +1,41 @@
+package org.argeo.cms.e4.parts;
+
+import java.time.ZonedDateTime;
+
+import javax.annotation.PostConstruct;
+
+import org.argeo.api.cms.CmsSession;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+/** A canonical view of the logged in user. */
+public class EgoDashboard {
+//     private BundleContext bc = FrameworkUtil.getBundle(EgoDashboard.class).getBundleContext();
+
+       @PostConstruct
+       public void createPartControl(Composite p) {
+               p.setLayout(new GridLayout());
+               String username = CurrentUser.getUsername();
+
+               CmsSwtUtils.lbl(p, "<strong>" + CurrentUser.getDisplayName() + "</strong>");
+               CmsSwtUtils.txt(p, username);
+               CmsSwtUtils.lbl(p, "Roles:");
+               roles: for (String role : CurrentUser.roles()) {
+                       if (username.equals(role))
+                               continue roles;
+                       CmsSwtUtils.txt(p, role);
+               }
+
+//             Subject subject = Subject.getSubject(AccessController.getContext());
+//             if (subject != null) {
+               CmsSession cmsSession = CurrentUser.getCmsSession();
+               ZonedDateTime loggedIndSince = cmsSession.getCreationTime();
+               CmsSwtUtils.lbl(p, "Session:");
+               CmsSwtUtils.txt(p, cmsSession.getUuid().toString());
+               CmsSwtUtils.lbl(p, "Logged in since:");
+               CmsSwtUtils.txt(p, loggedIndSince.toString());
+//             }
+       }
+}
index d54f8bc388803ba40c4aa10eab33256aea48fcfa..80c5998e3886142729a284e482241a7b8518282b 100644 (file)
@@ -25,11 +25,11 @@ import org.argeo.cms.e4.users.providers.RoleIconLP;
 import org.argeo.cms.e4.users.providers.UserFilter;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.useradmin.LdifUsersTable;
 import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
 import org.argeo.cms.ui.eclipse.forms.IManagedForm;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.util.naming.LdapAttrs;
index 73e4f5d11900f063fd587df6dc283267d59f4d52..84a279e78a4c84d0da86dbad56de020d8ede4cde 100644 (file)
@@ -15,6 +15,7 @@ import org.argeo.cms.e4.users.providers.DomainNameLP;
 import org.argeo.cms.e4.users.providers.RoleIconLP;
 import org.argeo.cms.e4.users.providers.UserDragListener;
 import org.argeo.cms.swt.CmsException;
+import org.argeo.cms.swt.useradmin.LdifUsersTable;
 //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;
@@ -25,7 +26,6 @@ import org.argeo.cms.swt.CmsException;
 //import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.util.naming.LdapAttrs;
 import org.argeo.util.naming.LdapObjs;
 import org.eclipse.e4.ui.di.Focus;
index 4fc59d30d5c47e1754bdcb0ef7002f248507c914..6f075f157aaf697d530c5be68e60c2c6761950a9 100644 (file)
@@ -14,9 +14,9 @@ import org.argeo.cms.e4.users.providers.DomainNameLP;
 import org.argeo.cms.e4.users.providers.MailLP;
 import org.argeo.cms.e4.users.providers.UserNameLP;
 import org.argeo.cms.swt.CmsException;
+import org.argeo.cms.swt.useradmin.LdifUsersTable;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.util.naming.LdapAttrs;
 import org.argeo.util.naming.LdapObjs;
 import org.argeo.util.transaction.WorkTransaction;
index 66f442082191a10f1161ea9cce546810d87700e5..fb443e384558658c95d0767525615edbb5167437 100644 (file)
@@ -21,12 +21,12 @@ import org.argeo.cms.e4.users.providers.DomainNameLP;
 import org.argeo.cms.e4.users.providers.RoleIconLP;
 import org.argeo.cms.e4.users.providers.UserFilter;
 import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.useradmin.LdifUsersTable;
 import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
 //import org.argeo.cms.ui.eclipse.forms.FormToolkit;
 import org.argeo.cms.ui.eclipse.forms.IManagedForm;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.util.naming.LdapAttrs;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.jface.action.Action;
index 720945c4ca144dcef475b424d7c18b89055e51c1..1d7c873ff44ef7da44ce4d9b24f54c8c6612402f 100644 (file)
@@ -15,9 +15,9 @@ import org.argeo.cms.e4.users.providers.MailLP;
 import org.argeo.cms.e4.users.providers.UserDragListener;
 import org.argeo.cms.e4.users.providers.UserNameLP;
 import org.argeo.cms.swt.CmsException;
+import org.argeo.cms.swt.useradmin.LdifUsersTable;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.util.naming.LdapAttrs;
 import org.argeo.util.naming.LdapObjs;
 import org.eclipse.e4.ui.di.Focus;
diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/jcr/e4/rap/CmsE4AdminApp.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/jcr/e4/rap/CmsE4AdminApp.java
new file mode 100644 (file)
index 0000000..de497b4
--- /dev/null
@@ -0,0 +1,17 @@
+package org.argeo.cms.jcr.e4.rap;
+
+import org.argeo.cms.e4.rap.AbstractRapE4App;
+import org.eclipse.rap.rwt.application.Application;
+
+/**
+ * Access to canonical views of the core CMS concepts, useful for devleopers and
+ * operators.
+ */
+public class CmsE4AdminApp extends AbstractRapE4App {
+       @Override
+       protected void addEntryPoints(Application application) {
+               addE4EntryPoint(application, "/devops", "org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi",
+                               customise("Argeo CMS DevOps"));
+       }
+
+}
diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/add.png b/swt/org.argeo.cms.jcr.ui/icons/actions/add.png
new file mode 100644 (file)
index 0000000..5c06bf0
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/add.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/close-all.png b/swt/org.argeo.cms.jcr.ui/icons/actions/close-all.png
new file mode 100644 (file)
index 0000000..81bfc95
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/close-all.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/delete.png b/swt/org.argeo.cms.jcr.ui/icons/actions/delete.png
new file mode 100644 (file)
index 0000000..9712723
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/delete.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/edit.png b/swt/org.argeo.cms.jcr.ui/icons/actions/edit.png
new file mode 100644 (file)
index 0000000..ad3db9f
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/edit.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/save-all.png b/swt/org.argeo.cms.jcr.ui/icons/actions/save-all.png
new file mode 100644 (file)
index 0000000..f48ed32
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/save-all.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/save.png b/swt/org.argeo.cms.jcr.ui/icons/actions/save.png
new file mode 100644 (file)
index 0000000..1c58ada
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/save.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/active.gif b/swt/org.argeo.cms.jcr.ui/icons/active.gif
new file mode 100644 (file)
index 0000000..7d24707
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/active.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/add.gif b/swt/org.argeo.cms.jcr.ui/icons/add.gif
new file mode 100644 (file)
index 0000000..252d7eb
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/add.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/add.png b/swt/org.argeo.cms.jcr.ui/icons/add.png
new file mode 100644 (file)
index 0000000..c7edfec
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/add.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/addFolder.gif b/swt/org.argeo.cms.jcr.ui/icons/addFolder.gif
new file mode 100644 (file)
index 0000000..d3f43d9
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addFolder.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/addPrivileges.gif b/swt/org.argeo.cms.jcr.ui/icons/addPrivileges.gif
new file mode 100644 (file)
index 0000000..a6b251f
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addPrivileges.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/addRepo.gif b/swt/org.argeo.cms.jcr.ui/icons/addRepo.gif
new file mode 100644 (file)
index 0000000..26d81c0
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addRepo.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/addWorkspace.png b/swt/org.argeo.cms.jcr.ui/icons/addWorkspace.png
new file mode 100644 (file)
index 0000000..bbee775
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addWorkspace.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/adminLog.gif b/swt/org.argeo.cms.jcr.ui/icons/adminLog.gif
new file mode 100644 (file)
index 0000000..6ef3bca
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/adminLog.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/batch.gif b/swt/org.argeo.cms.jcr.ui/icons/batch.gif
new file mode 100644 (file)
index 0000000..b8ca14a
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/batch.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/begin.gif b/swt/org.argeo.cms.jcr.ui/icons/begin.gif
new file mode 100755 (executable)
index 0000000..feb8e94
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/begin.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/binary.png b/swt/org.argeo.cms.jcr.ui/icons/binary.png
new file mode 100644 (file)
index 0000000..fdf4f82
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/binary.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/browser.gif b/swt/org.argeo.cms.jcr.ui/icons/browser.gif
new file mode 100644 (file)
index 0000000..6c7320c
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/browser.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/bundles.gif b/swt/org.argeo.cms.jcr.ui/icons/bundles.gif
new file mode 100644 (file)
index 0000000..e9a6bd9
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/bundles.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/changePassword.gif b/swt/org.argeo.cms.jcr.ui/icons/changePassword.gif
new file mode 100644 (file)
index 0000000..274a850
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/changePassword.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/clear.gif b/swt/org.argeo.cms.jcr.ui/icons/clear.gif
new file mode 100644 (file)
index 0000000..6bc10f9
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/clear.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/close-all.png b/swt/org.argeo.cms.jcr.ui/icons/close-all.png
new file mode 100644 (file)
index 0000000..85d4d42
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/close-all.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/commit.gif b/swt/org.argeo.cms.jcr.ui/icons/commit.gif
new file mode 100755 (executable)
index 0000000..876f3eb
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/commit.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/delete.png b/swt/org.argeo.cms.jcr.ui/icons/delete.png
new file mode 100644 (file)
index 0000000..676a39d
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/delete.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/dumpNode.gif b/swt/org.argeo.cms.jcr.ui/icons/dumpNode.gif
new file mode 100644 (file)
index 0000000..14eb1be
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/dumpNode.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/file.gif b/swt/org.argeo.cms.jcr.ui/icons/file.gif
new file mode 100644 (file)
index 0000000..ef30288
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/file.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/folder.gif b/swt/org.argeo.cms.jcr.ui/icons/folder.gif
new file mode 100644 (file)
index 0000000..42e027c
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/folder.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/getSize.gif b/swt/org.argeo.cms.jcr.ui/icons/getSize.gif
new file mode 100644 (file)
index 0000000..b05bf3e
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/getSize.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/group.png b/swt/org.argeo.cms.jcr.ui/icons/group.png
new file mode 100644 (file)
index 0000000..cc6683a
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/group.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/home.gif b/swt/org.argeo.cms.jcr.ui/icons/home.gif
new file mode 100644 (file)
index 0000000..fd0c669
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/home.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/home.png b/swt/org.argeo.cms.jcr.ui/icons/home.png
new file mode 100644 (file)
index 0000000..5eb0967
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/home.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/import_fs.png b/swt/org.argeo.cms.jcr.ui/icons/import_fs.png
new file mode 100644 (file)
index 0000000..d7c890c
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/import_fs.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/installed.gif b/swt/org.argeo.cms.jcr.ui/icons/installed.gif
new file mode 100644 (file)
index 0000000..2988716
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/installed.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/loading.gif b/swt/org.argeo.cms.jcr.ui/icons/loading.gif
deleted file mode 100644 (file)
index 3288d10..0000000
Binary files a/swt/org.argeo.cms.jcr.ui/icons/loading.gif and /dev/null differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/log.gif b/swt/org.argeo.cms.jcr.ui/icons/log.gif
new file mode 100644 (file)
index 0000000..e3ecc55
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/log.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/logout.png b/swt/org.argeo.cms.jcr.ui/icons/logout.png
new file mode 100644 (file)
index 0000000..f2952fa
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/logout.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/maintenance.gif b/swt/org.argeo.cms.jcr.ui/icons/maintenance.gif
new file mode 100644 (file)
index 0000000..e5690ec
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/maintenance.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png b/swt/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png
deleted file mode 100644 (file)
index 0396506..0000000
Binary files a/swt/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png and /dev/null differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png b/swt/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png
deleted file mode 100644 (file)
index 8e3abb5..0000000
Binary files a/swt/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png and /dev/null differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/node.gif b/swt/org.argeo.cms.jcr.ui/icons/node.gif
new file mode 100644 (file)
index 0000000..364c0e7
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/node.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/nodes.gif b/swt/org.argeo.cms.jcr.ui/icons/nodes.gif
new file mode 100644 (file)
index 0000000..bba3dbc
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/nodes.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/osgi_explorer.gif b/swt/org.argeo.cms.jcr.ui/icons/osgi_explorer.gif
new file mode 100644 (file)
index 0000000..e9a6bd9
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/osgi_explorer.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/password.gif b/swt/org.argeo.cms.jcr.ui/icons/password.gif
new file mode 100644 (file)
index 0000000..a6b251f
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/password.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/person-logged-in.png b/swt/org.argeo.cms.jcr.ui/icons/person-logged-in.png
new file mode 100644 (file)
index 0000000..87acc14
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/person-logged-in.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/person.png b/swt/org.argeo.cms.jcr.ui/icons/person.png
new file mode 100644 (file)
index 0000000..7d979a5
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/person.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/query.png b/swt/org.argeo.cms.jcr.ui/icons/query.png
new file mode 100644 (file)
index 0000000..54c089d
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/query.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/refresh.png b/swt/org.argeo.cms.jcr.ui/icons/refresh.png
new file mode 100644 (file)
index 0000000..71b3481
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/refresh.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/remote_connected.gif b/swt/org.argeo.cms.jcr.ui/icons/remote_connected.gif
new file mode 100644 (file)
index 0000000..1492b4e
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/remote_connected.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/remote_disconnected.gif b/swt/org.argeo.cms.jcr.ui/icons/remote_disconnected.gif
new file mode 100644 (file)
index 0000000..6c54da9
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/remote_disconnected.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/remove.gif b/swt/org.argeo.cms.jcr.ui/icons/remove.gif
new file mode 100644 (file)
index 0000000..0ae6dec
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/remove.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/removePrivileges.gif b/swt/org.argeo.cms.jcr.ui/icons/removePrivileges.gif
new file mode 100644 (file)
index 0000000..aa78fd2
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/removePrivileges.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/rename.gif b/swt/org.argeo.cms.jcr.ui/icons/rename.gif
new file mode 100644 (file)
index 0000000..8048405
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/rename.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/repositories.gif b/swt/org.argeo.cms.jcr.ui/icons/repositories.gif
new file mode 100644 (file)
index 0000000..c13bea1
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/repositories.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/repository_connected.gif b/swt/org.argeo.cms.jcr.ui/icons/repository_connected.gif
new file mode 100644 (file)
index 0000000..a15fa55
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/repository_connected.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/repository_disconnected.gif b/swt/org.argeo.cms.jcr.ui/icons/repository_disconnected.gif
new file mode 100644 (file)
index 0000000..4576dc5
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/repository_disconnected.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/resolved.gif b/swt/org.argeo.cms.jcr.ui/icons/resolved.gif
new file mode 100644 (file)
index 0000000..f4a1ea1
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/resolved.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/role.gif b/swt/org.argeo.cms.jcr.ui/icons/role.gif
new file mode 100644 (file)
index 0000000..274a850
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/role.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/rollback.gif b/swt/org.argeo.cms.jcr.ui/icons/rollback.gif
new file mode 100755 (executable)
index 0000000..c753995
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/rollback.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/save-all.png b/swt/org.argeo.cms.jcr.ui/icons/save-all.png
new file mode 100644 (file)
index 0000000..b68a29b
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save-all.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/save.gif b/swt/org.argeo.cms.jcr.ui/icons/save.gif
new file mode 100644 (file)
index 0000000..654ad7b
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/save.png b/swt/org.argeo.cms.jcr.ui/icons/save.png
new file mode 100644 (file)
index 0000000..f27ef2d
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/save_security.png b/swt/org.argeo.cms.jcr.ui/icons/save_security.png
new file mode 100644 (file)
index 0000000..ca41dc9
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save_security.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/save_security_disabled.png b/swt/org.argeo.cms.jcr.ui/icons/save_security_disabled.png
new file mode 100644 (file)
index 0000000..fb7d08d
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save_security_disabled.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/security.gif b/swt/org.argeo.cms.jcr.ui/icons/security.gif
new file mode 100644 (file)
index 0000000..57fb95e
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/security.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/service_published.gif b/swt/org.argeo.cms.jcr.ui/icons/service_published.gif
new file mode 100644 (file)
index 0000000..17f771a
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/service_published.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/service_referenced.gif b/swt/org.argeo.cms.jcr.ui/icons/service_referenced.gif
new file mode 100644 (file)
index 0000000..c24a95f
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/service_referenced.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/sort.gif b/swt/org.argeo.cms.jcr.ui/icons/sort.gif
new file mode 100644 (file)
index 0000000..23c5d0b
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/sort.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/starting.gif b/swt/org.argeo.cms.jcr.ui/icons/starting.gif
new file mode 100644 (file)
index 0000000..563743d
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/starting.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/sync.gif b/swt/org.argeo.cms.jcr.ui/icons/sync.gif
new file mode 100644 (file)
index 0000000..b4fa052
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/sync.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/user.gif b/swt/org.argeo.cms.jcr.ui/icons/user.gif
new file mode 100644 (file)
index 0000000..90a0014
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/user.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/users.gif b/swt/org.argeo.cms.jcr.ui/icons/users.gif
new file mode 100644 (file)
index 0000000..2de7edd
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/users.gif differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/workgroup.png b/swt/org.argeo.cms.jcr.ui/icons/workgroup.png
new file mode 100644 (file)
index 0000000..7fef996
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workgroup.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/workgroup.xcf b/swt/org.argeo.cms.jcr.ui/icons/workgroup.xcf
new file mode 100644 (file)
index 0000000..f517c82
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workgroup.xcf differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/workspace_connected.png b/swt/org.argeo.cms.jcr.ui/icons/workspace_connected.png
new file mode 100644 (file)
index 0000000..0430baa
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workspace_connected.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/icons/workspace_disconnected.png b/swt/org.argeo.cms.jcr.ui/icons/workspace_disconnected.png
new file mode 100644 (file)
index 0000000..fddcb8c
Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workspace_disconnected.png differ
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/LdifUsersTable.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/LdifUsersTable.java
new file mode 100644 (file)
index 0000000..a30d2f7
--- /dev/null
@@ -0,0 +1,401 @@
+package org.argeo.cms.swt.useradmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnWeightData;
+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.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.Composite;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.service.useradmin.User;
+
+/**
+ * Generic composite that display a filter and a table viewer to display users
+ * (can also be groups)
+ * 
+ * Warning: this class does not extends <code>TableViewer</code>. Use the
+ * getTableViewer method to access it.
+ * 
+ */
+public abstract class LdifUsersTable extends Composite {
+       private static final long serialVersionUID = -7385959046279360420L;
+
+       // Context
+       // private UserAdmin userAdmin;
+
+       // Configuration
+       private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
+       private boolean hasFilter;
+       private boolean preventTableLayout = false;
+       private boolean hasSelectionColumn;
+       private int tableStyle;
+
+       // Local UI Objects
+       private TableViewer usersViewer;
+       private Text filterTxt;
+
+       /* EXPOSED METHODS */
+
+       /**
+        * @param parent
+        * @param style
+        */
+       public LdifUsersTable(Composite parent, int style) {
+               super(parent, SWT.NO_FOCUS);
+               this.tableStyle = style;
+       }
+
+       // TODO workaround the bug of the table layout in the Form
+       public LdifUsersTable(Composite parent, int style, boolean preventTableLayout) {
+               super(parent, SWT.NO_FOCUS);
+               this.tableStyle = style;
+               this.preventTableLayout = preventTableLayout;
+       }
+
+       /** This must be called before the call to populate method */
+       public void setColumnDefinitions(List<ColumnDefinition> columnDefinitions) {
+               this.columnDefs = columnDefinitions;
+       }
+
+       /**
+        * 
+        * @param addFilter
+        *            choose to add a field to filter results or not
+        * @param addSelection
+        *            choose to add a column to select some of the displayed results or
+        *            not
+        */
+       public void populate(boolean addFilter, boolean addSelection) {
+               // initialization
+               Composite parent = this;
+               hasFilter = addFilter;
+               hasSelectionColumn = addSelection;
+
+               // Main Layout
+               GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
+               layout.verticalSpacing = 5;
+               this.setLayout(layout);
+               if (hasFilter)
+                       createFilterPart(parent);
+
+               Composite tableComp = new Composite(parent, SWT.NO_FOCUS);
+               tableComp.setLayoutData(EclipseUiUtils.fillAll());
+               usersViewer = createTableViewer(tableComp);
+               usersViewer.setContentProvider(new UsersContentProvider());
+       }
+
+       /**
+        * 
+        * @param showMore
+        *            display static filters on creation
+        * @param addSelection
+        *            choose to add a column to select some of the displayed results or
+        *            not
+        */
+       public void populateWithStaticFilters(boolean showMore, boolean addSelection) {
+               // initialization
+               Composite parent = this;
+               hasFilter = true;
+               hasSelectionColumn = addSelection;
+
+               // Main Layout
+               GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
+               layout.verticalSpacing = 5;
+               this.setLayout(layout);
+               createStaticFilterPart(parent, showMore);
+
+               Composite tableComp = new Composite(parent, SWT.NO_FOCUS);
+               tableComp.setLayoutData(EclipseUiUtils.fillAll());
+               usersViewer = createTableViewer(tableComp);
+               usersViewer.setContentProvider(new UsersContentProvider());
+       }
+
+       /** Enable access to the selected users or groups */
+       public List<User> getSelectedUsers() {
+               if (hasSelectionColumn) {
+                       Object[] elements = ((CheckboxTableViewer) usersViewer).getCheckedElements();
+
+                       List<User> result = new ArrayList<User>();
+                       for (Object obj : elements) {
+                               result.add((User) obj);
+                       }
+                       return result;
+               } else
+                       throw new EclipseUiException(
+                                       "Unvalid request: no selection column " + "has been created for the current table");
+       }
+
+       /** Returns the User table viewer, typically to add doubleclick listener */
+       public TableViewer getTableViewer() {
+               return usersViewer;
+       }
+
+       /**
+        * Force the refresh of the underlying table using the current filter string if
+        * relevant
+        */
+       public void refresh() {
+               String filter = hasFilter ? filterTxt.getText().trim() : null;
+               if ("".equals(filter))
+                       filter = null;
+               refreshFilteredList(filter);
+       }
+
+       /** Effective repository request: caller must implement this method */
+       abstract protected List<User> listFilteredElements(String filter);
+
+       // protected List<User> listFilteredElements(String filter) {
+       // List<User> users = new ArrayList<User>();
+       // try {
+       // Role[] roles = userAdmin.getRoles(filter);
+       // // Display all users and groups
+       // for (Role role : roles)
+       // users.add((User) role);
+       // } catch (InvalidSyntaxException e) {
+       // throw new EclipseUiException("Unable to get roles with filter: "
+       // + filter, e);
+       // }
+       // return users;
+       // }
+
+       /* GENERIC COMPOSITE METHODS */
+       @Override
+       public boolean setFocus() {
+               if (hasFilter)
+                       return filterTxt.setFocus();
+               else
+                       return usersViewer.getTable().setFocus();
+       }
+
+       @Override
+       public void dispose() {
+               super.dispose();
+       }
+
+       /* LOCAL CLASSES AND METHODS */
+       // Will be usefull to rather use a virtual table viewer
+       private void refreshFilteredList(String filter) {
+               List<User> users = listFilteredElements(filter);
+               usersViewer.setInput(users.toArray());
+       }
+
+       private class UsersContentProvider implements IStructuredContentProvider {
+               private static final long serialVersionUID = 1L;
+
+               public Object[] getElements(Object inputElement) {
+                       return (Object[]) inputElement;
+               }
+
+               public void dispose() {
+               }
+
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               }
+       }
+
+       /* MANAGE FILTER */
+       private void createFilterPart(Composite parent) {
+               // Text Area for the filter
+               filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
+               filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+               filterTxt.addModifyListener(new ModifyListener() {
+                       private static final long serialVersionUID = 1L;
+
+                       public void modifyText(ModifyEvent event) {
+                               refreshFilteredList(filterTxt.getText());
+                       }
+               });
+       }
+
+       private void createStaticFilterPart(Composite parent, boolean showMore) {
+               Composite filterComp = new Composite(parent, SWT.NO_FOCUS);
+               filterComp.setLayout(new GridLayout(2, false));
+               filterComp.setLayoutData(EclipseUiUtils.fillWidth());
+               // generic search
+               filterTxt = new Text(filterComp, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
+               filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+               // filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL |
+               // GridData.HORIZONTAL_ALIGN_FILL));
+               filterTxt.addModifyListener(new ModifyListener() {
+                       private static final long serialVersionUID = 1L;
+
+                       public void modifyText(ModifyEvent event) {
+                               refreshFilteredList(filterTxt.getText());
+                       }
+               });
+
+               // add static filter abilities
+               Link moreLk = new Link(filterComp, SWT.NONE);
+               Composite staticFilterCmp = new Composite(filterComp, SWT.NO_FOCUS);
+               staticFilterCmp.setLayoutData(EclipseUiUtils.fillWidth(2));
+               populateStaticFilters(staticFilterCmp);
+
+               MoreLinkListener listener = new MoreLinkListener(moreLk, staticFilterCmp, showMore);
+               // initialise the layout
+               listener.refresh();
+               moreLk.addSelectionListener(listener);
+       }
+
+       /** Overwrite to add static filters */
+       protected void populateStaticFilters(Composite staticFilterCmp) {
+       }
+
+       // private void addMoreSL(final Link more) {
+       // more.addSelectionListener( }
+
+       private class MoreLinkListener extends SelectionAdapter {
+               private static final long serialVersionUID = -524987616510893463L;
+               private boolean isShown;
+               private final Composite staticFilterCmp;
+               private final Link moreLk;
+
+               public MoreLinkListener(Link moreLk, Composite staticFilterCmp, boolean isShown) {
+                       this.moreLk = moreLk;
+                       this.staticFilterCmp = staticFilterCmp;
+                       this.isShown = isShown;
+               }
+
+               @Override
+               public void widgetSelected(SelectionEvent e) {
+                       isShown = !isShown;
+                       refresh();
+               }
+
+               public void refresh() {
+                       GridData gd = (GridData) staticFilterCmp.getLayoutData();
+                       if (isShown) {
+                               moreLk.setText("<a> Less... </a>");
+                               gd.heightHint = SWT.DEFAULT;
+                       } else {
+                               moreLk.setText("<a> More... </a>");
+                               gd.heightHint = 0;
+                       }
+                       forceLayout();
+               }
+       }
+
+       private void forceLayout() {
+               LdifUsersTable.this.getParent().layout(true, true);
+       }
+
+       private TableViewer createTableViewer(final Composite parent) {
+
+               int style = tableStyle | SWT.H_SCROLL | SWT.V_SCROLL;
+               if (hasSelectionColumn)
+                       style = style | SWT.CHECK;
+               Table table = new Table(parent, style);
+               TableColumnLayout layout = new TableColumnLayout();
+
+               // TODO the table layout does not works with the scrolled form
+
+               if (preventTableLayout) {
+                       parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+                       table.setLayoutData(EclipseUiUtils.fillAll());
+               } else
+                       parent.setLayout(layout);
+
+               TableViewer viewer;
+               if (hasSelectionColumn)
+                       viewer = new CheckboxTableViewer(table);
+               else
+                       viewer = new TableViewer(table);
+               table.setLinesVisible(true);
+               table.setHeaderVisible(true);
+
+               TableViewerColumn column;
+               // int offset = 0;
+               if (hasSelectionColumn) {
+                       // offset = 1;
+                       column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE, 25);
+                       column.setLabelProvider(new ColumnLabelProvider() {
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               public String getText(Object element) {
+                                       return null;
+                               }
+                       });
+                       layout.setColumnData(column.getColumn(), new ColumnWeightData(25, 25, false));
+
+                       SelectionAdapter selectionAdapter = new SelectionAdapter() {
+                               private static final long serialVersionUID = 1L;
+
+                               boolean allSelected = false;
+
+                               @Override
+                               public void widgetSelected(SelectionEvent e) {
+                                       allSelected = !allSelected;
+                                       ((CheckboxTableViewer) usersViewer).setAllChecked(allSelected);
+                               }
+                       };
+                       column.getColumn().addSelectionListener(selectionAdapter);
+               }
+
+               // NodeViewerComparator comparator = new NodeViewerComparator();
+               // TODO enable the sort by click on the header
+               // int i = offset;
+               for (ColumnDefinition colDef : columnDefs)
+                       createTableColumn(viewer, layout, colDef);
+
+               // column = ViewerUtils.createTableViewerColumn(viewer,
+               // colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize());
+               // column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
+               // column.getColumn().addSelectionListener(
+               // JcrUiUtils.getNodeSelectionAdapter(i,
+               // colDef.getPropertyType(), colDef.getPropertyName(),
+               // comparator, viewer));
+               // i++;
+               // }
+
+               // IMPORTANT: initialize comparator before setting it
+               // JcrColumnDefinition firstCol = colDefs.get(0);
+               // comparator.setColumn(firstCol.getPropertyType(),
+               // firstCol.getPropertyName());
+               // viewer.setComparator(comparator);
+
+               return viewer;
+       }
+
+       /** Default creation of a column for a user table */
+       private TableViewerColumn createTableColumn(TableViewer tableViewer, TableColumnLayout layout,
+                       ColumnDefinition columnDef) {
+
+               boolean resizable = true;
+               TableViewerColumn tvc = new TableViewerColumn(tableViewer, SWT.NONE);
+               TableColumn column = tvc.getColumn();
+
+               column.setText(columnDef.getLabel());
+               column.setWidth(columnDef.getMinWidth());
+               column.setResizable(resizable);
+
+               ColumnLabelProvider lp = columnDef.getLabelProvider();
+               // add a reference to the display to enable font management
+               // if (lp instanceof UserAdminAbstractLP)
+               // ((UserAdminAbstractLP) lp).setDisplay(tableViewer.getTable()
+               // .getDisplay());
+               tvc.setLabelProvider(lp);
+
+               layout.setColumnData(column, new ColumnWeightData(columnDef.getWeight(), columnDef.getMinWidth(), resizable));
+
+               return tvc;
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java
new file mode 100644 (file)
index 0000000..dbf6577
--- /dev/null
@@ -0,0 +1,245 @@
+package org.argeo.cms.swt.useradmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.LdapObjs;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+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.Shell;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+/** Dialog with a user (or group) list to pick up one */
+public class PickUpUserDialog extends TrayDialog {
+       private static final long serialVersionUID = -1420106871173920369L;
+
+       // Business objects
+       private final UserAdmin userAdmin;
+       private User selectedUser;
+
+       // this page widgets and UI objects
+       private String title;
+       private LdifUsersTable userTableViewerCmp;
+       private TableViewer userViewer;
+       private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
+
+       /**
+        * A dialog to pick up a group or a user, showing a table with default
+        * columns
+        */
+       public PickUpUserDialog(Shell parentShell, String title, UserAdmin userAdmin) {
+               super(parentShell);
+               this.title = title;
+               this.userAdmin = userAdmin;
+
+               columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_ICON), "",
+                               24, 24));
+               columnDefs.add(new ColumnDefinition(
+                               new UserLP(UserLP.COL_DISPLAY_NAME), "Common Name", 150, 100));
+               columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DOMAIN),
+                               "Domain", 100, 120));
+               columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DN),
+                               "Distinguished Name", 300, 100));
+       }
+
+       /** A dialog to pick up a group or a user */
+       public PickUpUserDialog(Shell parentShell, String title,
+                       UserAdmin userAdmin, List<ColumnDefinition> columnDefs) {
+               super(parentShell);
+               this.title = title;
+               this.userAdmin = userAdmin;
+               this.columnDefs = columnDefs;
+       }
+
+       @Override
+       protected void okPressed() {
+               if (getSelected() == null)
+                       MessageDialog.openError(getShell(), "No user chosen",
+                                       "Please, choose a user or press Cancel.");
+               else
+                       super.okPressed();
+       }
+
+       protected Control createDialogArea(Composite parent) {
+               Composite dialogArea = (Composite) super.createDialogArea(parent);
+               dialogArea.setLayout(new FillLayout());
+
+               Composite bodyCmp = new Composite(dialogArea, SWT.NO_FOCUS);
+               bodyCmp.setLayout(new GridLayout());
+
+               // Create and configure the table
+               userTableViewerCmp = new MyUserTableViewer(bodyCmp, SWT.MULTI
+                               | SWT.H_SCROLL | SWT.V_SCROLL);
+
+               userTableViewerCmp.setColumnDefinitions(columnDefs);
+               userTableViewerCmp.populateWithStaticFilters(false, false);
+               GridData gd = EclipseUiUtils.fillAll();
+               gd.minimumHeight = 300;
+               userTableViewerCmp.setLayoutData(gd);
+               userTableViewerCmp.refresh();
+
+               // Controllers
+               userViewer = userTableViewerCmp.getTableViewer();
+               userViewer.addDoubleClickListener(new MyDoubleClickListener());
+               userViewer
+                               .addSelectionChangedListener(new MySelectionChangedListener());
+
+               parent.pack();
+               return dialogArea;
+       }
+
+       public User getSelected() {
+               if (selectedUser == null)
+                       return null;
+               else
+                       return selectedUser;
+       }
+
+       protected void configureShell(Shell shell) {
+               super.configureShell(shell);
+               shell.setText(title);
+       }
+
+       class MyDoubleClickListener implements IDoubleClickListener {
+               public void doubleClick(DoubleClickEvent evt) {
+                       if (evt.getSelection().isEmpty())
+                               return;
+
+                       Object obj = ((IStructuredSelection) evt.getSelection())
+                                       .getFirstElement();
+                       if (obj instanceof User) {
+                               selectedUser = (User) obj;
+                               okPressed();
+                       }
+               }
+       }
+
+       class MySelectionChangedListener implements ISelectionChangedListener {
+               @Override
+               public void selectionChanged(SelectionChangedEvent event) {
+                       if (event.getSelection().isEmpty()) {
+                               selectedUser = null;
+                               return;
+                       }
+                       Object obj = ((IStructuredSelection) event.getSelection())
+                                       .getFirstElement();
+                       if (obj instanceof Group) {
+                               selectedUser = (Group) obj;
+                       }
+               }
+       }
+
+       private class MyUserTableViewer extends LdifUsersTable {
+               private static final long serialVersionUID = 8467999509931900367L;
+
+               private final String[] knownProps = { LdapAttrs.uid.name(),
+                               LdapAttrs.cn.name(), LdapAttrs.DN };
+
+               private Button showSystemRoleBtn;
+               private Button showUserBtn;
+
+               public MyUserTableViewer(Composite parent, int style) {
+                       super(parent, style);
+               }
+
+               protected void populateStaticFilters(Composite staticFilterCmp) {
+                       staticFilterCmp.setLayout(new GridLayout());
+                       showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK);
+                       showSystemRoleBtn.setText("Show system roles  ");
+
+                       showUserBtn = new Button(staticFilterCmp, SWT.CHECK);
+                       showUserBtn.setText("Show users  ");
+
+                       SelectionListener sl = new SelectionAdapter() {
+                               private static final long serialVersionUID = -7033424592697691676L;
+
+                               @Override
+                               public void widgetSelected(SelectionEvent e) {
+                                       refresh();
+                               }
+                       };
+
+                       showSystemRoleBtn.addSelectionListener(sl);
+                       showUserBtn.addSelectionListener(sl);
+               }
+
+               @Override
+               protected List<User> listFilteredElements(String filter) {
+                       Role[] roles;
+                       try {
+                               StringBuilder builder = new StringBuilder();
+
+                               StringBuilder filterBuilder = new StringBuilder();
+                               if (notNull(filter))
+                                       for (String prop : knownProps) {
+                                               filterBuilder.append("(");
+                                               filterBuilder.append(prop);
+                                               filterBuilder.append("=*");
+                                               filterBuilder.append(filter);
+                                               filterBuilder.append("*)");
+                                       }
+
+                               String typeStr = "(" + LdapAttrs.objectClass.name() + "="
+                                               + LdapObjs.groupOfNames.name() + ")";
+                               if ((showUserBtn.getSelection()))
+                                       typeStr = "(|(" + LdapAttrs.objectClass.name() + "="
+                                                       + LdapObjs.inetOrgPerson.name() + ")" + typeStr
+                                                       + ")";
+
+                               if (!showSystemRoleBtn.getSelection())
+                                       typeStr = "(& " + typeStr + "(!(" + LdapAttrs.DN + "=*"
+                                                       + CmsConstants.SYSTEM_ROLES_BASEDN + ")))";
+
+                               if (filterBuilder.length() > 1) {
+                                       builder.append("(&" + typeStr);
+                                       builder.append("(|");
+                                       builder.append(filterBuilder.toString());
+                                       builder.append("))");
+                               } else {
+                                       builder.append(typeStr);
+                               }
+                               roles = userAdmin.getRoles(builder.toString());
+                       } catch (InvalidSyntaxException e) {
+                               throw new EclipseUiException(
+                                               "Unable to get roles with filter: " + filter, e);
+                       }
+                       List<User> users = new ArrayList<User>();
+                       for (Role role : roles)
+                               if (!users.contains(role))
+                                       users.add((User) role);
+                       return users;
+               }
+       }
+
+       private boolean notNull(String string) {
+               if (string == null)
+                       return false;
+               else
+                       return !"".equals(string.trim());
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UserLP.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UserLP.java
new file mode 100644 (file)
index 0000000..b3ab40e
--- /dev/null
@@ -0,0 +1,76 @@
+package org.argeo.cms.swt.useradmin;
+
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.cms.auth.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.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+
+/** Centralize label providers for the group table */
+class UserLP extends ColumnLabelProvider {
+       private static final long serialVersionUID = -4645930210988368571L;
+
+       final static String COL_ICON = "colID.icon";
+       final static String COL_DN = "colID.dn";
+       final static String COL_DISPLAY_NAME = "colID.displayName";
+       final static String COL_DOMAIN = "colID.domain";
+
+       final String currType;
+
+       // private Font italic;
+       private Font bold;
+
+       UserLP(String colId) {
+               this.currType = colId;
+       }
+
+       @Override
+       public Font getFont(Object element) {
+               // Current user as bold
+               if (UserAdminUtils.isCurrentUser(((User) element))) {
+                       if (bold == null)
+                               bold = JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD)
+                                               .createFont(Display.getCurrent());
+                       return bold;
+               }
+               return null;
+       }
+
+       @Override
+       public Image getImage(Object element) {
+               if (COL_ICON.equals(currType)) {
+                       User user = (User) element;
+                       String dn = user.getName();
+                       if (dn.endsWith(CmsConstants.SYSTEM_ROLES_BASEDN))
+                               return UsersImages.ICON_ROLE;
+                       else if (user.getType() == Role.GROUP)
+                               return UsersImages.ICON_GROUP;
+                       else
+                               return UsersImages.ICON_USER;
+               } else
+                       return null;
+       }
+
+       @Override
+       public String getText(Object element) {
+               User user = (User) element;
+               return getText(user);
+
+       }
+
+       public String getText(User user) {
+               if (COL_DN.equals(currType))
+                       return user.getName();
+               else if (COL_DISPLAY_NAME.equals(currType))
+                       return UserAdminUtils.getCommonName(user);
+               else if (COL_DOMAIN.equals(currType))
+                       return UserAdminUtils.getDomainName(user);
+               else
+                       return "";
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UsersImages.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UsersImages.java
new file mode 100644 (file)
index 0000000..21fc5af
--- /dev/null
@@ -0,0 +1,14 @@
+package org.argeo.cms.swt.useradmin;
+
+import org.argeo.cms.ui.theme.CmsImages;
+import org.eclipse.swt.graphics.Image;
+
+/** Specific users icons. */
+public class UsersImages {
+       private final static String PREFIX = "icons/";
+
+       public final static Image ICON_USER = CmsImages.createImg(PREFIX + "person.png");
+       public final static Image ICON_GROUP = CmsImages.createImg(PREFIX + "group.png");
+       public final static Image ICON_ROLE = CmsImages.createImg(PREFIX + "role.gif");
+       public final static Image ICON_CHANGE_PASSWORD = CmsImages.createImg(PREFIX + "security.gif");
+}
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/ViewerUtils.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/ViewerUtils.java
new file mode 100644 (file)
index 0000000..d186783
--- /dev/null
@@ -0,0 +1,58 @@
+package org.argeo.cms.swt.useradmin;
+
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TreeColumn;
+
+/**
+ * Centralise useful methods to manage JFace Table, Tree and TreeColumn viewers.
+ */
+public class ViewerUtils {
+
+       /**
+        * Creates a basic column for the given table. For the time being, we do not
+        * support movable columns.
+        */
+       public static TableColumn createColumn(Table parent, String name, int style, int width) {
+               TableColumn result = new TableColumn(parent, style);
+               result.setText(name);
+               result.setWidth(width);
+               result.setResizable(true);
+               return result;
+       }
+
+       /**
+        * Creates a TableViewerColumn for the given viewer. For the time being, we do
+        * not support movable columns.
+        */
+       public static TableViewerColumn createTableViewerColumn(TableViewer parent, String name, int style, int width) {
+               TableViewerColumn tvc = new TableViewerColumn(parent, style);
+               TableColumn column = tvc.getColumn();
+               column.setText(name);
+               column.setWidth(width);
+               column.setResizable(true);
+               return tvc;
+       }
+
+       // public static TableViewerColumn createTableViewerColumn(TableViewer parent,
+       // Localized name, int style, int width) {
+       // return createTableViewerColumn(parent, name.lead(), style, width);
+       // }
+
+       /**
+        * Creates a TreeViewerColumn for the given viewer. For the time being, we do
+        * not support movable columns.
+        */
+       public static TreeViewerColumn createTreeViewerColumn(TreeViewer parent, String name, int style, int width) {
+               TreeViewerColumn tvc = new TreeViewerColumn(parent, style);
+               TreeColumn column = tvc.getColumn();
+               column.setText(name);
+               column.setWidth(width);
+               column.setResizable(true);
+               return tvc;
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/package-info.java
new file mode 100644 (file)
index 0000000..3597bfc
--- /dev/null
@@ -0,0 +1,2 @@
+/** SWT/JFace users management components. */
+package org.argeo.cms.swt.useradmin;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/CmsImages.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/CmsImages.java
new file mode 100644 (file)
index 0000000..1c4d79e
--- /dev/null
@@ -0,0 +1,49 @@
+package org.argeo.cms.ui.theme;
+
+import java.net.URL;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+public class CmsImages {
+       private static BundleContext themeBc = FrameworkUtil.getBundle(CmsImages.class).getBundleContext();
+
+       final public static String ICONS_BASE = "icons/";
+       final public static String TYPES_BASE = ICONS_BASE + "types/";
+       final public static String ACTIONS_BASE = ICONS_BASE + "actions/";
+
+       public static Image createIcon(String name) {
+               return createImg(CmsImages.ICONS_BASE + name);
+       }
+
+       public static Image createAction(String name) {
+               return createImg(CmsImages.ACTIONS_BASE + name);
+       }
+
+       public static Image createType(String name) {
+               return createImg(CmsImages.TYPES_BASE + name);
+       }
+
+       public static Image createImg(String name) {
+               return CmsImages.createDesc(name).createImage(Display.getDefault());
+       }
+
+       public static ImageDescriptor createDesc(String name) {
+               return createDesc(themeBc, name);
+       }
+
+       public static ImageDescriptor createDesc(BundleContext bc, String name) {
+               URL url = bc.getBundle().getResource(name);
+               if (url == null)
+                       return ImageDescriptor.getMissingImageDescriptor();
+               return ImageDescriptor.createFromURL(url);
+       }
+
+       public static Image createImg(BundleContext bc, String name) {
+               return createDesc(bc, name).createImage(Display.getDefault());
+       }
+
+}
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/package-info.java
new file mode 100644 (file)
index 0000000..7d3a260
--- /dev/null
@@ -0,0 +1,2 @@
+/** Argeo CMS core theme images. */
+package org.argeo.cms.ui.theme;
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java
new file mode 100644 (file)
index 0000000..a388e74
--- /dev/null
@@ -0,0 +1,106 @@
+package org.argeo.eclipse.ui.dialogs;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.argeo.api.cms.CmsLog;
+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.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Generic error dialog to be used in try/catch blocks.
+ * 
+ * @deprecated Use CMS dialogs instead.
+ */
+@Deprecated
+public class ErrorFeedback extends TitleAreaDialog {
+       private static final long serialVersionUID = -8918084784628179044L;
+
+       private final static CmsLog log = CmsLog.getLog(ErrorFeedback.class);
+
+       private final String message;
+       private final Throwable exception;
+
+       public static void show(String message, Throwable e) {
+               // rethrow ThreaDeath in order to make sure that RAP will properly clean
+               // up the UI thread
+               if (e instanceof ThreadDeath)
+                       throw (ThreadDeath) e;
+
+               new ErrorFeedback(newShell(), message, e).open();
+       }
+
+       public static void show(String message) {
+               new ErrorFeedback(newShell(), message, null).open();
+       }
+
+       private static Shell newShell() {
+               return new Shell(getDisplay(), SWT.NO_TRIM);
+       }
+
+       /** Tries to find a display */
+       private static Display getDisplay() {
+               try {
+                       Display display = Display.getCurrent();
+                       if (display != null)
+                               return display;
+                       else
+                               return Display.getDefault();
+               } catch (Exception e) {
+                       return Display.getCurrent();
+               }
+       }
+
+       public ErrorFeedback(Shell parentShell, String message, Throwable e) {
+               super(parentShell);
+               setShellStyle(SWT.NO_TRIM);
+               this.message = message;
+               this.exception = e;
+               log.error(message, e);
+       }
+
+       protected Point getInitialSize() {
+               if (exception != null)
+                       return new Point(800, 600);
+               else
+                       return new Point(400, 300);
+       }
+
+       @Override
+       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, true));
+
+               setMessage(message != null ? message + (exception != null ? ": " + exception.getMessage() : "")
+                               : exception != null ? exception.getMessage() : "Unkown Error", IMessageProvider.ERROR);
+
+               if (exception != null) {
+                       Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+                       stack.setEditable(false);
+                       stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+                       StringWriter sw = new StringWriter();
+                       exception.printStackTrace(new PrintWriter(sw));
+                       stack.setText(sw.toString());
+               }
+
+               parent.pack();
+               return composite;
+       }
+
+       protected void configureShell(Shell shell) {
+               super.configureShell(shell);
+               shell.setText("Error");
+       }
+}
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java
new file mode 100644 (file)
index 0000000..f2715bc
--- /dev/null
@@ -0,0 +1,141 @@
+package org.argeo.eclipse.ui.dialogs;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.argeo.api.cms.CmsLog;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Generic lightweight dialog, not based on JFace.
+ * 
+ * @deprecated Use CMS dialogs instead.
+ */
+@Deprecated
+public class FeedbackDialog extends LightweightDialog {
+       private final static CmsLog log = CmsLog.getLog(FeedbackDialog.class);
+
+       private String message;
+       private Throwable exception;
+
+//     private Shell parentShell;
+       private Shell shell;
+
+       public static void show(String message, Throwable e) {
+               // rethrow ThreaDeath in order to make sure that RAP will properly clean
+               // up the UI thread
+               if (e instanceof ThreadDeath)
+                       throw (ThreadDeath) e;
+
+               new FeedbackDialog(getDisplay().getActiveShell(), message, e).open();
+       }
+
+       public static void show(String message) {
+               new FeedbackDialog(getDisplay().getActiveShell(), message, null).open();
+       }
+
+       /** Tries to find a display */
+       private static Display getDisplay() {
+               try {
+                       Display display = Display.getCurrent();
+                       if (display != null)
+                               return display;
+                       else
+                               return Display.getDefault();
+               } catch (Exception e) {
+                       return Display.getCurrent();
+               }
+       }
+
+       public FeedbackDialog(Shell parentShell, String message, Throwable e) {
+               super(parentShell);
+               this.message = message;
+               this.exception = e;
+               log.error(message, e);
+       }
+
+       public int open() {
+               if (shell != null)
+                       throw new EclipseUiException("There is already a shell");
+               shell = new Shell(getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
+               shell.setLayout(new GridLayout());
+               // shell.setText("Error");
+               shell.setSize(getInitialSize());
+               createDialogArea(shell);
+               // shell.pack();
+               // shell.layout();
+
+               Rectangle shellBounds = Display.getCurrent().getBounds();// RAP
+               Point dialogSize = shell.getSize();
+               int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+               int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+               shell.setLocation(x, y);
+
+               shell.addShellListener(new ShellAdapter() {
+                       private static final long serialVersionUID = -2701270481953688763L;
+
+                       @Override
+                       public void shellDeactivated(ShellEvent e) {
+                               closeShell();
+                       }
+               });
+
+               shell.open();
+               return OK;
+       }
+
+       protected void closeShell() {
+               shell.close();
+               shell.dispose();
+               shell = null;
+       }
+
+       protected Point getInitialSize() {
+               // if (exception != null)
+               // return new Point(800, 600);
+               // else
+               return new Point(400, 300);
+       }
+
+       protected Control createDialogArea(Composite parent) {
+               Composite dialogarea = new Composite(parent, SWT.NONE);
+               dialogarea.setLayout(new GridLayout());
+               // Composite dialogarea = (Composite) super.createDialogArea(parent);
+               dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+               Label messageLbl = new Label(dialogarea, SWT.NONE);
+               if (message != null)
+                       messageLbl.setText(message);
+               else if (exception != null)
+                       messageLbl.setText(exception.getLocalizedMessage());
+
+               Composite composite = new Composite(dialogarea, SWT.NONE);
+               composite.setLayout(new GridLayout(2, false));
+               composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+               if (exception != null) {
+                       Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+                       stack.setEditable(false);
+                       stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+                       StringWriter sw = new StringWriter();
+                       exception.printStackTrace(new PrintWriter(sw));
+                       stack.setText(sw.toString());
+               }
+
+               // parent.pack();
+               return composite;
+       }
+}
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java
new file mode 100644 (file)
index 0000000..615e141
--- /dev/null
@@ -0,0 +1,256 @@
+package org.argeo.eclipse.ui.dialogs;
+
+import org.argeo.api.cms.CmsLog;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/** Generic lightweight dialog, not based on JFace. */
+@Deprecated
+public class LightweightDialog {
+       private final static CmsLog log = CmsLog.getLog(LightweightDialog.class);
+
+       // must be the same value as org.eclipse.jface.window.Window#OK
+       public final static int OK = 0;
+       // must be the same value as org.eclipse.jface.window.Window#CANCEL
+       public final static int CANCEL = 1;
+
+       private Shell parentShell;
+       private Shell backgroundShell;
+       private Shell foregoundShell;
+
+       private Integer returnCode = null;
+       private boolean block = true;
+
+       private String title;
+
+       /** Tries to find a display */
+       private static Display getDisplay() {
+               try {
+                       Display display = Display.getCurrent();
+                       if (display != null)
+                               return display;
+                       else
+                               return Display.getDefault();
+               } catch (Exception e) {
+                       return Display.getCurrent();
+               }
+       }
+
+       public LightweightDialog(Shell parentShell) {
+               this.parentShell = parentShell;
+       }
+
+       public int open() {
+               if (foregoundShell != null)
+                       throw new EclipseUiException("There is already a shell");
+               backgroundShell = new Shell(parentShell, SWT.ON_TOP);
+               backgroundShell.setFullScreen(true);
+               // if (parentShell != null) {
+               // backgroundShell.setBounds(parentShell.getBounds());
+               // } else
+               // backgroundShell.setMaximized(true);
+               backgroundShell.setAlpha(128);
+               backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
+               foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP);
+               if (title != null)
+                       setTitle(title);
+               foregoundShell.setLayout(new GridLayout());
+               foregoundShell.setSize(getInitialSize());
+               createDialogArea(foregoundShell);
+               // shell.pack();
+               // shell.layout();
+
+               Rectangle shellBounds = parentShell != null ? parentShell.getBounds() : Display.getCurrent().getBounds();// RAP
+               Point dialogSize = foregoundShell.getSize();
+               int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+               int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+               foregoundShell.setLocation(x, y);
+
+               foregoundShell.addShellListener(new ShellAdapter() {
+                       private static final long serialVersionUID = -2701270481953688763L;
+
+                       @Override
+                       public void shellDeactivated(ShellEvent e) {
+                               if (hasChildShells())
+                                       return;
+                               if (returnCode == null)// not yet closed
+                                       closeShell(CANCEL);
+                       }
+
+                       @Override
+                       public void shellClosed(ShellEvent e) {
+                               notifyClose();
+                       }
+
+               });
+
+               backgroundShell.open();
+               foregoundShell.open();
+               // after the foreground shell has been opened
+               backgroundShell.addFocusListener(new FocusListener() {
+                       private static final long serialVersionUID = 3137408447474661070L;
+
+                       @Override
+                       public void focusLost(FocusEvent event) {
+                       }
+
+                       @Override
+                       public void focusGained(FocusEvent event) {
+                               if (hasChildShells())
+                                       return;
+                               if (returnCode == null)// not yet closed
+                                       closeShell(CANCEL);
+                       }
+               });
+
+               if (block) {
+                       block();
+               }
+               if (returnCode == null)
+                       returnCode = OK;
+               return returnCode;
+       }
+
+       public void block() {
+               try {
+                       runEventLoop(foregoundShell);
+               } catch (ThreadDeath t) {
+                       returnCode = CANCEL;
+                       if (log.isTraceEnabled())
+                               log.error("Thread death, canceling dialog", t);
+               } catch (Throwable t) {
+                       returnCode = CANCEL;
+                       log.error("Cannot open blocking lightweight dialog", t);
+               }
+       }
+
+       private boolean hasChildShells() {
+               if (foregoundShell == null)
+                       return false;
+               return foregoundShell.getShells().length != 0;
+       }
+
+       // public synchronized int openAndWait() {
+       // open();
+       // while (returnCode == null)
+       // try {
+       // wait(100);
+       // } catch (InterruptedException e) {
+       // // silent
+       // }
+       // return returnCode;
+       // }
+
+       private synchronized void notifyClose() {
+               if (returnCode == null)
+                       returnCode = CANCEL;
+               notifyAll();
+       }
+
+       protected void closeShell(int returnCode) {
+               this.returnCode = returnCode;
+               if (CANCEL == returnCode)
+                       onCancel();
+               if (foregoundShell != null && !foregoundShell.isDisposed()) {
+                       foregoundShell.close();
+                       foregoundShell.dispose();
+                       foregoundShell = null;
+               }
+
+               if (backgroundShell != null && !backgroundShell.isDisposed()) {
+                       backgroundShell.close();
+                       backgroundShell.dispose();
+               }
+       }
+
+       protected Point getInitialSize() {
+               // if (exception != null)
+               // return new Point(800, 600);
+               // else
+               return new Point(600, 400);
+       }
+
+       protected Control createDialogArea(Composite parent) {
+               Composite dialogarea = new Composite(parent, SWT.NONE);
+               dialogarea.setLayout(new GridLayout());
+               dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               return dialogarea;
+       }
+
+       protected Shell getBackgroundShell() {
+               return backgroundShell;
+       }
+
+       protected Shell getForegoundShell() {
+               return foregoundShell;
+       }
+
+       public void setBlockOnOpen(boolean shouldBlock) {
+               block = shouldBlock;
+       }
+
+       public void pack() {
+               foregoundShell.pack();
+       }
+
+       private void runEventLoop(Shell loopShell) {
+               Display display;
+               if (foregoundShell == null) {
+                       display = Display.getCurrent();
+               } else {
+                       display = loopShell.getDisplay();
+               }
+
+               while (loopShell != null && !loopShell.isDisposed()) {
+                       try {
+                               if (!display.readAndDispatch()) {
+                                       display.sleep();
+                               }
+                       } catch (UnsupportedOperationException e) {
+                               throw e;
+                       } catch (Throwable e) {
+                               handleException(e);
+                       }
+               }
+               if (!display.isDisposed())
+                       display.update();
+       }
+
+       protected void handleException(Throwable t) {
+               if (t instanceof ThreadDeath) {
+                       // Don't catch ThreadDeath as this is a normal occurrence when
+                       // the thread dies
+                       throw (ThreadDeath) t;
+               }
+               // Try to keep running.
+               t.printStackTrace();
+       }
+
+       /** @return false, if the dialog should not be closed. */
+       protected boolean onCancel() {
+               return true;
+       }
+
+       public void setTitle(String title) {
+               this.title = title;
+               if (title != null && getForegoundShell() != null)
+                       getForegoundShell().setText(title);
+       }
+
+       public Integer getReturnCode() {
+               return returnCode;
+       }
+
+}
\ No newline at end of file
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/SingleValue.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/SingleValue.java
new file mode 100644 (file)
index 0000000..8ce9b44
--- /dev/null
@@ -0,0 +1,130 @@
+package org.argeo.eclipse.ui.dialogs;
+
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.window.Window;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog to retrieve a single value.
+ * 
+ * @deprecated Use CMS dialogs instead.
+ */
+@Deprecated
+public class SingleValue extends TitleAreaDialog {
+       private static final long serialVersionUID = 2843538207460082349L;
+
+       private Text valueT;
+       private String value;
+       private final String title, message, label;
+       private final Boolean multiline;
+
+       public static String ask(String label, String message) {
+               SingleValue svd = new SingleValue(label, message);
+               if (svd.open() == Window.OK)
+                       return svd.getString();
+               else
+                       return null;
+       }
+
+       public static Long askLong(String label, String message) {
+               SingleValue svd = new SingleValue(label, message);
+               if (svd.open() == Window.OK)
+                       return svd.getLong();
+               else
+                       return null;
+       }
+
+       public static Double askDouble(String label, String message) {
+               SingleValue svd = new SingleValue(label, message);
+               if (svd.open() == Window.OK)
+                       return svd.getDouble();
+               else
+                       return null;
+       }
+
+       public SingleValue(String label, String message) {
+               this(Display.getDefault().getActiveShell(), label, message, label, false);
+       }
+
+       public SingleValue(Shell parentShell, String title, String message, String label, Boolean multiline) {
+               super(parentShell);
+               this.title = title;
+               this.message = message;
+               this.label = label;
+               this.multiline = multiline;
+       }
+
+       protected Point getInitialSize() {
+               if (multiline)
+                       return new Point(450, 350);
+
+               else
+                       return new Point(400, 270);
+       }
+
+       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.setLayoutData(EclipseUiUtils.fillAll());
+               GridLayout layout = new GridLayout(2, false);
+               layout.marginWidth = layout.marginHeight = 20;
+               composite.setLayout(layout);
+
+               valueT = createLT(composite, label);
+
+               setMessage(message, IMessageProvider.NONE);
+
+               parent.pack();
+               valueT.setFocus();
+               return composite;
+       }
+
+       @Override
+       protected void okPressed() {
+               value = valueT.getText();
+               super.okPressed();
+       }
+
+       /** Creates label and text. */
+       protected Text createLT(Composite parent, String label) {
+               new Label(parent, SWT.NONE).setText(label);
+               Text text;
+               if (multiline) {
+                       text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.MULTI);
+                       text.setLayoutData(EclipseUiUtils.fillAll());
+               } else {
+                       text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.SINGLE);
+                       text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+               }
+               return text;
+       }
+
+       protected void configureShell(Shell shell) {
+               super.configureShell(shell);
+               shell.setText(title);
+       }
+
+       public String getString() {
+               return value;
+       }
+
+       public Long getLong() {
+               return Long.valueOf(getString());
+       }
+
+       public Double getDouble() {
+               return Double.valueOf(getString());
+       }
+}
diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/package-info.java
new file mode 100644 (file)
index 0000000..d6ab148
--- /dev/null
@@ -0,0 +1,2 @@
+/** Generic SWT/JFace dialogs. */
+package org.argeo.eclipse.ui.dialogs;
\ No newline at end of file