From: Bruno Sinou Date: Fri, 16 Oct 2015 08:16:10 +0000 (+0000) Subject: Code cleaning and refactoring. X-Git-Tag: argeo-commons-2.1.30~82 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=a1d862e4ef6221ebc91fcccea688d66504020365;p=lgpl%2Fargeo-commons.git Code cleaning and refactoring. Work on the new security model git-svn-id: https://svn.argeo.org/commons/trunk@8495 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/demo/argeo_node_rap.properties b/demo/argeo_node_rap.properties index 6ca4735ec..0ba8bfe5d 100644 --- a/demo/argeo_node_rap.properties +++ b/demo/argeo_node_rap.properties @@ -26,6 +26,8 @@ java.security.policy=file:../../all.policy #&userObjectClass=inetOrgPerson \ #dc=example,dc=org.ldif" +argeo.node.useradmin.uris="dc=example,dc=com.ldif dc=example,dc=org.ldif" + # HTTP org.osgi.service.http.port=7070 #org.eclipse.equinox.http.jetty.log.stderr.threshold=info diff --git a/org.argeo.eclipse.ui.workbench/META-INF/spring/commands.xml b/org.argeo.eclipse.ui.workbench/META-INF/spring/commands.xml index 5466e75f8..1d31e16b7 100644 --- a/org.argeo.eclipse.ui.workbench/META-INF/spring/commands.xml +++ b/org.argeo.eclipse.ui.workbench/META-INF/spring/commands.xml @@ -4,9 +4,15 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - + + + + + + \ No newline at end of file diff --git a/org.argeo.eclipse.ui.workbench/META-INF/spring/osgi.xml b/org.argeo.eclipse.ui.workbench/META-INF/spring/osgi.xml index 38f733291..5be2a197e 100644 --- a/org.argeo.eclipse.ui.workbench/META-INF/spring/osgi.xml +++ b/org.argeo.eclipse.ui.workbench/META-INF/spring/osgi.xml @@ -17,7 +17,7 @@ - + \ No newline at end of file diff --git a/org.argeo.eclipse.ui.workbench/icons/role.gif b/org.argeo.eclipse.ui.workbench/icons/role.gif new file mode 100644 index 000000000..274a850e4 Binary files /dev/null and b/org.argeo.eclipse.ui.workbench/icons/role.gif differ diff --git a/org.argeo.eclipse.ui.workbench/icons/user.gif b/org.argeo.eclipse.ui.workbench/icons/user.gif new file mode 100644 index 000000000..90a00147b Binary files /dev/null and b/org.argeo.eclipse.ui.workbench/icons/user.gif differ diff --git a/org.argeo.eclipse.ui.workbench/icons/users.gif b/org.argeo.eclipse.ui.workbench/icons/users.gif new file mode 100644 index 000000000..2de7edd64 Binary files /dev/null and b/org.argeo.eclipse.ui.workbench/icons/users.gif differ diff --git a/org.argeo.eclipse.ui.workbench/plugin.xml b/org.argeo.eclipse.ui.workbench/plugin.xml index a4292c261..c6d82a97a 100644 --- a/org.argeo.eclipse.ui.workbench/plugin.xml +++ b/org.argeo.eclipse.ui.workbench/plugin.xml @@ -130,7 +130,7 @@ name="Create a new folder"> diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddPrivileges.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddPrivileges.java index 684fea655..49ed4378f 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddPrivileges.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/AddPrivileges.java @@ -32,11 +32,15 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.service.useradmin.UserAdmin; -/** Open a dialog to change rights on the selected node. */ +/** Open a dialog to add privileges on the selected node to a chosen group */ public class AddPrivileges extends AbstractHandler { public final static String ID = WorkbenchUiPlugin.ID + ".addPrivileges"; + /* DEPENDENCY INJECTION */ + private UserAdmin userAdmin; + public Object execute(ExecutionEvent event) throws ExecutionException { ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) @@ -58,7 +62,8 @@ public class AddPrivileges extends AbstractHandler { try { ChangeRightsWizard wizard = new ChangeRightsWizard( - jcrParentNode.getSession(), jcrParentNode.getPath()); + jcrParentNode.getSession(), jcrParentNode.getPath(), + userAdmin); WizardDialog dialog = new WizardDialog( HandlerUtil.getActiveShell(event), wizard); dialog.open(); @@ -73,4 +78,9 @@ public class AddPrivileges extends AbstractHandler { } return null; } + + /* DEPENDENCY INJECTION */ + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } } \ No newline at end of file diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/CreateWorkspace.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/CreateWorkspace.java index cd9e402ee..9c59a369c 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/CreateWorkspace.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/CreateWorkspace.java @@ -29,7 +29,7 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.handlers.HandlerUtil; -/** Creates a new JCR workspace */ +/** Create a new JCR workspace */ public class CreateWorkspace extends AbstractHandler { public final static String ID = WorkbenchUiPlugin.ID + ".addFolderNode"; diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DeleteNodes.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DeleteNodes.java index 8a5b9d6e4..445537959 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DeleteNodes.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/DeleteNodes.java @@ -35,7 +35,7 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.handlers.HandlerUtil; /** - * Deletes the selected nodes: both in the JCR repository and in the UI view. + * Delete the selected nodes: both in the JCR repository and in the UI view. * Warning no check is done, except implementation dependent native checks, * handle with care. * diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/GetNodeSize.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/GetNodeSize.java index 226964405..9ffb944b0 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/GetNodeSize.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/GetNodeSize.java @@ -23,9 +23,9 @@ import javax.jcr.Node; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; import org.argeo.eclipse.ui.workbench.WorkbenchUiPlugin; -import org.argeo.jcr.JcrUtils; import org.argeo.eclipse.ui.workbench.jcr.internal.model.SingleJcrNodeElem; import org.argeo.eclipse.ui.workbench.jcr.internal.model.WorkspaceElem; +import org.argeo.jcr.JcrUtils; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -35,19 +35,13 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.handlers.HandlerUtil; -/** Opens the generic node editor. */ +/** Compute an approximative size for the selected node(s) */ public class GetNodeSize extends AbstractHandler { // private final static Log log = LogFactory.getLog(GetNodeSize.class); public final static String ID = WorkbenchUiPlugin.ID + ".getNodeSize"; - // public final static String DEFAULT_ICON_REL_PATH = "icons/getSize.gif"; - // public final static String DEFAULT_LABEL = JcrExplorerPlugin - // .getMessage("getNodeSizeCmdLbl"); - public Object execute(ExecutionEvent event) throws ExecutionException { - // JcrUtils.getRepositoryByAlias(repositoryRegister, - // ArgeoJcrConstants.ALIAS_NODE); ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event) .getActivePage().getSelection(); @@ -55,20 +49,14 @@ public class GetNodeSize extends AbstractHandler { if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection) { - // IStructuredSelection iss = (IStructuredSelection) selection; - // if (iss.size() > 1) - // ErrorFeedback.show(JcrExplorerPlugin - // .getMessage("warningInvalidMultipleSelection"), null); - long size = 0; Iterator it = ((IStructuredSelection) selection).iterator(); - // as the size method is recursive, we keep track of nodes for which - // we already have computed size so that we don't count them twice. - // In a first approximation, we assume that the structure selection - // keep the nodes ordered. - // TODO : enhance that. + // TODO enhance this: as the size method is recursive, we keep track + // of nodes for which we already have computed size so that we don't + // count them twice. In a first approximation, we assume that the + // structure selection keep the nodes ordered. List importedPathes = new ArrayList(); try { nodesIt: while (it.hasNext()) { @@ -83,7 +71,7 @@ public class GetNodeSize extends AbstractHandler { node = ((WorkspaceElem) obj).getRootNode(); curPath = node.getSession().getWorkspace().getName(); } else - // unvalid object type + // non valid object type continue nodesIt; Iterator itPath = importedPathes.iterator(); @@ -110,4 +98,4 @@ public class GetNodeSize extends AbstractHandler { } return null; } -} +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenEditor.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenEditor.java index 123f089b8..fe31bc4ef 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenEditor.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/OpenEditor.java @@ -15,10 +15,12 @@ */ package org.argeo.eclipse.ui.workbench.commands; +import javax.jcr.Node; + import org.argeo.ArgeoException; import org.argeo.eclipse.ui.workbench.WorkbenchUiPlugin; -import org.argeo.eclipse.ui.workbench.jcr.GenericJcrQueryEditor; import org.argeo.eclipse.ui.workbench.jcr.DefaultNodeEditor; +import org.argeo.eclipse.ui.workbench.jcr.GenericJcrQueryEditor; import org.argeo.eclipse.ui.workbench.jcr.internal.parts.JcrQueryEditorInput; import org.argeo.eclipse.ui.workbench.jcr.internal.parts.NodeEditorInput; import org.eclipse.core.commands.AbstractHandler; @@ -28,7 +30,7 @@ import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.handlers.HandlerUtil; -/** Opens an editor given its ID. */ +/** Open a {@link Node} editor of a specific type given the node path */ public class OpenEditor extends AbstractHandler { public final static String ID = WorkbenchUiPlugin.ID + ".openEditor"; diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/SortChildNodes.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/SortChildNodes.java index e5b7a7f3f..8eaac9f85 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/SortChildNodes.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/commands/SortChildNodes.java @@ -26,9 +26,7 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.handlers.HandlerUtil; -/** - * Change isSorted state of the JcrExplorer Browser - */ +/** Change isSorted state of the DataExplorer Browser */ public class SortChildNodes extends AbstractHandler { public final static String ID = WorkbenchUiPlugin.ID + ".sortChildNodes"; diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserView.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserView.java index 6a04870e2..dff153d97 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserView.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/JcrBrowserView.java @@ -339,6 +339,11 @@ public class JcrBrowserView extends ViewPart { return sortChildNodes; } + @Override + public void setFocus() { + getNodeViewer().getTree().setFocus(); + } + /* DEPENDENCY INJECTION */ public void setRepositoryRegister(RepositoryRegister repositoryRegister) { this.repositoryRegister = repositoryRegister; @@ -355,9 +360,4 @@ public class JcrBrowserView extends ViewPart { public void setNodeRepository(Repository nodeRepository) { this.nodeRepository = nodeRepository; } - - @Override - public void setFocus() { - getNodeViewer().getTree().setFocus(); - } } diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/VersionLabelProvider.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/VersionLabelProvider.java index 873b6b696..d79f568ab 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/VersionLabelProvider.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/VersionLabelProvider.java @@ -23,9 +23,9 @@ import org.argeo.ArgeoException; import org.eclipse.jface.viewers.ColumnLabelProvider; /** - * simple wrapping of the ColumnLabelProvider class to provide text display in - * order to build a tree for version. The Get text method does not assume that - * Version extends Node class to respect JCR 2.0 specification + * Simple wrapping of the ColumnLabelProvider class to provide text display in + * order to build a tree for version. The getText() method does not assume that + * {@link Version} extends {@link Node} class to respect JCR 2.0 specification * */ public class VersionLabelProvider extends ColumnLabelProvider { diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/MaintainedRepositoryElem.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/MaintainedRepositoryElem.java index 87e40e415..ce6aed3ed 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/MaintainedRepositoryElem.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/MaintainedRepositoryElem.java @@ -6,7 +6,7 @@ import org.argeo.ArgeoException; import org.argeo.eclipse.ui.TreeParent; import org.argeo.jcr.MaintainedRepository; -/** Wraps a {@link MaintainedRepository} */ +/** Wrap a {@link MaintainedRepository} */ public class MaintainedRepositoryElem extends RepositoryElem { public MaintainedRepositoryElem(String alias, Repository repository, diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoriesElem.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoriesElem.java index 1e1469bb8..d5e84af04 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoriesElem.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoriesElem.java @@ -34,7 +34,7 @@ import org.argeo.jcr.UserJcrUtils; import org.argeo.util.security.Keyring; /** - * UI Tree component. Implements the Argeo abstraction of a + * UI Tree component that implements the Argeo abstraction of a * {@link RepositoryFactory} that enable a user to "mount" various repositories * in a single Tree like View. It is usually meant to be at the root of the UI * Tree and thus {@link getParent()} method will return null. diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoryElem.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoryElem.java index 422e5cfbe..a468eab5e 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoryElem.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/model/RepositoryElem.java @@ -23,7 +23,7 @@ import org.argeo.ArgeoException; import org.argeo.eclipse.ui.TreeParent; /** - * UI Tree component. Wraps a JCR {@link Repository}. It also keeps a reference + * UI Tree component that wraps a JCR {@link Repository}. It also keeps a reference * to its parent Tree Ui component; typically the unique {@link Repositories} * object of the current view to enable bi-directionnal browsing in the tree. */ diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChangeRightsWizard.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChangeRightsWizard.java index 4564b5f3b..2339ce1a3 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChangeRightsWizard.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChangeRightsWizard.java @@ -17,25 +17,47 @@ package org.argeo.eclipse.ui.workbench.jcr.internal.parts; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.security.Privilege; import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.workbench.users.PickUpGroupDialog; import org.argeo.jcr.JcrUtils; +import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.UserAdmin; -/** - * Small wizard to manage authorizations on the root node of the current - * workspace - */ +/** Add Jcr privileges to the chosen user group on a given node */ public class ChangeRightsWizard extends Wizard { + private UserAdmin userAdmin; private Session currentSession; private String path; // This page widget - private ChooseRightsPage page; + private DefinePrivilegePage page; + + // USABLE SHORTCUTS + protected final static String[] validAuthType = { Privilege.JCR_READ, + Privilege.JCR_WRITE, Privilege.JCR_ALL }; - public ChangeRightsWizard(Session currentSession, String path) { + public ChangeRightsWizard(Session currentSession, String path, + UserAdmin userAdmin) { super(); + this.userAdmin = userAdmin; this.currentSession = currentSession; this.path = path; } @@ -43,7 +65,7 @@ public class ChangeRightsWizard extends Wizard { @Override public void addPages() { try { - page = new ChooseRightsPage(path); + page = new DefinePrivilegePage(userAdmin, path); addPage(page); } catch (Exception e) { throw new ArgeoException("Cannot add page to wizard ", e); @@ -63,4 +85,87 @@ public class ChangeRightsWizard extends Wizard { } return true; } -} + + private class DefinePrivilegePage extends WizardPage implements ModifyListener { + private static final long serialVersionUID = 8084431378762283920L; + + // Context + final private UserAdmin userAdmin; + + // This page widget + private Text groupNameTxt; + private Combo authorizationCmb; + + public DefinePrivilegePage(UserAdmin userAdmin, String path) { + super("Main"); + this.userAdmin = userAdmin; + setTitle("Define the privilege to apply to " + path); + } + + public void createControl(Composite parent) { + // specify subject + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(3, false)); + Label lbl = new Label(composite, SWT.LEAD); + lbl.setText("Group name"); + lbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + groupNameTxt = new Text(composite, SWT.LEAD | SWT.BORDER); + groupNameTxt.setLayoutData(EclipseUiUtils.fillWidth()); + if (groupNameTxt != null) + groupNameTxt.addModifyListener(this); + + Link pickUpLk = new Link(composite, SWT.LEFT); + pickUpLk.setText(" Pick up "); + pickUpLk.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + PickUpGroupDialog dialog = new PickUpGroupDialog( + getShell(), "Choose a group", userAdmin); + if (dialog.open() == Window.OK) + groupNameTxt.setText(dialog.getSelected()); + } + + }); + + // Choose rigths + new Label(composite, SWT.NONE) + .setText("Choose corresponding rights"); + authorizationCmb = new Combo(composite, SWT.BORDER | SWT.V_SCROLL); + authorizationCmb.setItems(validAuthType); + authorizationCmb.setLayoutData(EclipseUiUtils.fillWidth(2)); + authorizationCmb.select(0); + + // Compulsory + setControl(composite); + } + + protected String getGroupName() { + return groupNameTxt.getText(); + } + + protected String getAuthTypeStr() { + return authorizationCmb.getItem(authorizationCmb + .getSelectionIndex()); + } + + public void modifyText(ModifyEvent event) { + String message = checkComplete(); + if (message != null) + setMessage(message, WizardPage.ERROR); + else { + setMessage("Complete", WizardPage.INFORMATION); + setPageComplete(true); + } + } + + /** @return error message or null if complete */ + protected String checkComplete() { + String groupStr = groupNameTxt.getText(); + if (groupStr == null || "".equals(groupStr)) + return "Please enter the name of the corresponding group."; + return null; + } + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChooseRightsPage.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChooseRightsPage.java index f8a36080f..09c653cdb 100644 --- a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChooseRightsPage.java +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ChooseRightsPage.java @@ -17,20 +17,31 @@ package org.argeo.eclipse.ui.workbench.jcr.internal.parts; import javax.jcr.security.Privilege; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.workbench.users.PickUpGroupDialog; +import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.UserAdmin; +/** Simple wizard page to choose a group and corresponding rights to assign */ public class ChooseRightsPage extends WizardPage implements ModifyListener { private static final long serialVersionUID = 8084431378762283920L; + // Context + final private UserAdmin userAdmin; + // This page widget private Text groupNameTxt; private Combo authorizationCmb; @@ -39,31 +50,45 @@ public class ChooseRightsPage extends WizardPage implements ModifyListener { protected final static String[] validAuthType = { Privilege.JCR_READ, Privilege.JCR_WRITE, Privilege.JCR_ALL }; - public ChooseRightsPage(String path) { + public ChooseRightsPage(UserAdmin userAdmin, String path) { super("Main"); + this.userAdmin = userAdmin; setTitle("Add privilege to " + path); } public void createControl(Composite parent) { // specify subject Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); + composite.setLayout(new GridLayout(3, false)); Label lbl = new Label(composite, SWT.LEAD); - lbl.setText("Group or user name (no blank, no special chars)"); + lbl.setText("Group name"); + // lbl.setText("Group or user name (no blank, no special chars)"); lbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); groupNameTxt = new Text(composite, SWT.LEAD | SWT.BORDER); - groupNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, - false)); + groupNameTxt.setLayoutData(EclipseUiUtils.fillWidth()); if (groupNameTxt != null) groupNameTxt.addModifyListener(this); + Link pickUpLk = new Link(composite, SWT.LEFT); + pickUpLk.setText("Pick up"); + pickUpLk.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + PickUpGroupDialog dialog = new PickUpGroupDialog(getShell(), + "Choose a group", userAdmin); + if (dialog.open() == Window.OK) + groupNameTxt.setText(dialog.getSelected()); + } + + }); + // Choose rigths new Label(composite, SWT.NONE).setText("Choose corresponding rights"); authorizationCmb = new Combo(composite, SWT.BORDER | SWT.V_SCROLL); authorizationCmb.setItems(validAuthType); - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - authorizationCmb.setLayoutData(gd); - + authorizationCmb.setLayoutData(EclipseUiUtils.fillWidth(2)); authorizationCmb.select(0); // Compulsory @@ -93,10 +118,6 @@ public class ChooseRightsPage extends WizardPage implements ModifyListener { String groupStr = groupNameTxt.getText(); if (groupStr == null || "".equals(groupStr)) return "Please enter the name of the corresponding group."; - // Remove regexp check for the time being. - // else if (!match(groupStr)) - // return - // "Please use only alphanumerical chars for the short technical name."; return null; } } diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/GroupLP.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/GroupLP.java new file mode 100644 index 000000000..5e054dca4 --- /dev/null +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/GroupLP.java @@ -0,0 +1,119 @@ +package org.argeo.eclipse.ui.workbench.users; + +import java.util.List; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.workbench.users.internal.UsersImages; +import org.argeo.eclipse.ui.workbench.users.internal.UsersUtils; +import org.argeo.osgi.useradmin.LdifName; +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 GroupLP extends ColumnLabelProvider { + private static final long serialVersionUID = -4645930210988368571L; + + // TODO this constant is defined in the CMS + final static String ROLES_BASEDN = "ou=roles,ou=node"; + + 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; + + GroupLP(String colId) { + this.currType = colId; + } + + @Override + public Font getFont(Object element) { + // Self as bold + try { + LdapName selfUserName = UsersUtils.getLdapName(); + String userName = UsersUtils.getProperty((User) element, + LdifName.dn.name()); + LdapName userLdapName = new LdapName(userName); + if (userLdapName.equals(selfUserName)) { + if (bold == null) + bold = JFaceResources.getFontRegistry() + .defaultFontDescriptor().setStyle(SWT.BOLD) + .createFont(Display.getCurrent()); + return bold; + } + } catch (InvalidNameException e) { + throw new ArgeoException("cannot parse dn for " + element, e); + } + + // Disabled as Italic + // Node userProfile = (Node) elem; + // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) + // return italic; + + return null; + // return super.getFont(element); + } + + @Override + public Image getImage(Object element) { + if (COL_ICON.equals(currType)) { + User user = (User) element; + String dn = (String) user.getProperties().get(LdifName.dn.name()); + if (dn.endsWith(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)) { + Object obj = user.getProperties().get(LdifName.cn.name()); + if (obj != null) + return (String) obj; + else + return ""; + } else if (COL_DOMAIN.equals(currType)) { + String dn = (String) user.getProperties().get(LdifName.dn.name()); + if (dn.endsWith(ROLES_BASEDN)) + return "System roles"; + try { + LdapName name; + name = new LdapName(dn); + List rdns = name.getRdns(); + return (String) rdns.get(1).getValue() + '.' + + (String) rdns.get(0).getValue(); + } catch (InvalidNameException e) { + throw new ArgeoException("Unable to get domain name for " + dn, + e); + } + } else + return ""; + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/PickUpGroupDialog.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/PickUpGroupDialog.java new file mode 100644 index 000000000..e9c31e3f2 --- /dev/null +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/PickUpGroupDialog.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.eclipse.ui.workbench.users; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; +import org.argeo.osgi.useradmin.LdifName; +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.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +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 group list to pick up one */ +public class PickUpGroupDialog extends TrayDialog { + private static final long serialVersionUID = -1420106871173920369L; + + // Business objects + private final UserAdmin userAdmin; + private Group selectedGroup; + + // this page widgets and UI objects + private String title; + private LdifUsersTable groupTableViewerCmp; + private TableViewer userViewer; + private List columnDefs = new ArrayList(); + + public PickUpGroupDialog(Shell parentShell, String title, + UserAdmin userAdmin) { + super(parentShell); + this.title = title; + this.userAdmin = userAdmin; + + // Define the displayed columns + columnDefs.add(new ColumnDefinition(new GroupLP(GroupLP.COL_ICON), "", + 26, 0)); + columnDefs.add(new ColumnDefinition(new GroupLP( + GroupLP.COL_DISPLAY_NAME), "Common Name", 150, 100)); + columnDefs.add(new ColumnDefinition(new GroupLP(GroupLP.COL_DOMAIN), + "Domain", 100, 120)); + columnDefs.add(new ColumnDefinition(new GroupLP(GroupLP.COL_DN), + "Distinguished Name", 300, 100)); + } + + protected Point getInitialSize() { + return new Point(600, 450); + } + + 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 + groupTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL); + + groupTableViewerCmp.setColumnDefinitions(columnDefs); + groupTableViewerCmp.populateWithStaticFilters(false, false); + groupTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); + groupTableViewerCmp.refresh(); + + // Controllers + userViewer = groupTableViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new MyDoubleClickListener()); + userViewer + .addSelectionChangedListener(new MySelectionChangedListener()); + + parent.pack(); + return dialogArea; + } + + public String getSelected() { + if (selectedGroup == null) + return null; + else + return selectedGroup.getName(); + } + + 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 Group) { + selectedGroup = (Group) obj; + okPressed(); + } + } + } + + class MySelectionChangedListener implements ISelectionChangedListener { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (event.getSelection().isEmpty()) { + selectedGroup = null; + return; + } + Object obj = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + if (obj instanceof Group) { + selectedGroup = (Group) obj; + } + } + } + + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 8467999509931900367L; + + private final String[] knownProps = { LdifName.uid.name(), + LdifName.cn.name(), LdifName.dn.name() }; + + private Button showSystemRoleBtn; + + 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 "); + showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -7033424592697691676L; + + @Override + public void widgetSelected(SelectionEvent e) { + refresh(); + } + + }); + } + + @Override + protected List listFilteredElements(String filter) { + Role[] roles; + try { + StringBuilder builder = new StringBuilder(); + StringBuilder tmpBuilder = new StringBuilder(); + if (notNull(filter)) + for (String prop : knownProps) { + tmpBuilder.append("("); + tmpBuilder.append(prop); + tmpBuilder.append("=*"); + tmpBuilder.append(filter); + tmpBuilder.append("*)"); + } + if (tmpBuilder.length() > 1) { + builder.append("(&(objectclass=groupOfNames)"); + if (!showSystemRoleBtn.getSelection()) + builder.append("(!(").append(LdifName.dn.name()) + .append("=*").append(GroupLP.ROLES_BASEDN) + .append("))"); + builder.append("(|"); + builder.append(tmpBuilder.toString()); + builder.append("))"); + } else { + if (!showSystemRoleBtn.getSelection()) + builder.append("(&(objectclass=groupOfNames)(!(") + .append(LdifName.dn.name()).append("=*") + .append(GroupLP.ROLES_BASEDN).append(")))"); + else + builder.append("(objectclass=groupOfNames)"); + + } + roles = userAdmin.getRoles(builder.toString()); + } catch (InvalidSyntaxException e) { + throw new ArgeoException("Unable to get roles with filter: " + + filter, e); + } + List users = new ArrayList(); + for (Role role : roles) + users.add((User) role); + return users; + } + } + + private boolean notNull(String string) { + if (string == null) + return false; + else + return !"".equals(string.trim()); + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/internal/UsersImages.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/internal/UsersImages.java new file mode 100644 index 000000000..099756fda --- /dev/null +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/internal/UsersImages.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.eclipse.ui.workbench.users.internal; + +import org.argeo.eclipse.ui.workbench.WorkbenchUiPlugin; +import org.eclipse.swt.graphics.Image; + +/** Specific users icons. TODO centralize and use an image registry */ +public class UsersImages { + private final static String PREFIX = "icons/"; + + public final static Image ICON_USER = WorkbenchUiPlugin.getImageDescriptor( + PREFIX + "user.gif").createImage(); + public final static Image ICON_GROUP = WorkbenchUiPlugin + .getImageDescriptor(PREFIX + "users.gif").createImage(); + public final static Image ICON_ROLE = WorkbenchUiPlugin.getImageDescriptor( + PREFIX + "role.gif").createImage(); +} diff --git a/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/internal/UsersUtils.java b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/internal/UsersUtils.java new file mode 100644 index 000000000..e6c29f340 --- /dev/null +++ b/org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/users/internal/UsersUtils.java @@ -0,0 +1,64 @@ +package org.argeo.eclipse.ui.workbench.users.internal; + +import java.security.AccessController; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; + +import org.argeo.ArgeoException; +import org.argeo.osgi.useradmin.LdifName; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; + +/** Utility methods to manage user concepts in the ui.workbench bundle */ +public class UsersUtils { + + public final static boolean isCurrentUser(User user) { + String userName = getProperty(user, LdifName.dn.name()); + try { + LdapName selfUserName = getLdapName(); + LdapName userLdapName = new LdapName(userName); + if (userLdapName.equals(selfUserName)) + return true; + else + return false; + } catch (InvalidNameException e) { + throw new ArgeoException("User " + user + " has an unvalid dn: " + + userName, e); + } + } + + public final static LdapName getLdapName() { + Subject subject = Subject.getSubject(AccessController.getContext()); + String name = subject.getPrincipals(X500Principal.class).iterator() + .next().toString(); + LdapName dn; + try { + dn = new LdapName(name); + } catch (InvalidNameException e) { + throw new ArgeoException("Invalid user dn " + name, e); + } + return dn; + } + + public final static String getProperty(Role role, String key) { + Object obj = role.getProperties().get(key); + if (obj != null) + return (String) obj; + else + return ""; + } + + /* + * INTERNAL METHODS: Below methods are meant to stay here and are not part + * of a potential generic backend to manage the useradmin + */ + public final static boolean notNull(String string) { + if (string == null) + return false; + else + return !"".equals(string.trim()); + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/ColumnDefinition.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/ColumnDefinition.java new file mode 100644 index 000000000..a38552c07 --- /dev/null +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/ColumnDefinition.java @@ -0,0 +1,68 @@ +package org.argeo.eclipse.ui; + +import org.eclipse.jface.viewers.ColumnLabelProvider; + +/** + * Wraps the definition of a column to be used in the various JFace viewers + * (typically tree and table). It enables definition of generic viewers which + * column can be then defined externally. Also used to generate export. + */ +public class ColumnDefinition { + private ColumnLabelProvider labelProvider; + private String label; + private int weight = 0; + private int minWidth = 120; + + public ColumnDefinition(ColumnLabelProvider labelProvider, String label) { + this.labelProvider = labelProvider; + this.label = label; + } + + public ColumnDefinition(ColumnLabelProvider labelProvider, String label, + int weight) { + this.labelProvider = labelProvider; + this.label = label; + this.weight = weight; + this.minWidth = weight; + } + + public ColumnDefinition(ColumnLabelProvider labelProvider, String label, + int weight, int minimumWidth) { + this.labelProvider = labelProvider; + this.label = label; + this.weight = weight; + this.minWidth = minimumWidth; + } + + public ColumnLabelProvider getLabelProvider() { + return labelProvider; + } + + public void setLabelProvider(ColumnLabelProvider labelProvider) { + this.labelProvider = labelProvider; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public int getMinWidth() { + return minWidth; + } + + public void setMinWidth(int minWidth) { + this.minWidth = minWidth; + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/EclipseUiUtils.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/EclipseUiUtils.java index c75c5d810..36b8e3459 100644 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/EclipseUiUtils.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/EclipseUiUtils.java @@ -45,6 +45,28 @@ public class EclipseUiUtils { parent.layout(toUpdateControls); } + // + // FONTS + // + /** Shortcut to retrieve default italic font from display */ + public static Font getItalicFont(Composite parent) { + return JFaceResources.getFontRegistry().defaultFontDescriptor() + .setStyle(SWT.ITALIC).createFont(parent.getDisplay()); + } + + /** Shortcut to retrieve default bold font from display */ + public static Font getBoldFont(Composite parent) { + return JFaceResources.getFontRegistry().defaultFontDescriptor() + .setStyle(SWT.BOLD).createFont(parent.getDisplay()); + } + + /** Shortcut to retrieve default bold italic font from display */ + public static Font getBoldItalicFont(Composite parent) { + return JFaceResources.getFontRegistry().defaultFontDescriptor() + .setStyle(SWT.BOLD | SWT.ITALIC) + .createFont(parent.getDisplay()); + } + // // Simplify grid layouts management // @@ -166,25 +188,4 @@ public class EclipseUiUtils { return txt; } - // - // FONTS - // - /** Shortcut to retrieve default italic font from display */ - public static Font getItalicFont(Composite parent) { - return JFaceResources.getFontRegistry().defaultFontDescriptor() - .setStyle(SWT.ITALIC).createFont(parent.getDisplay()); - } - - /** Shortcut to retrieve default bold font from display */ - public static Font getBoldFont(Composite parent) { - return JFaceResources.getFontRegistry().defaultFontDescriptor() - .setStyle(SWT.BOLD).createFont(parent.getDisplay()); - } - - /** Shortcut to retrieve default bold italic font from display */ - public static Font getBoldItalicFont(Composite parent) { - return JFaceResources.getFontRegistry().defaultFontDescriptor() - .setStyle(SWT.BOLD | SWT.ITALIC) - .createFont(parent.getDisplay()); - } } \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/IListProvider.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/IListProvider.java new file mode 100644 index 000000000..ac7b2d8fb --- /dev/null +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/IListProvider.java @@ -0,0 +1,20 @@ +package org.argeo.eclipse.ui; + +import java.util.List; + +/** + * Views and editors can implement this interface so that one of the list that + * is displayed in the part (For instance in a Table or a Tree Viewer) can be + * rebuilt externally. Typically to generate csv or calc extract. + */ +public interface IListProvider { + /** + * Returns an array of current and relevant elements + */ + public Object[] getElements(String extractId); + + /** + * Returns the column definition for passed ID + */ + public List getColumnDefinition(String extractId); +} diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java index 69d24a752..997b466ed 100644 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java @@ -28,7 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.argeo.eclipse.ui.AbstractTreeContentProvider; -/** Canonic implementation of tree content provider manipulating JCR nodes. */ +/** Canonical implementation of tree content provider manipulating JCR nodes. */ public abstract class AbstractNodeContentProvider extends AbstractTreeContentProvider { private static final long serialVersionUID = -4905836490027272569L; diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java index 26d802d83..4699597b3 100644 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java @@ -24,7 +24,10 @@ import org.argeo.ArgeoException; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.swt.graphics.Image; -/** Provides reasonable overridable defaults for know JCR types. */ +/** + * Default label provider to manage node and corresponding UI objects. It + * provides reasonable overwrite-able default for known JCR types. + */ public class DefaultNodeLabelProvider extends ColumnLabelProvider { private static final long serialVersionUID = 1216182332792151235L; @@ -91,5 +94,4 @@ public class DefaultNodeLabelProvider extends ColumnLabelProvider { protected String getToolTipText(Node node) throws RepositoryException { return null; } - -} +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/WrappedNode.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/WrappedNode.java index c0e197336..91dab996a 100644 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/WrappedNode.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/WrappedNode.java @@ -17,7 +17,7 @@ package org.argeo.eclipse.ui.jcr; import javax.jcr.Node; -/** Wraps a node (created from a {@link NodesWrapper}) */ +/** Wrap a node (created from a {@link NodesWrapper}) */ public class WrappedNode { private final NodesWrapper parent; private final Node node; diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/ColumnDefinition.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/ColumnDefinition.java deleted file mode 100644 index 6dd92d122..000000000 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/ColumnDefinition.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.argeo.eclipse.ui.jcr.lists; - -/** - * Utility object to manage column in various tables and extracts displaying - * data from JCR - */ -public class ColumnDefinition { - private final static int DEFAULT_COLUMN_SIZE = 120; - - private String selectorName; - private String propertyName; - private String headerLabel; - private int propertyType; - private int columnSize = DEFAULT_COLUMN_SIZE; - - /** - * new column using default width - * - * @param selectorName - * @param propertyName - * @param propertyType - * @param headerLabel - */ - public ColumnDefinition(String selectorName, String propertyName, - int propertyType, String headerLabel) { - this.selectorName = selectorName; - this.propertyName = propertyName; - this.propertyType = propertyType; - this.headerLabel = headerLabel; - } - - /** - * - * @param selectorName - * @param propertyName - * @param propertyType - * @param headerLabel - * @param columnSize - */ - public ColumnDefinition(String selectorName, String propertyName, - int propertyType, String headerLabel, int columnSize) { - this.selectorName = selectorName; - this.propertyName = propertyName; - this.propertyType = propertyType; - this.headerLabel = headerLabel; - this.columnSize = columnSize; - } - - public String getSelectorName() { - return selectorName; - } - - public void setSelectorName(String selectorName) { - this.selectorName = selectorName; - } - - public String getPropertyName() { - return propertyName; - } - - public void setPropertyName(String propertyName) { - this.propertyName = propertyName; - } - - public String getHeaderLabel() { - return headerLabel; - } - - public void setHeaderLabel(String headerLabel) { - this.headerLabel = headerLabel; - } - - public int getPropertyType() { - return propertyType; - } - - public void setPropertyType(int propertyType) { - this.propertyType = propertyType; - } - - public int getColumnSize() { - return columnSize; - } - - public void setColumnSize(int columnSize) { - this.columnSize = columnSize; - } -} \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/IListProvider.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/IListProvider.java deleted file mode 100644 index 622e2e259..000000000 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/IListProvider.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.argeo.eclipse.ui.jcr.lists; - -import java.util.List; - -/** - * Views and editors can implement this interface so that one of the row list - * that is displayed in the part (For instance in a Table or a Tree Viewer) can - * be rebuilt externally. typically to generate csv or calc extract. - */ -public interface IListProvider { - /** - * Returns an array of current and relevant elements - */ - public Object[] getElements(String extractId); - - /** - * Returns the column definition for passed ID - */ - public List getColumnDefinition(String extractId); -} diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/JcrColumnDefinition.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/JcrColumnDefinition.java new file mode 100644 index 000000000..8f35b9456 --- /dev/null +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/JcrColumnDefinition.java @@ -0,0 +1,116 @@ +package org.argeo.eclipse.ui.jcr.lists; + +import javax.jcr.Node; +import javax.jcr.query.Row; + +import org.argeo.eclipse.ui.ColumnDefinition; + +/** + * Utility object to manage column in various tables and extracts displaying + * data from JCR + */ +public class JcrColumnDefinition extends ColumnDefinition { + private final static int DEFAULT_COLUMN_SIZE = 120; + + private String selectorName; + private String propertyName; + private int propertyType; + private int columnSize; + + /** + * Use this kind of columns to configure a table that displays JCR + * {@link Row} + * + * @param selectorName + * @param propertyName + * @param propertyType + * @param headerLabel + */ + public JcrColumnDefinition(String selectorName, String propertyName, + int propertyType, String headerLabel) { + super(new SimpleJcrRowLabelProvider(selectorName, propertyName), + headerLabel); + this.selectorName = selectorName; + this.propertyName = propertyName; + this.propertyType = propertyType; + this.columnSize = DEFAULT_COLUMN_SIZE; + } + + /** + * Use this kind of columns to configure a table that displays JCR + * {@link Row} + * + * @param selectorName + * @param propertyName + * @param propertyType + * @param headerLabel + * @param columnSize + */ + public JcrColumnDefinition(String selectorName, String propertyName, + int propertyType, String headerLabel, int columnSize) { + super(new SimpleJcrRowLabelProvider(selectorName, propertyName), + headerLabel, columnSize); + this.selectorName = selectorName; + this.propertyName = propertyName; + this.propertyType = propertyType; + this.columnSize = columnSize; + } + + /** + * Use this kind of columns to configure a table that displays JCR + * {@link Node} + * + * @param propertyName + * @param propertyType + * @param headerLabel + * @param columnSize + */ + public JcrColumnDefinition(String propertyName, int propertyType, + String headerLabel, int columnSize) { + super(new SimpleJcrNodeLabelProvider(propertyName), headerLabel, + columnSize); + this.propertyName = propertyName; + this.propertyType = propertyType; + this.columnSize = columnSize; + } + + public String getSelectorName() { + return selectorName; + } + + public void setSelectorName(String selectorName) { + this.selectorName = selectorName; + } + + public String getPropertyName() { + return propertyName; + } + + public void setPropertyName(String propertyName) { + this.propertyName = propertyName; + } + + public int getPropertyType() { + return propertyType; + } + + public void setPropertyType(int propertyType) { + this.propertyType = propertyType; + } + + public int getColumnSize() { + return columnSize; + } + + public void setColumnSize(int columnSize) { + this.columnSize = columnSize; + } + + public String getHeaderLabel() { + return super.getLabel(); + } + + public void setHeaderLabel(String headerLabel) { + super.setLabel(headerLabel); + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/NodeViewerComparator.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/NodeViewerComparator.java index a0f5b13f4..1fa46f099 100644 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/NodeViewerComparator.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/NodeViewerComparator.java @@ -20,7 +20,7 @@ import org.eclipse.jface.viewers.ViewerComparator; * Note that the following snippet must be added before setting the comparator * to the corresponding control: * // IMPORTANT: initialize comparator before setting it - * ColumnDefinition firstCol = colDefs.get(0); + * JcrColumnDefinition firstCol = colDefs.get(0); * comparator.setColumn(firstCol.getPropertyType(), * firstCol.getPropertyName()); * viewer.setComparator(comparator); @@ -51,7 +51,6 @@ public class NodeViewerComparator extends ViewerComparator { long lc = 0; try { - Node n1 = (Node) e1; Node n2 = (Node) e2; @@ -90,10 +89,8 @@ public class NodeViewerComparator extends ViewerComparator { ; lc = c1.getTimeInMillis() - c2.getTimeInMillis(); if (lc < Integer.MIN_VALUE) - // rc = Integer.MIN_VALUE; rc = -1; else if (lc > Integer.MAX_VALUE) - // rc = Integer.MAX_VALUE; rc = 1; else rc = (int) lc; @@ -101,7 +98,7 @@ public class NodeViewerComparator extends ViewerComparator { case PropertyType.LONG: long l1; long l2; - // FIXME sometimes an empty string is set instead of a long + // TODO Sometimes an empty string is set instead of a long try { l1 = v1.getLong(); } catch (ValueFormatException ve) { diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrNodeLabelProvider.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrNodeLabelProvider.java index 88585c343..76611dbe5 100644 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrNodeLabelProvider.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/lists/SimpleJcrNodeLabelProvider.java @@ -13,9 +13,7 @@ import javax.jcr.Value; import org.argeo.ArgeoException; import org.eclipse.jface.viewers.ColumnLabelProvider; -/** - * Base implementation of a label provider for widgets that display JCR Rows. - */ +/** Base implementation of a label provider for controls that display JCR Nodes */ public class SimpleJcrNodeLabelProvider extends ColumnLabelProvider { private static final long serialVersionUID = -5215787695436221993L; diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/JcrUsersTable.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/JcrUsersTable.java new file mode 100644 index 000000000..5c02b6ec3 --- /dev/null +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/JcrUsersTable.java @@ -0,0 +1,364 @@ +package org.argeo.eclipse.ui.parts; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; +import javax.jcr.query.qom.Constraint; +import javax.jcr.query.qom.Ordering; +import javax.jcr.query.qom.QueryObjectModel; +import javax.jcr.query.qom.QueryObjectModelFactory; +import javax.jcr.query.qom.Selector; +import javax.jcr.query.qom.StaticOperand; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.jcr.JcrUiUtils; +import org.argeo.eclipse.ui.jcr.lists.JcrColumnDefinition; +import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator; +import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider; +import org.argeo.eclipse.ui.utils.ViewerUtils; +import org.argeo.jcr.ArgeoNames; +import org.argeo.jcr.ArgeoTypes; +import org.argeo.jcr.JcrUtils; +import org.eclipse.jface.viewers.CheckboxTableViewer; +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.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; + +/** + * Composite that contains a JFace table to display users that are stored in JCR + * following the Argeo Conventions (See {@link ArgeoNames} + */ +public class JcrUsersTable extends Composite implements ArgeoNames { + // private final static Log log = + // LogFactory.getLog(UserTableComposite.class); + + private static final long serialVersionUID = -7385959046279360420L; + + private Session session; + + private boolean hasFilter; + private boolean hasSelectionColumn; + private int tableStyle; + + private TableViewer usersViewer; + private Text filterTxt; + private String filterHelpMsg = "Type filter criterion " + + "separated by a space"; + + private Font italic; + private Font bold; + + /** Overwrite to display other columns */ + public List getColumnsDef() { + List columnDefs = new ArrayList(); + + // User ID + columnDefs.add(new JcrColumnDefinition(ARGEO_USER_ID, + PropertyType.STRING, "User ID", 100)); + // Displayed name + columnDefs.add(new JcrColumnDefinition(Property.JCR_TITLE, + PropertyType.STRING, "Name", 150)); + + // E-mail + columnDefs.add(new JcrColumnDefinition(ARGEO_PRIMARY_EMAIL, + PropertyType.STRING, "E-mail", 150)); + + // Description + columnDefs.add(new JcrColumnDefinition(Property.JCR_DESCRIPTION, + PropertyType.STRING, "Description", 200)); + + return columnDefs; + } + + public JcrUsersTable(Composite parent, int style, Session session) { + super(parent, SWT.NO_FOCUS); + this.tableStyle = style; + this.session = session; + } + + /** + * + * @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; + italic = EclipseUiUtils.getItalicFont(parent); + bold = EclipseUiUtils.getBoldFont(parent); + hasFilter = addFilter; + hasSelectionColumn = addSelection; + + // Main Layout + GridLayout layout = EclipseUiUtils.noSpaceGridLayout(); + layout.verticalSpacing = 5; + this.setLayout(layout); + if (hasFilter) + createFilterPart(parent); + usersViewer = createTableViewer(parent); + // EclipseUiSpecificUtils.enableToolTipSupport(usersViewer); + usersViewer.setContentProvider(new UsersContentProvider()); + refreshFilteredList(); + } + + public List getSelectedUsers() { + if (hasSelectionColumn) { + Object[] elements = ((CheckboxTableViewer) usersViewer) + .getCheckedElements(); + + List result = new ArrayList(); + for (Object obj : elements) { + result.add((Node) obj); + } + return result; + } else + throw new ArgeoException("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; + } + + /** Returns filter String or null */ + protected String getFilterString() { + return hasFilter ? filterTxt.getText() : null; + } + + 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); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + 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; + } + }); + 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); + } + + // Create other columns + List colDefs = getColumnsDef(); + + NodeViewerComparator comparator = new NodeViewerComparator(); + int i = offset; + for (JcrColumnDefinition colDef : colDefs) { + 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; + } + + private class CLProvider extends SimpleJcrNodeLabelProvider { + + private static final long serialVersionUID = 1L; + + public CLProvider(String propertyName) { + super(propertyName); + } + + public String getToolTipText(Object element) { + return getText(element); + } + + @Override + public Font getFont(Object elem) { + // self + String username = getProperty(elem, ARGEO_USER_ID); + if (username.equals(session.getUserID())) + return bold; + // disabled + try { + Node userProfile = (Node) elem; + if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) + return italic; + else + return null; + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get font for " + username, e); + } + } + } + + @Override + public boolean setFocus() { + usersViewer.getTable().setFocus(); + return true; + } + + @Override + public void dispose() { + super.dispose(); + } + + public void refresh() { + refreshFilteredList(); + } + + private String getProperty(Object element, String name) { + try { + Node userProfile = (Node) element; + return userProfile.hasProperty(name) ? userProfile + .getProperty(name).getString() : ""; + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get property " + name, e); + } + } + + 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.setMessage(filterHelpMsg); + 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(); + } + }); + } + + /** + * Refresh the user list: caller might overwrite in order to display a + * subset of all users, typically to remove current user from the list + */ + protected void refreshFilteredList() { + List nodes; + try { + nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session, + hasFilter ? filterTxt.getText() : null)); + usersViewer.setInput(nodes.toArray()); + } catch (RepositoryException e) { + throw new ArgeoException("Unable to list users", e); + } + } + + /** + * Build repository request : caller might overwrite in order to display a + * subset of all users + */ + protected NodeIterator listFilteredElements(Session session, String filter) + throws RepositoryException { + QueryManager queryManager = session.getWorkspace().getQueryManager(); + QueryObjectModelFactory factory = queryManager.getQOMFactory(); + + Selector source = factory.selector(ArgeoTypes.ARGEO_USER_PROFILE, + ArgeoTypes.ARGEO_USER_PROFILE); + + // Dynamically build constraint depending on the filter String + Constraint defaultC = null; + if (filter != null && !"".equals(filter.trim())) { + String[] strs = filter.trim().split(" "); + for (String token : strs) { + StaticOperand so = factory.literal(session.getValueFactory() + .createValue("*" + token + "*")); + Constraint currC = factory.fullTextSearch( + source.getSelectorName(), null, so); + if (defaultC == null) + defaultC = currC; + else + defaultC = factory.and(defaultC, currC); + } + } + + Ordering order = factory.ascending(factory.propertyValue( + source.getSelectorName(), ARGEO_USER_ID)); + Ordering[] orderings = { order }; + + QueryObjectModel query = factory.createQuery(source, defaultC, + orderings, null); + + QueryResult result = query.execute(); + return result.getNodes(); + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/LdifUsersTable.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/LdifUsersTable.java new file mode 100644 index 000000000..703f3f6de --- /dev/null +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/LdifUsersTable.java @@ -0,0 +1,410 @@ +package org.argeo.eclipse.ui.parts; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.utils.ViewerUtils; +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 TableViewer. 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 columnDefs = new ArrayList(); + 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 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 getSelectedUsers() { + if (hasSelectionColumn) { + Object[] elements = ((CheckboxTableViewer) usersViewer) + .getCheckedElements(); + + List result = new ArrayList(); + for (Object obj : elements) { + result.add((User) obj); + } + return result; + } else + throw new ArgeoException("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() : null; + if ("".equals(filter.trim())) + filter = null; + refreshFilteredList(filter); + } + + /** Effective repository request: caller must implement this method */ + abstract protected List listFilteredElements(String filter); + + // protected List listFilteredElements(String filter) { + // List users = new ArrayList(); + // try { + // Role[] roles = userAdmin.getRoles(filter); + // // Display all users and groups + // for (Role role : roles) + // users.add((User) role); + // } catch (InvalidSyntaxException e) { + // throw new ArgeoException("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 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.GRAB_HORIZONTAL + | GridData.HORIZONTAL_ALIGN_FILL)); + 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.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(" Less... "); + gd.heightHint = SWT.DEFAULT; + } else { + moreLk.setText(" More... "); + 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; + } + }); + 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; + } +} \ No newline at end of file diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/UsersTable.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/UsersTable.java deleted file mode 100644 index 41afb6a3a..000000000 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/UsersTable.java +++ /dev/null @@ -1,360 +0,0 @@ -package org.argeo.eclipse.ui.parts; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.query.QueryManager; -import javax.jcr.query.QueryResult; -import javax.jcr.query.qom.Constraint; -import javax.jcr.query.qom.Ordering; -import javax.jcr.query.qom.QueryObjectModel; -import javax.jcr.query.qom.QueryObjectModelFactory; -import javax.jcr.query.qom.Selector; -import javax.jcr.query.qom.StaticOperand; - -import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.jcr.JcrUiUtils; -import org.argeo.eclipse.ui.jcr.lists.ColumnDefinition; -import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator; -import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider; -import org.argeo.eclipse.ui.utils.ViewerUtils; -import org.argeo.jcr.ArgeoNames; -import org.argeo.jcr.ArgeoTypes; -import org.argeo.jcr.JcrUtils; -import org.eclipse.jface.viewers.CheckboxTableViewer; -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.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.Text; - -public class UsersTable extends Composite implements ArgeoNames { - // private final static Log log = - // LogFactory.getLog(UserTableComposite.class); - - private static final long serialVersionUID = -7385959046279360420L; - - private Session session; - - private boolean hasFilter; - private boolean hasSelectionColumn; - private int tableStyle; - - private TableViewer usersViewer; - private Text filterTxt; - private String filterHelpMsg = "Type filter criterion " - + "separated by a space"; - - private Font italic; - private Font bold; - - /** Overwrite to display other columns */ - public List getColumnsDef() { - List columnDefs = new ArrayList(); - - // User ID - columnDefs.add(new ColumnDefinition(null, ARGEO_USER_ID, - PropertyType.STRING, "User ID", 100)); - // Displayed name - columnDefs.add(new ColumnDefinition(null, Property.JCR_TITLE, - PropertyType.STRING, "Name", 150)); - - // E-mail - columnDefs.add(new ColumnDefinition(null, ARGEO_PRIMARY_EMAIL, - PropertyType.STRING, "E-mail", 150)); - - // Description - columnDefs.add(new ColumnDefinition(null, Property.JCR_DESCRIPTION, - PropertyType.STRING, "Description", 200)); - - return columnDefs; - } - - public UsersTable(Composite parent, int style, Session session) { - super(parent, SWT.NO_FOCUS); - this.tableStyle = style; - this.session = session; - } - - /** - * - * @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; - italic = EclipseUiUtils.getItalicFont(parent); - bold = EclipseUiUtils.getBoldFont(parent); - hasFilter = addFilter; - hasSelectionColumn = addSelection; - - // Main Layout - GridLayout layout = EclipseUiUtils.noSpaceGridLayout(); - layout.verticalSpacing = 5; - this.setLayout(layout); - if (hasFilter) - createFilterPart(parent); - usersViewer = createTableViewer(parent); - // EclipseUiSpecificUtils.enableToolTipSupport(usersViewer); - usersViewer.setContentProvider(new UsersContentProvider()); - refreshFilteredList(); - } - - public List getSelectedUsers() { - if (hasSelectionColumn) { - Object[] elements = ((CheckboxTableViewer) usersViewer) - .getCheckedElements(); - - List result = new ArrayList(); - for (Object obj : elements) { - result.add((Node) obj); - } - return result; - } else - throw new ArgeoException("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; - } - - /** Returns filter String or null */ - protected String getFilterString() { - return hasFilter ? filterTxt.getText() : null; - } - - 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); - table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - 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; - } - }); - 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); - } - - // Create other columns - List colDefs = getColumnsDef(); - - NodeViewerComparator comparator = new NodeViewerComparator(); - int i = offset; - for (ColumnDefinition colDef : colDefs) { - 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 - ColumnDefinition firstCol = colDefs.get(0); - comparator.setColumn(firstCol.getPropertyType(), - firstCol.getPropertyName()); - viewer.setComparator(comparator); - - return viewer; - } - - private class CLProvider extends SimpleJcrNodeLabelProvider { - - private static final long serialVersionUID = 1L; - - public CLProvider(String propertyName) { - super(propertyName); - } - - public String getToolTipText(Object element) { - return getText(element); - } - - @Override - public Font getFont(Object elem) { - // self - String username = getProperty(elem, ARGEO_USER_ID); - if (username.equals(session.getUserID())) - return bold; - // disabled - try { - Node userProfile = (Node) elem; - if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) - return italic; - else - return null; - } catch (RepositoryException e) { - throw new ArgeoException("Cannot get font for " + username, e); - } - } - } - - @Override - public boolean setFocus() { - usersViewer.getTable().setFocus(); - return true; - } - - @Override - public void dispose() { - super.dispose(); - } - - public void refresh() { - refreshFilteredList(); - } - - private String getProperty(Object element, String name) { - try { - Node userProfile = (Node) element; - return userProfile.hasProperty(name) ? userProfile - .getProperty(name).getString() : ""; - } catch (RepositoryException e) { - throw new ArgeoException("Cannot get property " + name, e); - } - } - - 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.setMessage(filterHelpMsg); - 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(); - } - }); - } - - /** - * Refresh the user list: caller might overwrite in order to display a - * subset of all users, typically to remove current user from the list - */ - protected void refreshFilteredList() { - List nodes; - try { - nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session, - hasFilter ? filterTxt.getText() : null)); - usersViewer.setInput(nodes.toArray()); - } catch (RepositoryException e) { - throw new ArgeoException("Unable to list users", e); - } - } - - /** - * Build repository request : caller might overwrite in order to display a - * subset of all users - */ - protected NodeIterator listFilteredElements(Session session, String filter) - throws RepositoryException { - QueryManager queryManager = session.getWorkspace().getQueryManager(); - QueryObjectModelFactory factory = queryManager.getQOMFactory(); - - Selector source = factory.selector(ArgeoTypes.ARGEO_USER_PROFILE, - ArgeoTypes.ARGEO_USER_PROFILE); - - // Dynamically build constraint depending on the filter String - Constraint defaultC = null; - if (filter != null && !"".equals(filter.trim())) { - String[] strs = filter.trim().split(" "); - for (String token : strs) { - StaticOperand so = factory.literal(session.getValueFactory() - .createValue("*" + token + "*")); - Constraint currC = factory.fullTextSearch( - source.getSelectorName(), null, so); - if (defaultC == null) - defaultC = currC; - else - defaultC = factory.and(defaultC, currC); - } - } - - Ordering order = factory.ascending(factory.propertyValue( - source.getSelectorName(), ARGEO_USER_ID)); - Ordering[] orderings = { order }; - - QueryObjectModel query = factory.createQuery(source, defaultC, - orderings, null); - - QueryResult result = query.execute(); - return result.getNodes(); - } -} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/META-INF/spring/common.xml b/org.argeo.security.ui.admin/META-INF/spring/common.xml index 38d87da4c..f3b7ecb01 100644 --- a/org.argeo.security.ui.admin/META-INF/spring/common.xml +++ b/org.argeo.security.ui.admin/META-INF/spring/common.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - @@ -25,7 +24,4 @@ - - - \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java index a296961ea..ab92b8d19 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java @@ -31,8 +31,6 @@ public class SecurityAdminPerspective implements IPerspectiveFactory { IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.25f, editorArea); left.addView(UsersView.ID); - // left.addView(JcrUsersView.ID); - // left.addView(JcrRolesView.ID); IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT, 0.70f, editorArea); diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/ColumnDefinition.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/ColumnDefinition.java deleted file mode 100644 index ad24c6226..000000000 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/ColumnDefinition.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.argeo.security.ui.admin.internal; - -import org.eclipse.jface.viewers.ColumnLabelProvider; - -/** Centralize the colum definition for the various tables of the useradmin UI */ -public class ColumnDefinition { - private ColumnLabelProvider labelProvider; - private String label; - private int weight; - private int minWidth; - - public ColumnDefinition(ColumnLabelProvider labelProvider, String label, - int weight, int minimumWidth) { - this.labelProvider = labelProvider; - this.label = label; - this.weight = weight; - this.minWidth = minimumWidth; - } - - public ColumnDefinition(ColumnLabelProvider labelProvider, String label, - int weight) { - this.labelProvider = labelProvider; - this.label = label; - this.weight = weight; - this.minWidth = weight; - } - - public ColumnLabelProvider getLabelProvider() { - return labelProvider; - } - - public void setLabelProvider(ColumnLabelProvider labelProvider) { - this.labelProvider = labelProvider; - } - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public int getWeight() { - return weight; - } - - public void setWeight(int weight) { - this.weight = weight; - } - - public int getMinWidth() { - return minWidth; - } - - public void setMinWidth(int minWidth) { - this.minWidth = minWidth; - } -} diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java index 2d437540f..1a5f375d0 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java @@ -1,22 +1,17 @@ package org.argeo.security.ui.admin.internal; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IStartup; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.contexts.IContextActivation; /** Manage transaction and part refresh while updating the security model */ public class PartStateChanged implements IPartListener, IStartup { - private final static Log log = LogFactory.getLog(PartStateChanged.class); - IContextActivation contextActivation; + // private final static Log log = LogFactory.getLog(PartStateChanged.class); + // private IContextActivation contextActivation; @Override public void earlyStartup() { @@ -38,39 +33,7 @@ public class PartStateChanged implements IPartListener, IStartup { @Override public void partActivated(IWorkbenchPart part) { - if (log.isTraceEnabled()) - log.trace("Part activated: " + part.getTitle() + " - " - + part.getClass()); - - // Try to avoid NPE when closing the application - IWorkbenchPartSite site = part.getSite(); - if (site == null) - return; - IWorkbenchWindow window = site.getWorkbenchWindow(); - if (window == null) - return; - - // // Retrieve the service to enable/disable checkout button - // ISourceProviderService sourceProviderService = - // (ISourceProviderService) window - // .getService(ISourceProviderService.class); - // EditionSourceProvider esp = (EditionSourceProvider) - // sourceProviderService - // .getSourceProvider(EditionSourceProvider.EDITING_STATE); - // if (part instanceof IVersionedItemEditor) { - // IStatusLineManager manager = ((IEditorPart) part).getEditorSite() - // .getActionBars().getStatusLineManager(); - // manager.setMessage(((IVersionedItemEditor) part) - // .getlastUpdateMessage()); - // - // } - // if (part instanceof CmsEditable) { - // CmsEditable editor = (CmsEditable) part; - // // Processing the ability to checkout is delegated to the editor - // esp.setCurrentItemEditingState(editor.isEditing()); - // } else {// force button to be disabled if another part has the focus. - // esp.setCurrentItemEditingState(true); - // } + // Nothing to do } @Override @@ -85,28 +48,11 @@ public class PartStateChanged implements IPartListener, IStartup { @Override public void partDeactivated(IWorkbenchPart part) { - // Always remove checkOut button when the editor is left. - // if (part instanceof IVersionedItemEditor) { - // // Try to avoid NPE when closing the application - // IWorkbenchPartSite site = part.getSite(); - // if (site == null) - // return; - // IWorkbenchWindow window = site.getWorkbenchWindow(); - // if (window == null) - // return; - // - // // Retrieve the service to enable/disable checkout button - // ISourceProviderService sourceProviderService = - // (ISourceProviderService) window - // .getService(ISourceProviderService.class); - // EditionSourceProvider esp = (EditionSourceProvider) - // sourceProviderService - // .getSourceProvider(EditionSourceProvider.EDITING_STATE); - // esp.setCurrentItemEditingState(true); - // } + // Nothing to do } @Override public void partOpened(IWorkbenchPart part) { + // Nothing to do } } \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java index 062be2dfc..4419d80a9 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java @@ -10,6 +10,7 @@ import javax.transaction.Status; import javax.transaction.UserTransaction; import org.argeo.ArgeoException; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.internal.providers.UserTransactionProvider; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; @@ -28,8 +29,7 @@ public class UiAdminUtils { } public final static boolean isCurrentUser(User user) { - String userName = UiAdminUtils.getProperty(user, - UserAdminConstants.KEY_DN); + String userName = getProperty(user, LdifName.dn.name()); try { LdapName selfUserName = UiAdminUtils.getLdapName(); LdapName userLdapName = new LdapName(userName); @@ -57,14 +57,14 @@ public class UiAdminUtils { } public final static User getUser(UserAdmin userAdmin, LdapName dn) { - User user = userAdmin.getUser(UserAdminConstants.KEY_DN, dn.toString()); + User user = userAdmin.getUser(LdifName.dn.name(), dn.toString()); return user; } public final static String getUsername(User user) { - String cn = getProperty(user, UserAdminConstants.KEY_CN); + String cn = getProperty(user, LdifName.dn.name()); if (isEmpty(cn)) - cn = getProperty(user, UserAdminConstants.KEY_UID); + cn = getProperty(user, LdifName.uid.name()); return cn; } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminConstants.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminConstants.java index 848b27993..a2e28b02d 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminConstants.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminConstants.java @@ -3,15 +3,11 @@ package org.argeo.security.ui.admin.internal; /** Temporary centralization of the user admin constants */ public interface UserAdminConstants { - public final static String KEY_UID = "uid"; - public final static String KEY_DN = "dn"; - public final static String KEY_CN = "cn"; + public final static String KEY_DESC = "description"; public final static String KEY_FIRSTNAME = "givenname"; public final static String KEY_LASTNAME = "sn"; - public final static String KEY_MAIL = "mail"; - public final static String KEY_DESC = "description"; // TO BE CLEANED public final static String SYSTEM_ROLE_BASE_DN = "ou=roles,ou=node"; - + } \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java index d2ad472b3..de09f7b19 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java @@ -14,7 +14,7 @@ import org.osgi.service.useradmin.UserAdmin; import org.osgi.service.useradmin.UserAdminEvent; import org.osgi.service.useradmin.UserAdminListener; -/** Simplifies the interaction with the UserAdmin in this bundle */ +/** Centralize interaction with the UserAdmin in this bundle */ public class UserAdminWrapper { // private Log log = LogFactory.getLog(UserAdminWrapper.class); @@ -62,21 +62,9 @@ public class UserAdminWrapper { return userTransaction; } - /* DEPENDENCY INJECTION */ - public void setUserAdmin(UserAdmin userAdmin) { - this.userAdmin = userAdmin; - } - public void setUserAdminServiceReference( ServiceReference userAdminServiceReference) { this.userAdminServiceReference = userAdminServiceReference; - // for (String uri : userAdminServiceReference.getPropertyKeys()) { - // if (!uri.startsWith("/")) - // continue; - // log.debug(uri); - // Dictionary props = UserAdminConf.uriAsProperties(uri); - // log.debug(props); - // } } public List getKnownBaseDns(boolean onlyWritable) { @@ -90,28 +78,17 @@ public class UserAdminWrapper { if (onlyWritable && "true".equals(readOnly)) continue; + if (baseDn.equalsIgnoreCase(UserAdminConstants.SYSTEM_ROLE_BASE_DN)) + continue; dns.add(baseDn); } return dns; } - // // Returns the human friendly domain name give a dn. - // public String getDomainName(String dn) { - // if (dn.endsWith("ou=roles, ou=node")) - // return "System roles"; - // try { - // - // LdapName name; - // name = new LdapName(dn); - // List rdns = name.getRdns(); - // - // String penultimate = (String) rdns.get(rdns.size() - 2).getValue(); - // String last = (String) rdns.get(rdns.size() - 1).getValue(); - // return (penultimate + '.' + last); - // } catch (InvalidNameException e) { - // throw new ArgeoException("Unable to get domain name for " + dn, e); - // } - // } + /* DEPENDENCY INJECTION */ + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } public void setUserTransaction(UserTransaction userTransaction) { this.userTransaction = userTransaction; diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTableViewer.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTableViewer.java deleted file mode 100644 index ed29315e4..000000000 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTableViewer.java +++ /dev/null @@ -1,317 +0,0 @@ -package org.argeo.security.ui.admin.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.utils.ViewerUtils; -import org.argeo.security.ui.admin.internal.providers.UserAdminAbstractLP; -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.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Text; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; - -/** - * Generic composite that display a filter and a table viewer to display users - * (can also be groups) - * - * Warning: this class does not extends TableViewer. Use the - * getTableViewer to acces it. - * - */ -public class UserTableViewer extends Composite { - private static final long serialVersionUID = -7385959046279360420L; - - // Context - private UserAdmin userAdmin; - - // Configuration - private List columnDefs = new ArrayList(); - 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 - * @param userAdmin - */ - public UserTableViewer(Composite parent, int style, UserAdmin userAdmin) { - super(parent, SWT.NO_FOCUS); - this.tableStyle = style; - this.userAdmin = userAdmin; - } - - // TODO workaround the bug of the table layout in the Form - public UserTableViewer(Composite parent, int style, UserAdmin userAdmin, - boolean preventTableLayout) { - super(parent, SWT.NO_FOCUS); - this.tableStyle = style; - this.userAdmin = userAdmin; - this.preventTableLayout = preventTableLayout; - } - - /** This must be called before the call to populate method */ - public void setColumnDefinitions(List 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()); - } - - /** Enable access to the selected users or groups */ - public List getSelectedUsers() { - if (hasSelectionColumn) { - Object[] elements = ((CheckboxTableViewer) usersViewer) - .getCheckedElements(); - - List result = new ArrayList(); - for (Object obj : elements) { - result.add((User) obj); - } - return result; - } else - throw new ArgeoException("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() : null; - if ("".equals(filter.trim())) - filter = null; - refreshFilteredList(filter); - } - - /** - * Build repository request : caller might overwrite in order to display a - * subset of all users - */ - protected List listFilteredElements(String filter) { - List users = new ArrayList(); - try { - Role[] roles = userAdmin.getRoles(filter); - // Display all users and groups - for (Role role : roles) - users.add((User) role); - } catch (InvalidSyntaxException e) { - throw new ArgeoException("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 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.GRAB_HORIZONTAL - | GridData.HORIZONTAL_ALIGN_FILL)); - filterTxt.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = 1L; - - public void modifyText(ModifyEvent event) { - refreshFilteredList(filterTxt.getText()); - } - }); - } - - 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; - } - }); - 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 - // ColumnDefinition 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; - } -} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java index 47bd5f5da..93b1b61ad 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java @@ -36,7 +36,7 @@ import org.osgi.service.useradmin.Group; import org.osgi.service.useradmin.UserAdmin; import org.osgi.service.useradmin.UserAdminEvent; -/** Deletes the selected groups */ +/** Delete the selected groups */ public class DeleteGroups extends AbstractHandler { public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".deleteGroups"; diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java index 901c37137..44c76ea1a 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java @@ -36,7 +36,7 @@ import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; import org.osgi.service.useradmin.UserAdminEvent; -/** Deletes the selected users */ +/** Delete the selected users */ public class DeleteUsers extends AbstractHandler { public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".deleteUsers"; diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewGroup.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewGroup.java index b52bf9955..ddf0dceb7 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewGroup.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewGroup.java @@ -44,7 +44,6 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.ui.handlers.HandlerUtil; import org.osgi.service.useradmin.Group; import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.UserAdmin; import org.osgi.service.useradmin.UserAdminEvent; /** Create a new group. */ @@ -53,7 +52,6 @@ public class NewGroup extends AbstractHandler { /* DEPENDENCY INJECTION */ private UserAdminWrapper userAdminWrapper; - private UserAdmin userAdmin; public Object execute(ExecutionEvent event) throws ExecutionException { NewGroupWizard newGroupWizard = new NewGroupWizard(); @@ -93,8 +91,8 @@ public class NewGroup extends AbstractHandler { String commonName = commonNameTxt.getText(); try { userAdminWrapper.beginTransactionIfNeeded(); - Group group = (Group) userAdmin.createRole(getDn(commonName), - Role.GROUP); + Group group = (Group) userAdminWrapper.getUserAdmin() + .createRole(getDn(commonName), Role.GROUP); Dictionary props = group.getProperties(); String descStr = descriptionTxt.getText(); if (UiAdminUtils.notNull(descStr)) @@ -189,7 +187,8 @@ public class NewGroup extends AbstractHandler { if (name.trim().equals("")) return "Common name must not be empty"; - Role role = userAdmin.getRole(getDn(name)); + Role role = userAdminWrapper.getUserAdmin() + .getRole(getDn(name)); if (role != null) return "Group " + name + " already exists"; return null; @@ -233,6 +232,5 @@ public class NewGroup extends AbstractHandler { /* DEPENDENCY INJECTION */ public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { this.userAdminWrapper = userAdminWrapper; - this.userAdmin = userAdminWrapper.getUserAdmin(); } } \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewUser.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewUser.java index 4c1e8f4cb..7f89b6ab2 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewUser.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewUser.java @@ -26,6 +26,7 @@ import org.argeo.ArgeoException; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; import org.argeo.jcr.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.SecurityAdminPlugin; import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.argeo.security.ui.admin.internal.UserAdminConstants; @@ -69,25 +70,10 @@ public class NewUser extends AbstractHandler { NewUserWizard newUserWizard = new NewUserWizard(); WizardDialog dialog = new WizardDialog( HandlerUtil.getActiveShell(event), newUserWizard); - dialog.open(); - - // // Force refresh until the listener are implemented - // if (Window.OK == dialog.open()) - // forceRefresh(event); return null; } - // private void forceRefresh(ExecutionEvent event) { - // IWorkbenchWindow iww = HandlerUtil.getActiveWorkbenchWindow(event); - // if (iww == null) - // return; - // IWorkbenchPage activePage = iww.getActivePage(); - // IWorkbenchPart part = activePage.getActivePart(); - // if (part instanceof UsersView) - // ((UsersView) part).refresh(); - // } - private class NewUserWizard extends Wizard { // pages @@ -125,7 +111,7 @@ public class NewUser extends AbstractHandler { String lastNameStr = lastNameTxt.getText(); if (UiAdminUtils.notNull(lastNameStr)) - props.put(UserAdminConstants.KEY_LASTNAME, lastNameStr); + props.put(LdifName.dn.name(), lastNameStr); String firstNameStr = firstNameTxt.getText(); if (UiAdminUtils.notNull(firstNameStr)) @@ -134,11 +120,11 @@ public class NewUser extends AbstractHandler { String cn = UiAdminUtils .getDefaultCn(firstNameStr, lastNameStr); if (UiAdminUtils.notNull(cn)) - props.put(UserAdminConstants.KEY_CN, cn); + props.put(LdifName.cn.name(), cn); String mailStr = primaryMailTxt.getText(); if (UiAdminUtils.notNull(mailStr)) - props.put(UserAdminConstants.KEY_MAIL, mailStr); + props.put(LdifName.mail.name(), mailStr); char[] password = mainUserInfo.getPassword(); user.getCredentials().put(null, password); diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/DefaultUserMainPage.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/DefaultUserMainPage.java index bb770e68e..306a872e7 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/DefaultUserMainPage.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/DefaultUserMainPage.java @@ -226,7 +226,6 @@ public class DefaultUserMainPage extends FormPage implements ArgeoNames { public void modifyText(ModifyEvent e) { formPart.markDirty(); } - } public String getNewPassword() { diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java index 5270e1463..5df5b662d 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java @@ -19,14 +19,15 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.jcr.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.SecurityAdminImages; -import org.argeo.security.ui.admin.internal.ColumnDefinition; import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.argeo.security.ui.admin.internal.UserAdminConstants; import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.UserTableViewer; import org.argeo.security.ui.admin.internal.parts.UserEditor.GroupChangeListener; import org.argeo.security.ui.admin.internal.parts.UserEditor.MainInfoListener; import org.argeo.security.ui.admin.internal.providers.CommonNameLP; @@ -107,11 +108,11 @@ public class GroupMainPage extends FormPage implements ArgeoNames { body.setLayout(layout); final Text dnTxt = createLT(body, "DN", - UiAdminUtils.getProperty(group, UserAdminConstants.KEY_DN)); + UiAdminUtils.getProperty(group, LdifName.dn.name())); dnTxt.setEnabled(false); final Text cnTxt = createLT(body, "Common Name", - UiAdminUtils.getProperty(group, UserAdminConstants.KEY_CN)); + UiAdminUtils.getProperty(group, LdifName.cn.name())); cnTxt.setEnabled(false); Label descLbl = new Label(body, SWT.LEAD); @@ -156,7 +157,7 @@ public class GroupMainPage extends FormPage implements ArgeoNames { refreshFormTitle(group); dnTxt.setText(group.getName()); cnTxt.setText(UiAdminUtils.getProperty(group, - UserAdminConstants.KEY_CN)); + LdifName.cn.name())); descTxt.setText(UiAdminUtils.getProperty(group, UserAdminConstants.KEY_DESC)); @@ -181,7 +182,7 @@ public class GroupMainPage extends FormPage implements ArgeoNames { section.setClient(body); body.setLayoutData(EclipseUiUtils.fillAll()); - UserTableViewer userTableViewerCmp = createMemberPart(body, group); + LdifUsersTable userTableViewerCmp = createMemberPart(body, group); // create form part (controller) SectionPart part = new GroupMembersPart(section, userTableViewerCmp, @@ -190,7 +191,7 @@ public class GroupMainPage extends FormPage implements ArgeoNames { addRemoveAbitily(part, userTableViewerCmp.getTableViewer(), group); } - public UserTableViewer createMemberPart(Composite parent, Group group) { + public LdifUsersTable createMemberPart(Composite parent, Group group) { parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); // Define the displayed columns List columnDefs = new ArrayList(); @@ -202,7 +203,7 @@ public class GroupMainPage extends FormPage implements ArgeoNames { "Distinguished Name", 240)); // Create and configure the table - UserTableViewer userViewerCmp = new MyUserTableViewer(parent, SWT.MULTI + LdifUsersTable userViewerCmp = new MyUserTableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, userAdminWrapper.getUserAdmin()); userViewerCmp.setColumnDefinitions(columnDefs); @@ -223,12 +224,12 @@ public class GroupMainPage extends FormPage implements ArgeoNames { // Local viewers - private class MyUserTableViewer extends UserTableViewer { + private class MyUserTableViewer extends LdifUsersTable { private static final long serialVersionUID = 8467999509931900367L; public MyUserTableViewer(Composite parent, int style, UserAdmin userAdmin) { - super(parent, style, userAdmin, true); + super(parent, style, true); } @Override @@ -310,12 +311,12 @@ public class GroupMainPage extends FormPage implements ArgeoNames { // LOCAL CONTROLLERS private class GroupMembersPart extends SectionPart { - private final UserTableViewer userViewer; + private final LdifUsersTable userViewer; private final Group group; private GroupChangeListener listener; - public GroupMembersPart(Section section, UserTableViewer userViewer, + public GroupMembersPart(Section section, LdifUsersTable userViewer, Group group) { super(section); this.userViewer = userViewer; @@ -341,7 +342,7 @@ public class GroupMainPage extends FormPage implements ArgeoNames { getSection().setText( "Members of group " + UiAdminUtils.getProperty(group, - UserAdminConstants.KEY_CN)); + LdifName.cn.name())); userViewer.refresh(); super.refresh(); } @@ -355,11 +356,11 @@ public class GroupMainPage extends FormPage implements ArgeoNames { private static final long serialVersionUID = 2893468717831451621L; private final UserAdminWrapper userAdminWrapper; - // private final UserTableViewer myUserViewerCmp; + // private final LdifUsersTable myUserViewerCmp; private final Group myGroup; public GroupDropListener(UserAdminWrapper userAdminWrapper, - UserTableViewer userTableViewerCmp, Group group) { + LdifUsersTable userTableViewerCmp, Group group) { super(userTableViewerCmp.getTableViewer()); this.userAdminWrapper = userAdminWrapper; this.myGroup = group; @@ -438,7 +439,7 @@ public class GroupMainPage extends FormPage implements ArgeoNames { // LOCAL HELPERS private void refreshFormTitle(Group group) { getManagedForm().getForm().setText( - UiAdminUtils.getProperty(group, UserAdminConstants.KEY_CN)); + UiAdminUtils.getProperty(group, LdifName.cn.name())); } private Composite addSection(FormToolkit tk, Composite parent, String title) { diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java index 0f4d12ccf..fd1931a4f 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java @@ -18,15 +18,18 @@ package org.argeo.security.ui.admin.internal.parts; import java.util.ArrayList; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.jcr.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.SecurityAdminPlugin; -import org.argeo.security.ui.admin.internal.ColumnDefinition; import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.argeo.security.ui.admin.internal.UserAdminConstants; import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.UserTableViewer; import org.argeo.security.ui.admin.internal.providers.CommonNameLP; import org.argeo.security.ui.admin.internal.providers.DomainNameLP; import org.argeo.security.ui.admin.internal.providers.RoleIconLP; @@ -38,17 +41,21 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.part.ViewPart; import org.osgi.framework.InvalidSyntaxException; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; import org.osgi.service.useradmin.UserAdminEvent; import org.osgi.service.useradmin.UserAdminListener; /** List all groups with filter */ public class GroupsView extends ViewPart implements ArgeoNames { + private final static Log log = LogFactory.getLog(GroupsView.class); public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".groupsView"; @@ -56,7 +63,7 @@ public class GroupsView extends ViewPart implements ArgeoNames { private UserAdminWrapper userAdminWrapper; // UI Objects - private UserTableViewer groupTableViewerCmp; + private LdifUsersTable groupTableViewerCmp; private TableViewer userViewer; private List columnDefs = new ArrayList(); @@ -75,10 +82,10 @@ public class GroupsView extends ViewPart implements ArgeoNames { // Create and configure the table groupTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL, userAdminWrapper.getUserAdmin()); + | SWT.H_SCROLL | SWT.V_SCROLL); groupTableViewerCmp.setColumnDefinitions(columnDefs); - groupTableViewerCmp.populate(true, false); + groupTableViewerCmp.populateWithStaticFilters(false, false); groupTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); // Links @@ -106,15 +113,31 @@ public class GroupsView extends ViewPart implements ArgeoNames { userAdminWrapper.addListener(listener); } - private class MyUserTableViewer extends UserTableViewer { + private class MyUserTableViewer extends LdifUsersTable { private static final long serialVersionUID = 8467999509931900367L; - private final String[] knownProps = { UserAdminConstants.KEY_UID, - UserAdminConstants.KEY_CN, UserAdminConstants.KEY_DN }; + private Button showSystemRoleBtn; - public MyUserTableViewer(Composite parent, int style, - UserAdmin userAdmin) { - super(parent, style, userAdmin); + private final String[] knownProps = { LdifName.uid.name(), + LdifName.cn.name(), LdifName.dn.name() }; + + 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"); + showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -7033424592697691676L; + + @Override + public void widgetSelected(SelectionEvent e) { + refresh(); + } + + }); } @Override @@ -132,11 +155,25 @@ public class GroupsView extends ViewPart implements ArgeoNames { tmpBuilder.append("*)"); } if (tmpBuilder.length() > 1) { - builder.append("(&(objectclass=groupOfNames)(|"); + builder.append("(&(objectclass=groupOfNames)"); + if (!showSystemRoleBtn.getSelection()) + builder.append("(!(").append(LdifName.dn.name()) + .append("=*") + .append(UserAdminConstants.SYSTEM_ROLE_BASE_DN) + .append("))"); + builder.append("(|"); builder.append(tmpBuilder.toString()); builder.append("))"); - } else - builder.append("(objectclass=groupOfNames)"); + } else { + if (!showSystemRoleBtn.getSelection()) + builder.append("(&(objectclass=groupOfNames)(!(") + .append(LdifName.dn.name()).append("=*") + .append(UserAdminConstants.SYSTEM_ROLE_BASE_DN) + .append(")))"); + else + builder.append("(objectclass=groupOfNames)"); + + } roles = userAdminWrapper.getUserAdmin().getRoles( builder.toString()); } catch (InvalidSyntaxException e) { @@ -145,8 +182,11 @@ public class GroupsView extends ViewPart implements ArgeoNames { } List users = new ArrayList(); for (Role role : roles) - // if (role.getType() == Role.GROUP) - users.add((User) role); + if (!users.contains(role)) + users.add((User) role); + else + log.warn("Duplicated role: " + role); + return users; } } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java index 5c86abf32..e49c803e4 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; import org.argeo.ArgeoException; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.SecurityAdminPlugin; import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.argeo.security.ui.admin.internal.UserAdminConstants; @@ -98,7 +99,8 @@ public class UserEditor extends FormEditor implements UserAdminConstants { void updateEditorTitle(String title) { if (title == null) { - String commonName = UiAdminUtils.getProperty(user, KEY_CN); + String commonName = UiAdminUtils.getProperty(user, + LdifName.cn.name()); title = "".equals(commonName) ? user.getName() : commonName; } setPartName(title); diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java index 154be42f3..ab8ea3216 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java @@ -20,14 +20,15 @@ import java.util.Iterator; import java.util.List; import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.jcr.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.SecurityAdminImages; -import org.argeo.security.ui.admin.internal.ColumnDefinition; import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.argeo.security.ui.admin.internal.UserAdminConstants; import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.UserTableViewer; import org.argeo.security.ui.admin.internal.parts.UserEditor.GroupChangeListener; import org.argeo.security.ui.admin.internal.parts.UserEditor.MainInfoListener; import org.argeo.security.ui.admin.internal.providers.CommonNameLP; @@ -113,11 +114,11 @@ public class UserMainPage extends FormPage implements ArgeoNames { body.setLayout(new GridLayout(2, false)); final Text distinguishedName = createLT(tk, body, "User Name", - UiAdminUtils.getProperty(user, UserAdminConstants.KEY_UID)); + UiAdminUtils.getProperty(user, LdifName.uid.name())); distinguishedName.setEnabled(false); final Text commonName = createLT(tk, body, "Common Name", - UiAdminUtils.getProperty(user, UserAdminConstants.KEY_CN)); + UiAdminUtils.getProperty(user, LdifName.cn.name())); commonName.setEnabled(false); final Text firstName = createLT(tk, body, "First name", @@ -128,7 +129,7 @@ public class UserMainPage extends FormPage implements ArgeoNames { UiAdminUtils.getProperty(user, UserAdminConstants.KEY_LASTNAME)); final Text email = createLT(tk, body, "Email", - UiAdminUtils.getProperty(user, UserAdminConstants.KEY_MAIL)); + UiAdminUtils.getProperty(user, LdifName.mail.name())); // create form part (controller) AbstractFormPart part = new SectionPart((Section) body.getParent()) { @@ -154,10 +155,9 @@ public class UserMainPage extends FormPage implements ArgeoNames { firstName.getText()); user.getProperties().put(UserAdminConstants.KEY_LASTNAME, lastName.getText()); - user.getProperties().put(UserAdminConstants.KEY_CN, + user.getProperties().put(LdifName.cn.name(), commonName.getText()); - user.getProperties().put(UserAdminConstants.KEY_MAIL, - email.getText()); + user.getProperties().put(LdifName.mail.name(), email.getText()); // Enable common name ? // editor.setProperty(UserAdminConstants.KEY_CN, // email.getText()); @@ -167,15 +167,14 @@ public class UserMainPage extends FormPage implements ArgeoNames { @Override public void refresh() { distinguishedName.setText(UiAdminUtils.getProperty(user, - UserAdminConstants.KEY_UID)); + LdifName.uid.name())); commonName.setText(UiAdminUtils.getProperty(user, - UserAdminConstants.KEY_CN)); + LdifName.cn.name())); firstName.setText(UiAdminUtils.getProperty(user, UserAdminConstants.KEY_FIRSTNAME)); lastName.setText(UiAdminUtils.getProperty(user, UserAdminConstants.KEY_LASTNAME)); - email.setText(UiAdminUtils.getProperty(user, - UserAdminConstants.KEY_MAIL)); + email.setText(LdifName.mail.name()); refreshFormTitle(user); super.refresh(); } @@ -245,7 +244,7 @@ public class UserMainPage extends FormPage implements ArgeoNames { getManagedForm().addPart(part); } - private UserTableViewer appendMemberOfPart(Composite parent, User user) { + private LdifUsersTable appendMemberOfPart(Composite parent, User user) { FormToolkit tk = getManagedForm().getToolkit(); Section section = addSection(tk, parent, "Roles"); Composite body = (Composite) section.getClient(); @@ -262,9 +261,8 @@ public class UserMainPage extends FormPage implements ArgeoNames { "Distinguished Name", 300)); // Create and configure the table - final UserTableViewer userViewerCmp = new MyUserTableViewer(body, - SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, - userAdminWrapper.getUserAdmin(), user); + final LdifUsersTable userViewerCmp = new MyUserTableViewer(body, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, user); userViewerCmp.setColumnDefinitions(columnDefs); userViewerCmp.populate(true, false); @@ -313,14 +311,13 @@ public class UserMainPage extends FormPage implements ArgeoNames { return userViewerCmp; } - private class MyUserTableViewer extends UserTableViewer { + private class MyUserTableViewer extends LdifUsersTable { private static final long serialVersionUID = 8467999509931900367L; private final User user; - public MyUserTableViewer(Composite parent, int style, - UserAdmin userAdmin, User user) { - super(parent, style, userAdmin, true); + public MyUserTableViewer(Composite parent, int style, User user) { + super(parent, style, true); this.user = user; } @@ -460,7 +457,7 @@ public class UserMainPage extends FormPage implements ArgeoNames { // LOCAL HELPERS private void refreshFormTitle(User group) { getManagedForm().getForm().setText( - UiAdminUtils.getProperty(group, UserAdminConstants.KEY_CN)); + UiAdminUtils.getProperty(group, LdifName.cn.name())); } /** Appends a section with a title */ diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UsersView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UsersView.java index 70e79daec..837d6a17e 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UsersView.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UsersView.java @@ -19,14 +19,15 @@ import java.util.ArrayList; import java.util.List; import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.jcr.ArgeoNames; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.SecurityAdminPlugin; -import org.argeo.security.ui.admin.internal.ColumnDefinition; import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.argeo.security.ui.admin.internal.UserAdminConstants; import org.argeo.security.ui.admin.internal.UserAdminWrapper; -import org.argeo.security.ui.admin.internal.UserTableViewer; import org.argeo.security.ui.admin.internal.providers.CommonNameLP; import org.argeo.security.ui.admin.internal.providers.DomainNameLP; import org.argeo.security.ui.admin.internal.providers.MailLP; @@ -43,23 +44,21 @@ import org.eclipse.ui.part.ViewPart; import org.osgi.framework.InvalidSyntaxException; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; import org.osgi.service.useradmin.UserAdminEvent; import org.osgi.service.useradmin.UserAdminListener; /** List all users with filter - based on Ldif userAdmin */ public class UsersView extends ViewPart implements ArgeoNames { // private final static Log log = LogFactory.getLog(UsersView.class); + public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".usersView"; /* DEPENDENCY INJECTION */ private UserAdminWrapper userAdminWrapper; - private UserAdmin userAdmin; - // UI Objects - private UserTableViewer userTableViewerCmp; + private LdifUsersTable userTableViewerCmp; private TableViewer userViewer; private List columnDefs = new ArrayList(); @@ -79,7 +78,7 @@ public class UsersView extends ViewPart implements ArgeoNames { // Create and configure the table userTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL, userAdmin); + | SWT.H_SCROLL | SWT.V_SCROLL); userTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); userTableViewerCmp.setColumnDefinitions(columnDefs); @@ -110,17 +109,16 @@ public class UsersView extends ViewPart implements ArgeoNames { userAdminWrapper.addListener(listener); } - private class MyUserTableViewer extends UserTableViewer { + private class MyUserTableViewer extends LdifUsersTable { private static final long serialVersionUID = 8467999509931900367L; - private final String[] knownProps = { UserAdminConstants.KEY_UID, - UserAdminConstants.KEY_DN, UserAdminConstants.KEY_CN, + private final String[] knownProps = { LdifName.uid.name(), + LdifName.dn.name(), LdifName.cn.name(), UserAdminConstants.KEY_FIRSTNAME, - UserAdminConstants.KEY_LASTNAME, UserAdminConstants.KEY_MAIL }; + UserAdminConstants.KEY_LASTNAME, LdifName.mail.name() }; - public MyUserTableViewer(Composite parent, int style, - UserAdmin userAdmin) { - super(parent, style, userAdmin); + public MyUserTableViewer(Composite parent, int style) { + super(parent, style); } @Override @@ -145,7 +143,8 @@ public class UsersView extends ViewPart implements ArgeoNames { builder.append("))"); } else builder.append("(objectclass=inetOrgPerson)"); - roles = userAdmin.getRoles(builder.toString()); + roles = userAdminWrapper.getUserAdmin().getRoles( + builder.toString()); } catch (InvalidSyntaxException e) { throw new ArgeoException("Unable to get roles with filter: " + filter, e); @@ -178,6 +177,5 @@ public class UsersView extends ViewPart implements ArgeoNames { /* DEPENDENCY INJECTION */ public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { this.userAdminWrapper = userAdminWrapper; - this.userAdmin = userAdminWrapper.getUserAdmin(); } } \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java index cc6c3d90c..1bd387e20 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java @@ -1,5 +1,6 @@ package org.argeo.security.ui.admin.internal.providers; +import org.argeo.osgi.useradmin.LdifName; import org.osgi.service.useradmin.User; /** Simply declare a label provider that returns the common name of a user */ @@ -8,7 +9,7 @@ public class CommonNameLP extends UserAdminAbstractLP { @Override public String getText(User user) { - Object obj = user.getProperties().get(KEY_CN); + Object obj = user.getProperties().get(LdifName.cn.name()); if (obj != null) return (String) obj; else diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java index ddd771aea..287d2facc 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java @@ -7,16 +7,17 @@ import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; import org.argeo.ArgeoException; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.internal.UserAdminConstants; import org.osgi.service.useradmin.User; -/** Returns the human friendly domain name for the corresponding user. */ +/** The human friendly domain name for the corresponding user. */ public class DomainNameLP extends UserAdminAbstractLP { private static final long serialVersionUID = 5256703081044911941L; @Override public String getText(User user) { - String dn = (String) user.getProperties().get(KEY_DN); + String dn = (String) user.getProperties().get(LdifName.dn.name()); if (dn.endsWith(UserAdminConstants.SYSTEM_ROLE_BASE_DN)) return "System roles"; try { diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/MailLP.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/MailLP.java index b56776795..1037446c9 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/MailLP.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/MailLP.java @@ -2,9 +2,10 @@ package org.argeo.security.ui.admin.internal.providers; import java.util.Dictionary; +import org.argeo.osgi.useradmin.LdifName; import org.osgi.service.useradmin.User; -/** Simply declare a label provider that returns the Primary Mail for a user */ +/** Simply declare a label provider that returns the Primary Mail of a user */ public class MailLP extends UserAdminAbstractLP { private static final long serialVersionUID = 8329764452141982707L; @@ -12,7 +13,7 @@ public class MailLP extends UserAdminAbstractLP { public String getText(User user) { @SuppressWarnings("rawtypes") Dictionary props = user.getProperties(); - Object obj = props.get(KEY_MAIL); + Object obj = props.get(LdifName.mail.name()); if (obj != null) return (String) obj; else diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/RoleIconLP.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/RoleIconLP.java index 8bda40429..1529f9059 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/RoleIconLP.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/RoleIconLP.java @@ -1,11 +1,13 @@ package org.argeo.security.ui.admin.internal.providers; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.SecurityAdminImages; import org.argeo.security.ui.admin.internal.UserAdminConstants; import org.eclipse.swt.graphics.Image; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; +/** Provide a bundle specific image depending on the current user type */ public class RoleIconLP extends UserAdminAbstractLP { private static final long serialVersionUID = 6550449442061090388L; @@ -17,7 +19,7 @@ public class RoleIconLP extends UserAdminAbstractLP { @Override public Image getImage(Object element) { User user = (User) element; - String dn = (String) user.getProperties().get(KEY_DN); + String dn = (String) user.getProperties().get(LdifName.dn.name()); if (dn.endsWith(UserAdminConstants.SYSTEM_ROLE_BASE_DN)) return SecurityAdminImages.ICON_ROLE; else if (user.getType() == Role.GROUP) diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java index 68138ca26..0590088b2 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java @@ -3,6 +3,8 @@ package org.argeo.security.ui.admin.internal.providers; import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; +import org.argeo.ArgeoException; +import org.argeo.osgi.useradmin.LdifName; import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.argeo.security.ui.admin.internal.UserAdminConstants; import org.eclipse.jface.resource.JFaceResources; @@ -29,13 +31,17 @@ public abstract class UserAdminAbstractLP extends ColumnLabelProvider implements try { LdapName selfUserName = UiAdminUtils.getLdapName(); String userName = UiAdminUtils.getProperty((User) element, - UserAdminConstants.KEY_DN); + LdifName.dn.name()); LdapName userLdapName = new LdapName(userName); - if (userLdapName.equals(selfUserName)) + if (userLdapName.equals(selfUserName)) { + if (bold == null) + bold = JFaceResources.getFontRegistry() + .defaultFontDescriptor().setStyle(SWT.BOLD) + .createFont(Display.getCurrent()); return bold; + } } catch (InvalidNameException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + throw new ArgeoException("cannot parse dn for " + element, e); } // Disabled as Italic @@ -57,7 +63,7 @@ public abstract class UserAdminAbstractLP extends ColumnLabelProvider implements // italic = JFaceResources.getFontRegistry().defaultFontDescriptor() // .setStyle(SWT.ITALIC).createFont(display); bold = JFaceResources.getFontRegistry().defaultFontDescriptor() - .setStyle(SWT.BOLD).createFont(display); + .setStyle(SWT.BOLD).createFont(Display.getCurrent()); } public abstract String getText(User user); diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserDragListener.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserDragListener.java index 74b837a73..f60b64c65 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserDragListener.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserDragListener.java @@ -6,6 +6,7 @@ import org.eclipse.swt.dnd.DragSourceEvent; import org.eclipse.swt.dnd.DragSourceListener; import org.osgi.service.useradmin.User; +/** Default drag listener to modify group and users via the UI */ public class UserDragListener implements DragSourceListener { private static final long serialVersionUID = -2074337775033781454L; private final Viewer viewer; diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTableDefaultDClickListener.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTableDefaultDClickListener.java index 82e227b11..fa45edd86 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTableDefaultDClickListener.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTableDefaultDClickListener.java @@ -24,14 +24,13 @@ public class UserTableDefaultDClickListener implements IDoubleClickListener { Object obj = ((IStructuredSelection) evt.getSelection()) .getFirstElement(); User user = (User) obj; - // IWorkbench iw = IWorkbenchWindow iww = WorkbenchUiPlugin.getDefault().getWorkbench() .getActiveWorkbenchWindow(); IWorkbenchPage iwp = iww.getActivePage(); UserEditorInput uei = new UserEditorInput(user.getName()); try { - // Work around the fact that dynamic setting of the editor icon + // Works around the fact that dynamic setting of the editor icon // causes NPE after a login/logout on RAP if (user instanceof Group) iwp.openEditor(uei, UserEditor.GROUP_EDITOR_ID); diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTransactionProvider.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTransactionProvider.java index 877e5641f..43c71ddff 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTransactionProvider.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserTransactionProvider.java @@ -11,7 +11,7 @@ import org.argeo.security.ui.admin.SecurityAdminPlugin; import org.eclipse.ui.AbstractSourceProvider; import org.eclipse.ui.ISources; -/** Notifies the UI on UserTransaction state change */ +/** Observe and notify UI on UserTransaction state changes */ public class UserTransactionProvider extends AbstractSourceProvider { public final static String TRANSACTION_STATE = SecurityAdminPlugin.PLUGIN_ID + ".userTransactionState"; @@ -51,7 +51,7 @@ public class UserTransactionProvider extends AbstractSourceProvider { } } - /** Publish the ability to notify a state change */ + /** Publishes the ability to notify a state change */ public void fireTransactionStateChange() { fireSourceChanged(ISources.WORKBENCH, TRANSACTION_STATE, getInternalCurrentState()); diff --git a/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java b/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java index f29fc8e4e..14bcee124 100644 --- a/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java +++ b/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/RapActionBarAdvisor.java @@ -15,6 +15,7 @@ */ package org.argeo.security.ui.rap; +import org.argeo.cms.auth.CurrentUser; import org.argeo.security.ui.commands.OpenHomePerspective; import org.eclipse.core.commands.Category; import org.eclipse.core.commands.Command; @@ -110,7 +111,8 @@ public class RapActionBarAdvisor extends ActionBarAdvisor { @Override protected void fillCoolBar(ICoolBarManager coolBar) { - // Add a command which label is the login of the current logged-in user + // Add a command which label is the display name of the current + // logged-in user if (username != null) { ICommandService cmdService = (ICommandService) getActionBarConfigurer() .getWindowConfigurer().getWorkbenchConfigurer() @@ -122,7 +124,10 @@ public class RapActionBarAdvisor extends ActionBarAdvisor { + ".userMenuCommand"); if (userMenu.isDefined()) userMenu.undefine(); - userMenu.define(username, "User menu actions", userMenus); + userMenu.define(CurrentUser.getDisplayName(), "User menu actions", + userMenus); + // userMenu.define(username, "User menu actions", userMenus); + userMenu.setHandler(new OpenHomePerspective()); // userToolbar.add(new UserMenuAction());