Enable user and group deletion. Remove dynamic Editor icon that triggered NPE on...
authorBruno Sinou <bsinou@argeo.org>
Tue, 15 Sep 2015 11:10:38 +0000 (11:10 +0000)
committerBruno Sinou <bsinou@argeo.org>
Tue, 15 Sep 2015 11:10:38 +0000 (11:10 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8398 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.security.ui.admin/META-INF/spring/commands.xml
org.argeo.security.ui.admin/plugin.xml
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteGroups.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteUsers.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/NewGroup.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/NewUser.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/GroupMainPage.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserMainPage.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/UsersView.java

index a2a25d7e844bf98fbaf40a14ecc309eae83a63fc..6ce0496c669938313d01396ae7f03f801bf666be 100644 (file)
@@ -4,7 +4,7 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
 
-       <!-- USERS -->
+       <!-- USERS & GROUPS CRUDS -->
        <bean id="newUser" class="org.argeo.security.ui.admin.commands.NewUser"
                scope="prototype">
                <property name="userAdmin" ref="userAdmin" />
                <property name="userAdmin" ref="userAdmin" />
                <property name="userTransaction" ref="userTransaction" />
        </bean>
+       <bean id="deleteUsers" class="org.argeo.security.ui.admin.commands.DeleteUsers"
+               scope="prototype">
+               <property name="userAdmin" ref="userAdmin" />
+               <property name="userTransaction" ref="userTransaction" />
+       </bean>
+       <bean id="deleteGroups" class="org.argeo.security.ui.admin.commands.DeleteGroups"
+               scope="prototype">
+               <property name="userAdmin" ref="userAdmin" />
+               <property name="userTransaction" ref="userTransaction" />
+       </bean>
 
        <!-- <bean id="userBatchUpdate" class="org.argeo.security.ui.admin.commands.UserBatchUpdate" 
                scope="prototype"> <property name="repository" ref="nodeRepository" /> <property 
index 6bdfd6d8b4b8e923a44f42749fd57e3ab3158818..86fca8c114a05db6b9b8495bdd3090ffed92097d 100644 (file)
@@ -52,7 +52,7 @@
        </command>
                <command
                        id="org.argeo.security.ui.admin.deleteUsers"
-                       defaultHandler="org.argeo.security.ui.admin.commands.DeleteUsers"
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
                        name="Delete User">
                </command>
                <!-- Group CRUD -->
@@ -63,7 +63,7 @@
                </command>
                <command
             id="org.argeo.security.ui.admin.deleteGroups"
-            defaultHandler="org.argeo.security.ui.admin.commands.DeleteGroups"
+                       defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
             name="Delete Group">
                </command>
                <!-- Transaction -->
index b655cd136bdc9dc5c2ac424f39c7becbad149c4a..88700cdd941080296a06a8e179b151edcefbcbab 100644 (file)
@@ -19,42 +19,49 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeMap;
 
+import javax.transaction.UserTransaction;
+
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
 import org.argeo.security.ui.admin.internal.UiAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminConstants;
+import org.argeo.security.ui.admin.views.GroupsView;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.handlers.HandlerUtil;
 import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.UserAdmin;
 
 /** Deletes the selected groups */
 public class DeleteGroups extends AbstractHandler {
-       public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".deleteGroups";
+       public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+                       + ".deleteGroups";
+
+       /* DEPENDENCY INJECTION */
+       private UserAdmin userAdmin;
+       private UserTransaction userTransaction;
 
-       
        @SuppressWarnings("unchecked")
        public Object execute(ExecutionEvent event) throws ExecutionException {
                ISelection selection = HandlerUtil.getCurrentSelection(event);
                if (selection.isEmpty())
                        return null;
 
-               Map<String, Group> toDelete = new TreeMap<String, Group>();
+               Map<String, String> toDelete = new TreeMap<String, String>();
+               // List<String> names = new ArrayList<String>();
                Iterator<Group> it = ((IStructuredSelection) selection).iterator();
-               groups: while (it.hasNext()) {
+               while (it.hasNext()) {
                        Group currGroup = it.next();
                        String groupName = UiAdminUtils.getProperty(currGroup,
                                        UserAdminConstants.KEY_CN);
-
                        // TODO add checks
-                       // if (userName.equals(profileNode.getSession().getUserID())) {
-                       // log.warn("Cannot delete its own user: " + userName);
-                       // continue groups;
-                       // }
-                       toDelete.put(groupName, currGroup);
+                       toDelete.put(groupName, currGroup.getName());
                }
 
                if (!MessageDialog
@@ -67,20 +74,31 @@ public class DeleteGroups extends AbstractHandler {
                                                                + "This might lead to inconsistencies in the application."))
                        return null;
 
-               for (String groupName : toDelete.keySet()) {
-               }
-               MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
-                               "Unimplemented method",
-                               "The effective deletion is not yet implemented");
-               // TODO refresh?
-               // JcrUsersView view = (JcrUsersView) HandlerUtil
-               // .getActiveWorkbenchWindow(event).getActivePage()
-               // .findView(JcrUsersView.ID);
-               // view.refresh();
+               UiAdminUtils.beginTransactionIfNeeded(userTransaction);
+               for (String name : toDelete.values())
+                       userAdmin.removeRole(name);
+
+               // TODO rather notify the update listener
+               forceRefresh(event);
                return null;
        }
 
-       // public void setUserAdmin(UserAdmin userAdmin) {
-       // this.userAdmin = userAdmin;
-       // }
+       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 GroupsView)
+                       ((GroupsView) part).refresh();
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setUserAdmin(UserAdmin userAdmin) {
+               this.userAdmin = userAdmin;
+       }
+
+       public void setUserTransaction(UserTransaction userTransaction) {
+               this.userTransaction = userTransaction;
+       }
 }
\ No newline at end of file
index af2fb567ff81504294f512d71bad018bbec4be2b..554e90aff3421da52c565bb7d6a96e8866897e22 100644 (file)
@@ -19,20 +19,32 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeMap;
 
+import javax.transaction.UserTransaction;
+
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
 import org.argeo.security.ui.admin.internal.UiAdminUtils;
+import org.argeo.security.ui.admin.views.UsersView;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.handlers.HandlerUtil;
 import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
 
 /** Deletes the selected users */
 public class DeleteUsers extends AbstractHandler {
-       public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".deleteUsers";
+       public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+                       + ".deleteUsers";
+
+       /* DEPENDENCY INJECTION */
+       private UserAdmin userAdmin;
+       private UserTransaction userTransaction;
 
        @SuppressWarnings("unchecked")
        public Object execute(ExecutionEvent event) throws ExecutionException {
@@ -40,17 +52,18 @@ public class DeleteUsers extends AbstractHandler {
                if (selection.isEmpty())
                        return null;
 
-               Map<String, User> toDelete = new TreeMap<String, User>();
+               Map<String, String> toDelete = new TreeMap<String, String>();
+               // Map<String, User> toDelete = new TreeMap<String, User>();
                Iterator<User> it = ((IStructuredSelection) selection).iterator();
                users: while (it.hasNext()) {
                        User currUser = it.next();
                        String userName = UiAdminUtils.getUsername(currUser);
-                       // check not deleting own user
+                       // TODO check not deleting own user
                        // if (userName.equals(profileNode.getSession().getUserID())) {
                        // log.warn("Cannot delete its own user: " + userName);
                        // continue nodes;
                        // }
-                       toDelete.put(userName, currUser);
+                       toDelete.put(userName, currUser.getName());
                }
 
                if (!MessageDialog
@@ -63,17 +76,32 @@ public class DeleteUsers extends AbstractHandler {
                                                                + "This might lead to inconsistencies in the application."))
                        return null;
 
-               for (String username : toDelete.keySet()) {
-                       // TODO perform real deletion
+               UiAdminUtils.beginTransactionIfNeeded(userTransaction);
+               for (String name : toDelete.values()) {
+                       userAdmin.removeRole(name);
                }
-               MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
-                               "Unimplemented method",
-                               "The effective deletion is not yet implemented");
-               // TODO refresh?
-               // JcrUsersView view = (JcrUsersView) HandlerUtil
-               // .getActiveWorkbenchWindow(event).getActivePage()
-               // .findView(JcrUsersView.ID);
-               // view.refresh();
+
+               // TODO rather notify the update listener
+               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();
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setUserAdmin(UserAdmin userAdmin) {
+               this.userAdmin = userAdmin;
+       }
+
+       public void setUserTransaction(UserTransaction userTransaction) {
+               this.userTransaction = userTransaction;
+       }
 }
\ No newline at end of file
index 22780f27cf3bd0f625343591d7bce35d452e82df..d797c5d748fae47b1c09b59a63009acc0c259466 100644 (file)
@@ -17,10 +17,8 @@ package org.argeo.security.ui.admin.commands;
 
 import java.util.Dictionary;
 
-import javax.transaction.Status;
 import javax.transaction.UserTransaction;
 
-import org.argeo.ArgeoException;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.jcr.ArgeoNames;
@@ -111,17 +109,8 @@ public class NewGroup extends AbstractHandler {
                        if (!canFinish())
                                return false;
                        String commonName = commonNameTxt.getText();
-
-                       // Begin transaction if needed
-                       try {
-                               if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
-                                       userTransaction.begin();
-                       } catch (Exception e) {
-                               throw new ArgeoException("Unable to start "
-                                               + "transaction to create user " + commonName, e);
-                       }
-
                        try {
+                               UiAdminUtils.beginTransactionIfNeeded(userTransaction);
                                Group user = (Group) userAdmin.createRole(getDn(commonName),
                                                Role.GROUP);
                                Dictionary props = user.getProperties();
index 9f1ae8d0d0d37363b670c0ba250ad8c8028fb3d6..656185b73e401f0c99cbc6d440d388b2f1a240b7 100644 (file)
@@ -17,10 +17,8 @@ package org.argeo.security.ui.admin.commands;
 
 import java.util.Dictionary;
 
-import javax.transaction.Status;
 import javax.transaction.UserTransaction;
 
-import org.argeo.ArgeoException;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.jcr.ArgeoNames;
@@ -112,17 +110,8 @@ public class NewUser extends AbstractHandler {
                        if (!canFinish())
                                return false;
                        String username = mainUserInfo.getUsername();
-
-                       // Begin transaction if needed
-                       try {
-                               if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
-                                       userTransaction.begin();
-                       } catch (Exception e) {
-                               throw new ArgeoException("Unable to start "
-                                               + "transaction to create user " + username, e);
-                       }
-
                        try {
+                               UiAdminUtils.beginTransactionIfNeeded(userTransaction);
                                char[] password = mainUserInfo.getPassword();
                                User user = (User) userAdmin.createRole(getDn(username),
                                                Role.USER);
index f56f1cf670ee995fb80899a7a7892e9bfdc910ca..401aa400d5eeaabe811474a8b99fe35d09c39d96 100644 (file)
@@ -31,12 +31,21 @@ import org.argeo.security.ui.admin.internal.UserAdminConstants;
 import org.argeo.security.ui.admin.internal.UserNameLP;
 import org.argeo.security.ui.admin.internal.UserTableDefaultDClickListener;
 import org.argeo.security.ui.admin.internal.UserTableViewer;
+import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.forms.AbstractFormPart;
 import org.eclipse.ui.forms.IManagedForm;
@@ -140,12 +149,6 @@ public class GroupMainPage extends FormPage implements ArgeoNames {
        private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
 
        public void createMemberPart(Composite parent) {
-               // parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-               // parent2.setLayoutData(EclipseUiUtils.fillAll());
-               // Composite parent = new Composite(parent2, SWT.NO_FOCUS);
-               // parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-               // parent.setLayoutData(EclipseUiUtils.fillAll());
-
                parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
                // Define the displayed columns
                columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24));
@@ -170,6 +173,12 @@ public class GroupMainPage extends FormPage implements ArgeoNames {
                userViewer.addDoubleClickListener(new UserTableDefaultDClickListener());
                // Really?
                userTableViewerCmp.refresh();
+
+               // Drag and drop
+               int operations = DND.DROP_COPY | DND.DROP_MOVE;
+               Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
+               userViewer.addDropSupport(operations, tt, new GroupDropListener(
+                               userViewer, userAdmin, (Group) editor.getDisplayedUser()));
        }
 
        private class MyUserTableViewer extends UserTableViewer {
@@ -197,6 +206,89 @@ public class GroupMainPage extends FormPage implements ArgeoNames {
                                editor.getProperty(UserAdminConstants.KEY_CN));
        }
 
+       /**
+        * Defines this table as being a potential target to add group membership
+        * (roles) to this user
+        */
+       private class GroupDropListener extends ViewerDropAdapter {
+               private static final long serialVersionUID = 2893468717831451621L;
+
+               private final UserAdmin myUserAdmin;
+               private final Group myGroup;
+
+               public GroupDropListener(Viewer viewer, UserAdmin userAdmin, Group group) {
+                       super(viewer);
+                       this.myUserAdmin = userAdmin;
+                       this.myGroup = group;
+               }
+
+               @Override
+               public boolean validateDrop(Object target, int operation,
+                               TransferData transferType) {
+                       // Target is always OK in a list only view
+                       // TODO check if not a string
+                       boolean validDrop = true;
+                       return validDrop;
+               }
+
+               @Override
+               public void drop(DropTargetEvent event) {
+                       String newUserName = (String) event.data;
+                       Role role = myUserAdmin.getRole(newUserName);
+                       // TODO this check should be done before.
+                       if (role.getType() == Role.USER) {
+                               // TODO check if the user is already member of this group
+                               // we expect here that there is already a begun transaction
+                               // TODO implement the dirty state
+                               editor.beginTransactionIfNeeded();
+                               User user = (User) role;
+                               myGroup.addMember(user);
+                       } else if (role.getType() == Role.GROUP) {
+                               Group newGroup = (Group) role;
+
+                               Shell shell = getViewer().getControl().getShell();
+                               // Sanity checks
+                               if (myGroup == newGroup) { // Equality
+
+                                       MessageDialog.openError(shell, "Forbidden addition ",
+                                                       "A group cannot be a member of itself.");
+                                       return;
+                               }
+
+                               // Cycle
+                               String myName = myGroup.getName();
+                               List<User> myMemberships = editor.getFlatGroups(myGroup);
+                               if (myMemberships.contains(newGroup)) {
+                                       MessageDialog.openError(shell, "Forbidden addition: cycle",
+                                                       "Cannot add " + newUserName + " to group " + myName
+                                                                       + ". This would create a cycle");
+                                       return;
+                               }
+
+                               // Already member
+                               List<User> newGroupMemberships = editor.getFlatGroups(newGroup);
+                               if (newGroupMemberships.contains(myGroup)) {
+                                       MessageDialog.openError(shell, "Forbidden addition",
+                                                       "Cannot add " + newUserName + " to group " + myName
+                                                                       + ", this membership already exists");
+                                       return;
+                               }
+
+                               editor.beginTransactionIfNeeded();
+                               // TODO implement the dirty state
+                               myGroup.addMember(newGroup);
+                       }
+                       super.drop(event);
+               }
+
+               @Override
+               public boolean performDrop(Object data) {
+                       userTableViewerCmp.refresh();
+                       return true;
+               }
+       }
+
+       // LOCAL HELPERS
        private Composite addSection(FormToolkit tk, Composite parent, String title) {
                Section section = tk.createSection(parent, Section.TITLE_BAR);
                GridData gd = EclipseUiUtils.fillWidth();
@@ -218,17 +310,4 @@ public class GroupMainPage extends FormPage implements ArgeoNames {
                text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
                return text;
        }
-
-       // private class FormPartML implements ModifyListener {
-       // private static final long serialVersionUID = 6299808129505381333L;
-       // private AbstractFormPart formPart;
-       //
-       // public FormPartML(AbstractFormPart generalPart) {
-       // this.formPart = generalPart;
-       // }
-       //
-       // public void modifyText(ModifyEvent e) {
-       // formPart.markDirty();
-       // }
-       // }
 }
\ No newline at end of file
index 485956b9a3cb504f046cb6c278992e6e8be8d8d3..76e6a690367caa15a66fed5acacf30ea68c7289e 100644 (file)
@@ -21,8 +21,8 @@ import java.util.List;
 import javax.transaction.UserTransaction;
 
 import org.argeo.ArgeoException;
-import org.argeo.security.ui.admin.SecurityAdminImages;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.internal.UiAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminConstants;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.ui.IEditorInput;
@@ -56,20 +56,28 @@ public class UserEditor extends FormEditor implements UserAdminConstants {
                user = (User) userAdmin.getRole(username);
 
                String commonName = getProperty(KEY_CN);
-               // this.setPartProperty("name", commonName != null ? commonName
-               // : "username");
 
-               // if (user.getType() == Role.GROUP) {
-               // this.setPartProperty("icon", "icons/users.gif");
-               // firePartPropertyChanged("icon", "icons/user.gif", "icons/users.gif");
-               // }
                setPartName(commonName != null ? commonName : "username");
-               setTitleImage(user.getType() == Role.GROUP ? SecurityAdminImages.ICON_GROUP
-                               : SecurityAdminImages.ICON_USER);
+
+               // TODO: following has been disabled because it causes NPE after a
+               // login/logout on RAP
+               // Image titleIcon = user.getType() == Role.GROUP ?
+               // SecurityAdminImages.ICON_GROUP
+               // : SecurityAdminImages.ICON_USER;
+               // setTitleImage(titleIcon);
        }
 
-       protected List<User> getFlatGroups() {
-               Authorization currAuth = userAdmin.getAuthorization(user);
+       /**
+        * returns the list of all authorisation for the given user or of the
+        * current displayed user if parameter is null
+        */
+       protected List<User> getFlatGroups(User aUser) {
+               Authorization currAuth;
+               if (aUser == null)
+                       currAuth = userAdmin.getAuthorization(this.user);
+               else
+                       currAuth = userAdmin.getAuthorization(aUser);
+
                String[] roles = currAuth.getRoles();
 
                List<User> groups = new ArrayList<User>();
@@ -109,7 +117,14 @@ public class UserEditor extends FormEditor implements UserAdminConstants {
                        return "";
        }
 
-       /** The property is directly updated!!! */
+       protected void beginTransactionIfNeeded() {
+               UiAdminUtils.beginTransactionIfNeeded(userTransaction);
+       }
+
+       /**
+        * Updates the property in the working copy. The transaction must be
+        * explicitly committed to persist the update.
+        */
        @SuppressWarnings("unchecked")
        protected void setProperty(String key, String value) {
                user.getProperties().put(key, value);
index 41b21651f8b9acbaa74481a798ac183170a94c42..c657c35086650e1f01f636ffbf8c3b97f6235690 100644 (file)
@@ -249,7 +249,7 @@ public class UserMainPage extends FormPage implements ArgeoNames {
                // Drag and drop
                int operations = DND.DROP_COPY | DND.DROP_MOVE;
                Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
-               userViewer.addDropSupport(operations, tt, new ItemDropListener(
+               userViewer.addDropSupport(operations, tt, new GroupDropListener(
                                userViewer, userAdmin, editor.getDisplayedUser()));
 
        }
@@ -264,19 +264,21 @@ public class UserMainPage extends FormPage implements ArgeoNames {
 
                @Override
                protected List<User> listFilteredElements(String filter) {
-                       return (List<User>) editor.getFlatGroups();
+                       return (List<User>) editor.getFlatGroups(null);
                }
        }
 
-       // DRAG & DROP MANAGEMENT
-
-       private class ItemDropListener extends ViewerDropAdapter {
+       /**
+        * Defines this table as being a potential target to add group membership
+        * (roles) to this user
+        */
+       private class GroupDropListener extends ViewerDropAdapter {
                private static final long serialVersionUID = 2893468717831451621L;
 
                private final UserAdmin myUserAdmin;
                private final User myUser;
 
-               public ItemDropListener(Viewer viewer, UserAdmin userAdmin, User user) {
+               public GroupDropListener(Viewer viewer, UserAdmin userAdmin, User user) {
                        super(viewer);
                        this.myUserAdmin = userAdmin;
                        this.myUser = user;
@@ -300,6 +302,7 @@ public class UserMainPage extends FormPage implements ArgeoNames {
                                // TODO check if the user is already member of this group
                                // we expect here that there is already a begun transaction
                                // TODO implement the dirty state
+                               editor.beginTransactionIfNeeded();
                                Group group = (Group) role;
                                group.addMember(myUser);
                        }
index 05858cbd4e4b290a74a0afb5821137e4e734a2de..5430b34d90710432e4000511119e7a88e977ed32 100644 (file)
@@ -5,7 +5,10 @@ import java.security.Principal;
 
 import javax.security.auth.Subject;
 import javax.security.auth.x500.X500Principal;
+import javax.transaction.Status;
+import javax.transaction.UserTransaction;
 
+import org.argeo.ArgeoException;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
 
@@ -38,6 +41,16 @@ public class UiAdminUtils {
                return (firstName.trim() + " " + lastName.trim() + " ").trim();
        }
 
+       public final static void beginTransactionIfNeeded(
+                       UserTransaction userTransaction) {
+               try {
+                       if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
+                               userTransaction.begin();
+               } catch (Exception e) {
+                       throw new ArgeoException("Unable to begin transaction", e);
+               }
+       }
+
        /*
         * INTERNAL METHODS: Below methods are meant to stay here and are not part
         * of a potential generic backend to manage the useradmin
index 538329559a1ef3284754990f4691baddae8a01a8..a14e2b42f9e13ee9c725d99b87b685dbb50ae602 100644 (file)
@@ -21,6 +21,7 @@ import java.util.List;
 import org.argeo.ArgeoException;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.jcr.ArgeoNames;
+import org.argeo.security.ui.admin.SecurityAdminImages;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
 import org.argeo.security.ui.admin.internal.ColumnDefinition;
 import org.argeo.security.ui.admin.internal.CommonNameLP;
@@ -36,6 +37,7 @@ 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.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.part.ViewPart;
 import org.osgi.framework.InvalidSyntaxException;
@@ -59,6 +61,7 @@ public class UsersView extends ViewPart implements ArgeoNames {
 
        @Override
        public void createPartControl(Composite parent) {
+
                parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
                // Define the displayed columns
                columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name",
@@ -88,6 +91,12 @@ public class UsersView extends ViewPart implements ArgeoNames {
                Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
                userViewer.addDragSupport(operations, tt, new UserDragListener(
                                userViewer));
+
+               // FIXME insure the group and person icons are registered before calling
+               // the open editor
+               @SuppressWarnings("unused")
+               Image dummyImg = SecurityAdminImages.ICON_GROUP;
+               dummyImg = SecurityAdminImages.ICON_USER;
        }
 
        private class MyUserTableViewer extends UserTableViewer {