You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2006/12/28 10:38:48 UTC

svn commit: r490684 - in /directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor: icons/ src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/ src/org/apache/directory/ldapstudio/aciitemeditor/widgets/

Author: seelmann
Date: Thu Dec 28 01:38:47 2006
New Revision: 490684

URL: http://svn.apache.org/viewvc?view=rev&rev=490684
Log:
Added three-state-checkbox and categories in GrantsAndDenials, precedence is optional, updated displayed string in ItemPermission and UserPermission

Added:
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_deny.gif   (with props)
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_grant.gif   (with props)
Modified:
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/ItemPermissionDialog.java
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/UserPermissionDialog.java
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGeneralComposite.java
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGrantsAndDenialsComposite.java
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java
    directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserPermissionsComposite.java

Added: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_deny.gif
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_deny.gif?view=auto&rev=490684
==============================================================================
Binary file - no diff available.

Propchange: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_deny.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_grant.gif
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_grant.gif?view=auto&rev=490684
==============================================================================
Binary file - no diff available.

Propchange: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/icons/checkbox_grant.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/ItemPermissionDialog.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/ItemPermissionDialog.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/ItemPermissionDialog.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/ItemPermissionDialog.java Thu Dec 28 01:38:47 2006
@@ -32,11 +32,13 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Spinner;
 
@@ -54,7 +56,7 @@
 
     private ItemPermission returnItemPermission;
     
-    private Label precedenceLabel = null;
+    private Button precedenceCheckbox = null;
     
     private Spinner precedenceSpinner = null;
     
@@ -97,7 +99,7 @@
     {
         try
         {
-            int precedence = precedenceSpinner.getSelection();
+            int precedence = precedenceCheckbox.getSelection() ? precedenceSpinner.getSelection() : -1;
             Collection<UserClass> userClasses = userClassesComposite.getUserClasses();
             Collection<GrantAndDenial> grantsAndDenials = grantsAndDenialsComposite.getGrantsAndDenials();
             returnItemPermission = new ItemPermission(precedence, grantsAndDenials, userClasses);
@@ -119,10 +121,23 @@
         Composite spinnerComposite = new Composite( composite, SWT.NONE );
         spinnerComposite.setLayout( new GridLayout( 2, false ) );
         spinnerComposite.setLayoutData( new GridData() );
-        precedenceLabel = new Label( spinnerComposite, SWT.NONE );
-        precedenceLabel.setText( "Precedence:" );
+        precedenceCheckbox = new Button( spinnerComposite, SWT.CHECK );
+        precedenceCheckbox.setText( "Precedence:" );
+        precedenceCheckbox.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                precedenceSpinner.setEnabled( precedenceCheckbox.getSelection() );
+            }
+        } );
         precedenceSpinner = new Spinner( spinnerComposite, SWT.BORDER );
-        precedenceSpinner.setValues( 0, 0, 255, 0, 1, 10 );
+        precedenceSpinner.setMinimum( 0 );
+        precedenceSpinner.setMaximum( 255 );
+        precedenceSpinner.setDigits( 0 );
+        precedenceSpinner.setIncrement( 1 );
+        precedenceSpinner.setPageIncrement( 10 );
+        precedenceSpinner.setSelection( 0 );
+        precedenceSpinner.setEnabled( false );
         GridData precedenceGridData = new GridData();
         precedenceGridData.grabExcessHorizontalSpace = true;
         precedenceGridData.verticalAlignment = GridData.CENTER;
@@ -137,7 +152,12 @@
         
         if(initialItemPermission != null)
         {
-            precedenceSpinner.setSelection( initialItemPermission.getPrecedence() );
+            if ( initialItemPermission.getPrecedence() > -1 )
+            {
+                precedenceCheckbox.setSelection( true );
+                precedenceSpinner.setEnabled( true );
+                precedenceSpinner.setSelection( initialItemPermission.getPrecedence() );
+            }
             userClassesComposite.setUserClasses( initialItemPermission.getUserClasses() );
             grantsAndDenialsComposite.setGrantsAndDenials( initialItemPermission.getGrantsAndDenials() );
         }

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/UserPermissionDialog.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/UserPermissionDialog.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/UserPermissionDialog.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/dialogs/UserPermissionDialog.java Thu Dec 28 01:38:47 2006
@@ -21,16 +21,12 @@
 package org.apache.directory.ldapstudio.aciitemeditor.dialogs;
 
 
-import java.text.ParseException;
 import java.util.Collection;
 
-import javax.swing.SpinnerListModel;
-
 import org.apache.directory.ldapstudio.aciitemeditor.widgets.ACIItemGrantsAndDenialsComposite;
 import org.apache.directory.ldapstudio.aciitemeditor.widgets.ACIItemProtectedItemsComposite;
 import org.apache.directory.shared.ldap.aci.GrantAndDenial;
 import org.apache.directory.shared.ldap.aci.ProtectedItem;
-import org.apache.directory.shared.ldap.aci.UserClass;
 import org.apache.directory.shared.ldap.aci.UserPermission;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
@@ -43,11 +39,8 @@
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Spinner;
-import org.eclipse.swt.widgets.Text;
 
 
 public class UserPermissionDialog extends Dialog
@@ -62,13 +55,13 @@
     private UserPermission initialUserPermission;
 
     private UserPermission returnUserPermission;
-    
-    private Label precedenceLabel = null;
-    
+
+    private Button precedenceCheckbox = null;
+
     private Spinner precedenceSpinner = null;
-    
+
     private ACIItemProtectedItemsComposite protectedItemsComposite;
-    
+
     private ACIItemGrantsAndDenialsComposite grantsAndDenialsComposite;
 
 
@@ -106,10 +99,10 @@
     {
         try
         {
-            int precedence = precedenceSpinner.getSelection();
+            int precedence = precedenceCheckbox.getSelection() ? precedenceSpinner.getSelection() : -1;
             Collection<ProtectedItem> protectedItems = protectedItemsComposite.getProtectedItems();
             Collection<GrantAndDenial> grantsAndDenials = grantsAndDenialsComposite.getGrantsAndDenials();
-            returnUserPermission = new UserPermission(precedence, grantsAndDenials, protectedItems);
+            returnUserPermission = new UserPermission( precedence, grantsAndDenials, protectedItems );
             super.okPressed();
         }
         catch ( Exception e )
@@ -128,29 +121,46 @@
         Composite spinnerComposite = new Composite( composite, SWT.NONE );
         spinnerComposite.setLayout( new GridLayout( 2, false ) );
         spinnerComposite.setLayoutData( new GridData() );
-        precedenceLabel = new Label( spinnerComposite, SWT.NONE );
-        precedenceLabel.setText( "Precedence:" );
+        precedenceCheckbox = new Button( spinnerComposite, SWT.CHECK );
+        precedenceCheckbox.setText( "Precedence:" );
+        precedenceCheckbox.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                precedenceSpinner.setEnabled( precedenceCheckbox.getSelection() );
+            }
+        } );
         precedenceSpinner = new Spinner( spinnerComposite, SWT.BORDER );
-        precedenceSpinner.setValues( 0, 0, 255, 0, 1, 10 );
+        precedenceSpinner.setMinimum( 0 );
+        precedenceSpinner.setMaximum( 255 );
+        precedenceSpinner.setDigits( 0 );
+        precedenceSpinner.setIncrement( 1 );
+        precedenceSpinner.setPageIncrement( 10 );
+        precedenceSpinner.setSelection( 0 );
+        precedenceSpinner.setEnabled( false );
         GridData precedenceGridData = new GridData();
         precedenceGridData.grabExcessHorizontalSpace = true;
         precedenceGridData.verticalAlignment = GridData.CENTER;
         precedenceGridData.horizontalAlignment = GridData.BEGINNING;
         precedenceGridData.widthHint = 3 * 12;
         precedenceSpinner.setLayoutData( precedenceGridData );
-        
+
         protectedItemsComposite = new ACIItemProtectedItemsComposite( composite, SWT.NONE );
-        
+
         grantsAndDenialsComposite = new ACIItemGrantsAndDenialsComposite( composite, SWT.NONE );
 
-        
-        if(initialUserPermission != null)
+        if ( initialUserPermission != null )
         {
-            precedenceSpinner.setSelection( initialUserPermission.getPrecedence() );
+            if ( initialUserPermission.getPrecedence() > -1 )
+            {
+                precedenceCheckbox.setSelection( true );
+                precedenceSpinner.setEnabled( true );
+                precedenceSpinner.setSelection( initialUserPermission.getPrecedence() );
+            }
             protectedItemsComposite.setProtectedItems( initialUserPermission.getProtectedItems() );
             grantsAndDenialsComposite.setGrantsAndDenials( initialUserPermission.getGrantsAndDenials() );
         }
-        
+
         applyDialogFont( composite );
         return composite;
     }

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGeneralComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGeneralComposite.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGeneralComposite.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGeneralComposite.java Thu Dec 28 01:38:47 2006
@@ -28,6 +28,7 @@
 import org.eclipse.jface.viewers.ComboViewer;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
@@ -171,7 +172,12 @@
         precedenceLabel = new Label( composite, SWT.NONE );
         precedenceLabel.setText( "Precedence:" );
         precedenceSpinner = new Spinner( composite, SWT.BORDER );
-        precedenceSpinner.setValues( 0, 0, 255, 0, 1, 10 );
+        precedenceSpinner.setMinimum( 0 );
+        precedenceSpinner.setMaximum( 255 );
+        precedenceSpinner.setDigits( 0 );
+        precedenceSpinner.setIncrement( 1 );
+        precedenceSpinner.setPageIncrement( 10 );
+        precedenceSpinner.setSelection( 0 );
         precedenceSpinner.setLayoutData( precedenceGridData );
         precedenceSpinner.addModifyListener( this );
 
@@ -188,6 +194,8 @@
         authenticationLevelComboViewer.setLabelProvider( new LabelProvider() );
         authenticationLevelComboViewer.setInput( authenticationLevels );
         authenticationLevelCombo.addModifyListener( this );
+        authenticationLevelComboViewer.setSelection( new StructuredSelection( AuthenticationLevel.NONE ) );
+        
 
         userOrItemFirstLabel = new Label( composite, SWT.NONE );
         userOrItemFirstLabel.setText( "User or Item first:" );

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGrantsAndDenialsComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGrantsAndDenialsComposite.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGrantsAndDenialsComposite.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemGrantsAndDenialsComposite.java Thu Dec 28 01:38:47 2006
@@ -23,6 +23,8 @@
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
 
 import org.apache.directory.ldapstudio.aciitemeditor.Activator;
 import org.apache.directory.shared.ldap.aci.GrantAndDenial;
@@ -31,9 +33,12 @@
 import org.eclipse.jface.viewers.CheckboxCellEditor;
 import org.eclipse.jface.viewers.ICellModifier;
 import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
@@ -42,108 +47,119 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Item;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
 
 
+/**
+ * This composite contains GUI elements to edit ACI item grants and denials.
+
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
 public class ACIItemGrantsAndDenialsComposite extends Composite
 {
+    /** The inner composite for all the content */
+    private Composite composite = null;
+
+    /** The description label */
+    private Label label = null;
+
+    /** The tree control for the tree viewer */
+    private Tree tree = null;
+
+    /** The tree viewer containing all grants and denials */
+    private TreeViewer treeViewer = null;
+
+    /** The composite containing the buttons */
+    private Composite buttonComposite = null;
+
+    /** The grant all button */
+    private Button grantAllButton = null;
+
+    /** The deny all button */
+    private Button denyAllButton = null;
+
+    /** The deselect all button */
+    private Button deselectAllButton = null;
+
+    /** The undo button */
+    private Button undoButton = null;
+
+    /** The redo button */
+    private Button redoButton = null;
+
+    /** Colum 1 */
+    private static String PERMISSION = "Right";
+
+    /** Colum2 */
+    private static String STATE = "Grant/Deny";
+
+    /** The colums */
+    private static String[] COLUMNS = new String[]
+        { PERMISSION, STATE };
+
+    /** The undo/redo stack size */
+    private static final int MAX_STACK_SIZE = 25;
+
+    private GrantAndDenialCategory[] grantAndDenialCategories = new GrantAndDenialCategory[]
+        {
+            new GrantAndDenialCategory( "Read Rights", true, new GrantAndDenialWrapper[]
+                { new GrantAndDenialWrapper( GrantAndDenial.GRANT_BROWSE, GrantAndDenial.DENY_BROWSE ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_READ, GrantAndDenial.DENY_READ ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_COMPARE, GrantAndDenial.DENY_COMPARE ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_FILTER_MATCH, GrantAndDenial.DENY_FILTER_MATCH ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_RETURN_DN, GrantAndDenial.DENY_RETURN_DN ) } ),
+            new GrantAndDenialCategory( "Modification Rights", true, new GrantAndDenialWrapper[]
+                { new GrantAndDenialWrapper( GrantAndDenial.GRANT_ADD, GrantAndDenial.DENY_ADD ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_MODIFY, GrantAndDenial.DENY_MODIFY ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_REMOVE, GrantAndDenial.DENY_REMOVE ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_RENAME, GrantAndDenial.DENY_RENAME ) } ),
+            new GrantAndDenialCategory( "Advanced Rights", false, new GrantAndDenialWrapper[]
+                {
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_EXPORT, GrantAndDenial.DENY_EXPORT ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_IMPORT, GrantAndDenial.DENY_IMPORT ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_INVOKE, GrantAndDenial.DENY_INVOKE ),
+                    new GrantAndDenialWrapper( GrantAndDenial.GRANT_DISCLOSE_ON_ERROR,
+                        GrantAndDenial.DENY_DISCLOSE_ON_ERROR ) } ) };
+
+    private class GrantAndDenialCategory
+    {
+        private String name;
+        private boolean expanded;
+        private GrantAndDenialWrapper[] grantAndDenialWrappers;
+
+
+        public GrantAndDenialCategory( String name, boolean expanded, GrantAndDenialWrapper[] grantAndDenialWrappers )
+        {
+            super();
+            this.name = name;
+            this.expanded = expanded;
+            this.grantAndDenialWrappers = grantAndDenialWrappers;
+        }
+    }
 
-    private static String PERMISSION = "Permission";
-    private static String GRANT = "Grant";
-    private static String DENY = "Deny";
-    private static String[] COLUMNS = new String[] { PERMISSION, GRANT, DENY };
-    
-    
-    private GrantAndDenialWrapper[] grantAndDenialWrappers = new GrantAndDenialWrapper[]
-                                                                    {
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_ADD, GrantAndDenial.DENY_ADD),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_DISCLOSE_ON_ERROR, GrantAndDenial.DENY_DISCLOSE_ON_ERROR),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_READ, GrantAndDenial.DENY_READ),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_REMOVE, GrantAndDenial.DENY_REMOVE),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_BROWSE, GrantAndDenial.DENY_BROWSE),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_EXPORT, GrantAndDenial.DENY_EXPORT),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_IMPORT, GrantAndDenial.DENY_IMPORT),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_MODIFY, GrantAndDenial.DENY_MODIFY),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_RENAME, GrantAndDenial.DENY_RENAME),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_RETURN_DN, GrantAndDenial.DENY_RETURN_DN),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_COMPARE, GrantAndDenial.DENY_COMPARE),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_FILTER_MATCH, GrantAndDenial.DENY_FILTER_MATCH),
-        new GrantAndDenialWrapper(GrantAndDenial.GRANT_INVOKE, GrantAndDenial.DENY_INVOKE),
-//        new GrantAndDenialWrapper(MicroOperation.ADD),
-//        new GrantAndDenialWrapper(MicroOperation.DISCLOSE_ON_ERROR),
-//        new GrantAndDenialWrapper(MicroOperation.READ),
-//        new GrantAndDenialWrapper(MicroOperation.REMOVE),
-//        new GrantAndDenialWrapper(MicroOperation.BROWSE),
-//        new GrantAndDenialWrapper(MicroOperation.EXPORT),
-//        new GrantAndDenialWrapper(MicroOperation.IMPORT),
-//        new GrantAndDenialWrapper(MicroOperation.MODIFY),
-//        new GrantAndDenialWrapper(MicroOperation.RENAME),
-//        new GrantAndDenialWrapper(MicroOperation.RETURN_DN),
-//        new GrantAndDenialWrapper(MicroOperation.COMPARE),
-//        new GrantAndDenialWrapper(MicroOperation.FILTER_MATCH),
-//        new GrantAndDenialWrapper(MicroOperation.INVOKE)
-                                                                    };
-    
-//    private enum State {
-//        UNSET,
-//        GRANT,
-//        DENY
-//    }
-    
     private class GrantAndDenialWrapper
     {
-        private static final String DUMMY = 
-            "{ identificationTag \"id1\", precedence 1, authenticationLevel simple, "
-            + "itemOrUserFirst itemFirst: { protectedItems  { entry }, "
-            + "itemPermissions { { userClasses { allUsers }, grantsAndDenials { #value# } } }"
-            + " } }";
-        
         private GrantAndDenial grant;
         private GrantAndDenial deny;
         private GrantAndDenial activeGrantAndDenial;
+
+        private List<GrantAndDenial> undoStack;
+        private List<GrantAndDenial> redoStack;
+
         GrantAndDenialWrapper( GrantAndDenial grant, GrantAndDenial deny )
         {
             this.grant = grant;
             this.deny = deny;
             this.activeGrantAndDenial = null;
+            undoStack = new LinkedList<GrantAndDenial>();
+            redoStack = new LinkedList<GrantAndDenial>();
         }
-        
-//        private MicroOperation microOperation;
-//        private State state; 
-//        public GrantAndDenialWrapper( MicroOperation microOperation )
-//        {
-//            this.microOperation = microOperation;
-//            this.state = State.UNSET;
-//        }
-//        public GrantAndDenial getGrantAndDenial() throws ParseException
-//        {
-//            String value = "";
-//            if(state == State.GRANT) value += "grant";
-//            if(state == State.DENY) value += "deny";
-//            value += microOperation.getName();
-//                
-//                
-//            String spec = DUMMY;
-//            spec = spec.replaceAll( "#value#", value );
-//            ACIItemParser parser = new ACIItemParser(null);
-//            ItemFirstACIItem aci = ( ItemFirstACIItem ) parser.parse( spec );
-//            ItemPermission itemPermission = ( ItemPermission ) aci.getItemPermissions().iterator().next();
-//            GrantAndDenial grantAndDenial = ( GrantAndDenial ) itemPermission.getGrantsAndDenials().iterator().next();
-//            return grantAndDenial;
-//        }
     }
-    
-    
-    private Composite composite = null;
-    private Label label = null;
-    private Table table = null;
-    private TableViewer tableViewer = null;
-    private Composite buttonComposite = null;
-    private Button grantAllButton = null;
-    private Button denyAllButton = null;
-    private Button deselectAllButton = null;
-    
+
+
     public ACIItemGrantsAndDenialsComposite( Composite parent, int style )
     {
         super( parent, style );
@@ -161,7 +177,7 @@
         layout.marginHeight = 0;
         layout.marginWidth = 0;
         setLayout( layout );
-        
+
         createComposite();
 
         GridData layoutData = new GridData();
@@ -183,84 +199,87 @@
         labelGridData.verticalAlignment = GridData.CENTER;
         labelGridData.grabExcessHorizontalSpace = true;
         labelGridData.horizontalAlignment = GridData.FILL;
-        
+
         GridLayout gridLayout = new GridLayout();
         gridLayout.makeColumnsEqualWidth = false;
         gridLayout.numColumns = 2;
-        
+
         GridData gridData = new GridData();
         gridData.horizontalAlignment = GridData.FILL;
         gridData.grabExcessHorizontalSpace = true;
         gridData.verticalAlignment = GridData.BEGINNING;
-        
+
         composite = new Composite( this, SWT.NONE );
-        composite.setLayoutData(gridData);
-        composite.setLayout(gridLayout);
+        composite.setLayoutData( gridData );
+        composite.setLayout( gridLayout );
+
+        label = new Label( composite, SWT.NONE );
+        label.setText( "Grants and Denials:" );
+        label.setLayoutData( labelGridData );
+
+        createTree();
 
-        label = new Label(composite, SWT.NONE);
-        label.setText("Grants and Denials:");
-        label.setLayoutData(labelGridData);
-        
-        createTable();
-        
         createButtonComposite();
-        
     }
-    
+
+
     /**
-     * This method initializes table
+     * This method initializes tree
      *
      */
-    private void createTable()
+    private void createTree()
     {
         GridData tableGridData = new GridData();
         tableGridData.grabExcessHorizontalSpace = true;
         tableGridData.verticalAlignment = GridData.FILL;
         tableGridData.horizontalAlignment = GridData.FILL;
         //tableGridData.heightHint = 100;
-        
-        table = new Table(composite, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION );
-        table.setHeaderVisible(true);
-        table.setLayoutData(tableGridData);
-        table.setLinesVisible(true);
-        
-        TableColumn c1 = new TableColumn(table, SWT.LEFT, 0);
+
+        tree = new Tree( composite, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION
+            | SWT.HIDE_SELECTION );
+        tree.setHeaderVisible( true );
+        tree.setLayoutData( tableGridData );
+        tree.setLinesVisible( true );
+
+        TreeColumn c1 = new TreeColumn( tree, SWT.LEFT, 0 );
         c1.setText( COLUMNS[0] );
         c1.setWidth( 160 );
-        TableColumn c2 = new TableColumn(table, SWT.CENTER, 1);
+        TreeColumn c2 = new TreeColumn( tree, SWT.CENTER, 1 );
         c2.setText( COLUMNS[1] );
         c2.setWidth( 80 );
-        TableColumn c3 = new TableColumn(table, SWT.CENTER, 2);
-        c3.setText( COLUMNS[2] );
-        c3.setWidth( 80 );
-        TableColumn c4 = new TableColumn(table, SWT.LEFT, 3);
-        c4.setText( " " );
-        c4.setWidth( 1 );
-        
-        tableViewer = new TableViewer(table);
-        tableViewer.setUseHashlookup(true);
-        
-        tableViewer.setColumnProperties( COLUMNS );
-        
+        TreeColumn c3 = new TreeColumn( tree, SWT.LEFT, 2 );
+        c3.setText( " " );
+        c3.setWidth( 1 );
+
+        treeViewer = new TreeViewer( tree );
+        treeViewer.setUseHashlookup( true );
+
+        treeViewer.setColumnProperties( COLUMNS );
+
         ICellModifier cellModifier = new GrantsAndDenialsCellModifier();
-        tableViewer.setCellModifier( cellModifier );
+        treeViewer.setCellModifier( cellModifier );
         CellEditor[] cellEditors = new CellEditor[]
-                                                  {
-            null,
-            new CheckboxCellEditor(table),
-            new CheckboxCellEditor(table),
-            null
-                                                  };
-        tableViewer.setCellEditors( cellEditors );
+            { null, new CheckboxCellEditor( tree ), null };
+        treeViewer.setCellEditors( cellEditors );
         //tableViewer.setSorter( new ViewerSorter() );
-        
-        tableViewer.setContentProvider( new ArrayContentProvider() );
-        tableViewer.setLabelProvider( new GrantsAndDenialsLabelProvider() );
-        tableViewer.setInput( grantAndDenialWrappers );
 
-        
+        treeViewer.setContentProvider( new GrantsAndDenialsContentProvider() );
+        treeViewer.setLabelProvider( new GrantsAndDenialsLabelProvider() );
+        treeViewer.setInput( grantAndDenialCategories );
+
+        // set expanded state
+        List<GrantAndDenialCategory> expandedList = new ArrayList<GrantAndDenialCategory>();
+        for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
+        {
+            if ( grantAndDenialCategory.expanded )
+            {
+                expandedList.add( grantAndDenialCategory );
+            }
+        }
+        treeViewer.setExpandedElements( expandedList.toArray() );
     }
 
+
     /**
      * This method initializes buttonComposite  
      *
@@ -271,17 +290,27 @@
         deselectAllButtonGridData.horizontalAlignment = GridData.FILL;
         deselectAllButtonGridData.grabExcessHorizontalSpace = false;
         deselectAllButtonGridData.verticalAlignment = GridData.BEGINNING;
-        
+
         GridData denyAllButtonGridData = new GridData();
         denyAllButtonGridData.horizontalAlignment = GridData.FILL;
         denyAllButtonGridData.grabExcessHorizontalSpace = false;
         denyAllButtonGridData.verticalAlignment = GridData.BEGINNING;
-        
+
         GridData grantAllButtonGridData = new GridData();
         grantAllButtonGridData.horizontalAlignment = GridData.FILL;
         grantAllButtonGridData.grabExcessHorizontalSpace = false;
         grantAllButtonGridData.verticalAlignment = GridData.BEGINNING;
-        
+
+        GridData undoButtonGridData = new GridData();
+        undoButtonGridData.horizontalAlignment = GridData.FILL;
+        undoButtonGridData.grabExcessHorizontalSpace = false;
+        undoButtonGridData.verticalAlignment = GridData.BEGINNING;
+
+        GridData redoButtonGridData = new GridData();
+        redoButtonGridData.horizontalAlignment = GridData.FILL;
+        redoButtonGridData.grabExcessHorizontalSpace = false;
+        redoButtonGridData.verticalAlignment = GridData.BEGINNING;
+
         GridLayout gridLayout = new GridLayout();
         gridLayout.marginWidth = 0;
         gridLayout.marginHeight = 0;
@@ -290,91 +319,195 @@
         gridData.grabExcessHorizontalSpace = false;
         gridData.grabExcessVerticalSpace = false;
         gridData.verticalAlignment = GridData.FILL;
-        
+
         buttonComposite = new Composite( composite, SWT.NONE );
-        buttonComposite.setLayoutData(gridData);
+        buttonComposite.setLayoutData( gridData );
         buttonComposite.setLayout( gridLayout );
-        
-        grantAllButton = new Button(buttonComposite, SWT.NONE);
-        grantAllButton.setText("Grant All");
-        grantAllButton.setLayoutData(grantAllButtonGridData);
-        
-        denyAllButton = new Button(buttonComposite, SWT.NONE);
-        denyAllButton.setText("Deny All");
-        denyAllButton.setLayoutData(denyAllButtonGridData);
-        
-        deselectAllButton = new Button(buttonComposite, SWT.NONE);
-        deselectAllButton.setText("Deselect All");
-        deselectAllButton.setLayoutData(deselectAllButtonGridData);
-        
+
+        grantAllButton = new Button( buttonComposite, SWT.NONE );
+        grantAllButton.setText( "Grant All" );
+        grantAllButton.setLayoutData( grantAllButtonGridData );
+        grantAllButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                backup();
+                for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
+                {
+                    for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.grant;
+                    }
+                }
+                treeViewer.refresh();
+            }
+        } );
+
+        denyAllButton = new Button( buttonComposite, SWT.NONE );
+        denyAllButton.setText( "Deny All" );
+        denyAllButton.setLayoutData( denyAllButtonGridData );
+        denyAllButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                backup();
+                for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
+                {
+                    for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.deny;
+                    }
+                }
+                treeViewer.refresh();
+            }
+        } );
+
+        deselectAllButton = new Button( buttonComposite, SWT.NONE );
+        deselectAllButton.setText( "Deselect All" );
+        deselectAllButton.setLayoutData( deselectAllButtonGridData );
+        deselectAllButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                backup();
+                for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
+                {
+                    for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = null;
+                    }
+                }
+                treeViewer.refresh();
+            }
+        } );
+
+        undoButton = new Button( buttonComposite, SWT.NONE );
+        undoButton.setText( "Undo" );
+        undoButton.setLayoutData( undoButtonGridData );
+        undoButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                undo();
+                treeViewer.refresh();
+            }
+        } );
+        undoButton.setEnabled( false );
+
+        redoButton = new Button( buttonComposite, SWT.NONE );
+        redoButton.setText( "Redo" );
+        redoButton.setLayoutData( redoButtonGridData );
+        redoButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                redo();
+                treeViewer.refresh();
+            }
+        } );
+        redoButton.setEnabled( false );
+
     }
-    
+
     private class GrantsAndDenialsCellModifier implements ICellModifier
     {
 
         public boolean canModify( Object element, String property )
         {
             //System.out.println("canModify() " + element + " " + property);
-            
-            if(element instanceof GrantAndDenialWrapper)
+
+            if ( element instanceof GrantAndDenialWrapper )
             {
-                return property.equals( GRANT ) || property.equals( DENY ) ;
+                return property.equals( STATE );
             }
-            
+
             return false;
         }
 
+
         public Object getValue( Object element, String property )
         {
             //System.out.println("getValue() " + element + " " + property);
-            
-            if(element instanceof GrantAndDenialWrapper)
+
+            if ( element instanceof GrantAndDenialWrapper )
             {
-                GrantAndDenialWrapper i = (GrantAndDenialWrapper) element;
-                if( property.equals( GRANT ) ) 
+                if ( property.equals( STATE ) )
                 {
-                    return new Boolean( i.activeGrantAndDenial == i.grant );
-                }
-                else if( property.equals( DENY ) ) 
-                {
-                    return new Boolean( i.activeGrantAndDenial == i.deny );
+                    return new Boolean( true );
                 }
             }
-                
+
             return null;
         }
 
+
         public void modify( Object element, String property, Object value )
         {
             if ( element != null && element instanceof Item )
             {
                 element = ( ( Item ) element ).getData();
             }
-            
+
             //System.out.println("modify() " + element + " " + property + " " + value);
-            
-            if(element instanceof GrantAndDenialWrapper)
+
+            if ( element instanceof GrantAndDenialWrapper )
             {
-                GrantAndDenialWrapper i = (GrantAndDenialWrapper) element;
-                Boolean b = (Boolean) value;
-                if( property.equals( GRANT ) ) 
-                {
-                    i.activeGrantAndDenial = b ? i.grant : null;
-                }
-                else if( property.equals( DENY ) ) 
+                GrantAndDenialWrapper grantAndDenialWrapper = ( GrantAndDenialWrapper ) element;
+
+                if ( property.equals( STATE ) )
                 {
-                    i.activeGrantAndDenial = b ? i.deny : null;
+                    backup();
+                    if ( grantAndDenialWrapper.activeGrantAndDenial == null )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.grant;
+                    }
+                    else if ( grantAndDenialWrapper.activeGrantAndDenial == grantAndDenialWrapper.grant )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.deny;
+                    }
+                    else if ( grantAndDenialWrapper.activeGrantAndDenial == grantAndDenialWrapper.deny )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = null;
+                    }
                 }
-                
+
                 //System.out.println("modify() " + property + " " + value + " = " + i.state);
-                
+
             }
-            
-            tableViewer.refresh();
+
+            treeViewer.refresh();
         }
-        
+
     }
-    
+
+    private class GrantsAndDenialsContentProvider extends ArrayContentProvider implements ITreeContentProvider
+    {
+
+        public Object[] getChildren( Object parentElement )
+        {
+            if ( parentElement instanceof GrantAndDenialCategory )
+            {
+                GrantAndDenialCategory cat = ( GrantAndDenialCategory ) parentElement;
+                return cat.grantAndDenialWrappers;
+            }
+
+            return null;
+        }
+
+
+        public Object getParent( Object element )
+        {
+            return null;
+        }
+
+
+        public boolean hasChildren( Object element )
+        {
+            return ( element instanceof GrantAndDenialCategory );
+        }
+
+    }
+
     private class GrantsAndDenialsLabelProvider extends LabelProvider implements ITableLabelProvider
     {
 
@@ -382,39 +515,57 @@
         {
             if ( element instanceof GrantAndDenialWrapper )
             {
-                GrantAndDenialWrapper i = ( GrantAndDenialWrapper ) element;
+                GrantAndDenialWrapper grantAndDenialWrapper = ( GrantAndDenialWrapper ) element;
                 switch ( columnIndex )
                 {
                     case 0:
                         return null;
                     case 1:
-                        return i.activeGrantAndDenial == i.grant ? 
-                            Activator.getDefault().getImage( "icons/checkbox_checked.gif" )
-                            : Activator.getDefault().getImage( "icons/checkbox_unchecked.gif" );
+                        if ( grantAndDenialWrapper.activeGrantAndDenial == null )
+                        {
+                            return Activator.getDefault().getImage( "icons/checkbox_unchecked.gif" );
+                        }
+                        else if ( grantAndDenialWrapper.activeGrantAndDenial == grantAndDenialWrapper.grant )
+                        {
+                            return Activator.getDefault().getImage( "icons/checkbox_grant.gif" );
+                        }
+                        else if ( grantAndDenialWrapper.activeGrantAndDenial == grantAndDenialWrapper.deny )
+                        {
+                            return Activator.getDefault().getImage( "icons/checkbox_deny.gif" );
+                        }
                     case 2:
-                        return i.activeGrantAndDenial == i.deny ? Activator.getDefault().getImage( "icons/checkbox_checked.gif" )
-                            : Activator.getDefault().getImage( "icons/checkbox_unchecked.gif" );
+                        return null;
                 }
             }
             return null;
         }
 
+
         public String getColumnText( Object element, int columnIndex )
         {
-            if(element instanceof GrantAndDenialWrapper)
+            if ( element instanceof GrantAndDenialCategory )
+            {
+                if ( columnIndex == 0 )
+                {
+                    GrantAndDenialCategory cat = ( GrantAndDenialCategory ) element;
+                    return cat.name;
+                }
+            }
+            else if ( element instanceof GrantAndDenialWrapper )
             {
-                if(columnIndex == 0)
+                if ( columnIndex == 0 )
                 {
-                    GrantAndDenialWrapper i = (GrantAndDenialWrapper) element;
-                    return i.grant.getMicroOperation().getName();
+                    GrantAndDenialWrapper wrapper = ( GrantAndDenialWrapper ) element;
+                    return wrapper.grant.getMicroOperation().getName();
                 }
             }
-            
+
             return "";
         }
+
     }
-    
-    
+
+
     /**
      * Sets the grants and denials. 
      *
@@ -424,24 +575,26 @@
     {
         for ( GrantAndDenial grantAndDenial : grantsAndDenials )
         {
-            for(int i=0; i<grantAndDenialWrappers.length; i++) 
+            for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
             {
-                GrantAndDenialWrapper grantAndDenialWrapper = grantAndDenialWrappers[i];
-                
-                if( grantAndDenialWrapper.grant == grantAndDenial )
+                for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
                 {
-                    grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.grant;
-                }
-                else if( grantAndDenialWrapper.deny == grantAndDenial )
-                {
-                    grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.deny;
+                    if ( grantAndDenialWrapper.grant == grantAndDenial )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.grant;
+                    }
+                    else if ( grantAndDenialWrapper.deny == grantAndDenial )
+                    {
+                        grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.deny;
+                    }
                 }
             }
         }
-        
-        tableViewer.refresh();
+
+        treeViewer.refresh();
     }
 
+
     /**
      * Returns the grants and denials as selected by the user.
      *
@@ -452,17 +605,76 @@
     {
         Collection<GrantAndDenial> grantsAndDenials = new ArrayList<GrantAndDenial>();
 
-        for(int i=0; i<grantAndDenialWrappers.length; i++) 
+        for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
         {
-            GrantAndDenialWrapper grantAndDenialWrapper = grantAndDenialWrappers[i];
-            if( grantAndDenialWrapper.activeGrantAndDenial != null )
+            for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
             {
-                grantsAndDenials.add( grantAndDenialWrapper.activeGrantAndDenial );
+                if ( grantAndDenialWrapper.activeGrantAndDenial != null )
+                {
+                    grantsAndDenials.add( grantAndDenialWrapper.activeGrantAndDenial );
+                }
             }
         }
 
         return grantsAndDenials;
+    }
+
 
+    private void undo()
+    {
+        for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
+        {
+            for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
+            {
+                if ( grantAndDenialWrapper.undoStack.size() > 0 )
+                {
+                    grantAndDenialWrapper.redoStack.add( 0, grantAndDenialWrapper.activeGrantAndDenial );
+                    grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.undoStack.remove( 0 );
+                }
+
+                undoButton.setEnabled( !grantAndDenialWrapper.undoStack.isEmpty() );
+                redoButton.setEnabled( !grantAndDenialWrapper.redoStack.isEmpty() );
+            }
+        }
     }
-    
+
+
+    private void redo()
+    {
+        for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
+        {
+            for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
+            {
+                if ( grantAndDenialWrapper.redoStack.size() > 0 )
+                {
+                    grantAndDenialWrapper.undoStack.add( 0, grantAndDenialWrapper.activeGrantAndDenial );
+                    grantAndDenialWrapper.activeGrantAndDenial = grantAndDenialWrapper.redoStack.remove( 0 );
+                }
+
+                undoButton.setEnabled( !grantAndDenialWrapper.undoStack.isEmpty() );
+                redoButton.setEnabled( !grantAndDenialWrapper.redoStack.isEmpty() );
+            }
+        }
+    }
+
+
+    private void backup()
+    {
+        for ( GrantAndDenialCategory grantAndDenialCategory : grantAndDenialCategories )
+        {
+            for ( GrantAndDenialWrapper grantAndDenialWrapper : grantAndDenialCategory.grantAndDenialWrappers )
+            {
+                if ( grantAndDenialWrapper.undoStack.size() == MAX_STACK_SIZE )
+                {
+                    grantAndDenialWrapper.undoStack.remove( grantAndDenialWrapper.undoStack.size() - 1 );
+                }
+                grantAndDenialWrapper.undoStack.add( 0, grantAndDenialWrapper.activeGrantAndDenial );
+                grantAndDenialWrapper.redoStack.clear();
+
+                undoButton.setEnabled( !grantAndDenialWrapper.undoStack.isEmpty() );
+                redoButton.setEnabled( !grantAndDenialWrapper.redoStack.isEmpty() );
+            }
+        }
+    }
+
 }

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java Thu Dec 28 01:38:47 2006
@@ -23,11 +23,14 @@
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 
-import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
 import org.apache.directory.ldapstudio.aciitemeditor.dialogs.ItemPermissionDialog;
+import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
+import org.apache.directory.shared.ldap.aci.GrantAndDenial;
 import org.apache.directory.shared.ldap.aci.ItemPermission;
+import org.apache.directory.shared.ldap.aci.UserClass;
 import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
@@ -112,16 +115,48 @@
             }
             else 
             {
-                String s = itemPermission.toString();
+                StringBuffer buffer = new StringBuffer();
+                if(itemPermission.getPrecedence() > -1)
+                {
+                    buffer.append( '(' );
+                    buffer.append( itemPermission.getPrecedence() );
+                    buffer.append( ')' );
+                    buffer.append( ' ' );
+                }
+                for(Iterator<UserClass> it = ((Collection<UserClass>)itemPermission.getUserClasses()).iterator(); it.hasNext(); )
+                {
+                    UserClass uc = it.next();
+                    String s = ACIItemUserClassesComposite.UserClassWrapper.classToDisplayMap.get( uc.getClass() );
+                    buffer.append( s );
+                    
+                    if(it.hasNext())
+                    {
+                        buffer.append( ',' );
+                    }
+                }
+                buffer.append( ": " );
+                for(Iterator<GrantAndDenial> it = ((Collection<GrantAndDenial>)itemPermission.getGrantsAndDenials()).iterator(); it.hasNext(); )
+                {
+                    GrantAndDenial gd = it.next();
+                    String s = (gd.isGrant() ? "+" : "-") + gd.getMicroOperation().getName();
+                    buffer.append( s );
+                    
+                    if(it.hasNext())
+                    {
+                        buffer.append( ',' );
+                    }
+                }
+                
+                
+                String s = buffer.toString();
                 s = s.replace( '\r', ' ' );
                 s = s.replace( '\n', ' ' );
-                s = ": " + s;
-                if(s.length() > 40)
+                if(s.length() > 50)
                 {
                     String temp = s;
-                    s = temp.substring( 0, 20 );
+                    s = temp.substring( 0, 25 );
                     s = s + "...";
-                    s = s + temp.substring( temp.length() - 20, temp.length() );
+                    s = s + temp.substring( temp.length() - 25, temp.length() );
                 }
                 return s;
             }

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java Thu Dec 28 01:38:47 2006
@@ -24,7 +24,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
 import org.apache.directory.shared.ldap.aci.ACIItemParser;
@@ -111,8 +113,41 @@
      * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
      * @version $Rev$, $Date$
      */
-    private class ProtectedItemWrapper
+    public static class ProtectedItemWrapper
     {
+        public static final Map<Class, String> classToItemMap = new HashMap<Class, String>();
+        static
+        {
+            classToItemMap.put( ProtectedItem.Entry.class, "entry" );
+            classToItemMap.put( ProtectedItem.AllUserAttributeTypes.class, "allUserAttributeTypes" );
+            classToItemMap.put( ProtectedItem.AttributeType.class, "AttributeType" );
+            classToItemMap.put( ProtectedItem.AllAttributeValues.class, "allAttributeValues" );
+            classToItemMap.put( ProtectedItem.AllUserAttributeTypesAndValues.class, "allUserAttributeTypesAndValues" );
+            classToItemMap.put( ProtectedItem.AttributeValue.class, "attributeValue" );
+            classToItemMap.put( ProtectedItem.SelfValue.class, "selfValue" );
+            classToItemMap.put( ProtectedItem.RangeOfValues.class, "rangeOfValues" );
+            classToItemMap.put( ProtectedItem.MaxValueCount.class, "maxValueCount" );
+            classToItemMap.put( ProtectedItem.MaxImmSub.class, "maxImmSub" );
+            classToItemMap.put( ProtectedItem.RestrictedBy.class, "restrictedBy" );
+            classToItemMap.put( ProtectedItem.Classes.class, "classes" );
+        }
+        public static final Map<Class, String> classToDisplayMap = new HashMap<Class, String>();
+        static
+        {
+            classToDisplayMap.put( ProtectedItem.Entry.class, "Entry" );
+            classToDisplayMap.put( ProtectedItem.AllUserAttributeTypes.class, "All User Attribute Types" );
+            classToDisplayMap.put( ProtectedItem.AttributeType.class, "Attribute Type" );
+            classToDisplayMap.put( ProtectedItem.AllAttributeValues.class, "All Attribute Values" );
+            classToDisplayMap.put( ProtectedItem.AllUserAttributeTypesAndValues.class, "All User Attribute Types and Values" );
+            classToDisplayMap.put( ProtectedItem.AttributeValue.class, "Attribute Value" );
+            classToDisplayMap.put( ProtectedItem.SelfValue.class, "Self Value" );
+            classToDisplayMap.put( ProtectedItem.RangeOfValues.class, "Range of Values" );
+            classToDisplayMap.put( ProtectedItem.MaxValueCount.class, "Max. Value Count" );
+            classToDisplayMap.put( ProtectedItem.MaxImmSub.class, "Max. Number of immediate Subordinates" );
+            classToDisplayMap.put( ProtectedItem.RestrictedBy.class, "Restricted by" );
+            classToDisplayMap.put( ProtectedItem.Classes.class, "Classes" );
+        }
+        
         private static final String DUMMY = 
             "{ identificationTag \"id1\", precedence 1, authenticationLevel simple, "
             + "itemOrUserFirst itemFirst: { protectedItems  { #item# #value# }, "
@@ -146,57 +181,7 @@
          */
         private ProtectedItem getProtectedItem() throws ParseException
         {
-            String type = "";
-            
-            if(protectedItemClass == ProtectedItem.Entry.class) 
-            {
-                type = "entry";
-            }
-            else if(protectedItemClass == ProtectedItem.AllUserAttributeTypes.class) 
-            {
-                type = "allUserAttributeTypes";
-            }
-            else if(protectedItemClass == ProtectedItem.AttributeType.class) 
-            {
-                type = "attributeType";
-            }
-            else if(protectedItemClass == ProtectedItem.AllAttributeValues.class) 
-            {
-                type = "allAttributeValues";
-            }
-            else if(protectedItemClass == ProtectedItem.AllUserAttributeTypesAndValues.class) 
-            {
-                type = "allUserAttributeTypesAndValues";
-            }
-            else if(protectedItemClass == ProtectedItem.AttributeValue.class) 
-            {
-                type = "attributeValue";
-            }
-            else if(protectedItemClass == ProtectedItem.SelfValue.class) 
-            {
-                type = "selfValue";
-            }
-            else if(protectedItemClass == ProtectedItem.RangeOfValues.class) 
-            {
-                type = "rangeOfValues";
-            }
-            else if(protectedItemClass == ProtectedItem.MaxValueCount.class) 
-            {
-                type = "maxValueCount";
-            }
-            else if(protectedItemClass == ProtectedItem.MaxImmSub.class) 
-            {
-                type = "maxImmSub";
-            }
-            else if(protectedItemClass == ProtectedItem.RestrictedBy.class) 
-            {
-                type = "restrictedBy";
-            }
-            else if(protectedItemClass == ProtectedItem.Classes.class) 
-            {
-                type = "classes";
-            }
-
+            String type = classToItemMap.get( protectedItemClass );
             String spec = DUMMY;
             spec = spec.replaceAll( "#item#", type );
             spec = spec.replaceAll( "#value#", protectedItemValue );
@@ -208,70 +193,26 @@
         
         public String toString()
         {
-            if(protectedItemClass == ProtectedItem.Entry.class) 
-            {
-                return "Entry";
-            }
-            else if(protectedItemClass == ProtectedItem.AllUserAttributeTypes.class) 
-            {
-                return "All User Attribute Types";
-            }
-            else if(protectedItemClass == ProtectedItem.AttributeType.class) 
-            {
-                return "Attribute Type" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.AllAttributeValues.class) 
-            {
-                return "All Attribute Values" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.AllUserAttributeTypesAndValues.class) 
-            {
-                return "All User Attribute Types and Values";
-            }
-            else if(protectedItemClass == ProtectedItem.AttributeValue.class) 
-            {
-                return "Attribute Value" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.SelfValue.class) 
-            {
-                return "Self Value" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.RangeOfValues.class) 
-            {
-                return "Range of Values" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.MaxValueCount.class) 
-            {
-                return "Max. Value Count" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.MaxImmSub.class) 
-            {
-                return "Max. Number of Immediate Subordinates" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.RestrictedBy.class) 
-            {
-                return "Restricted by" + getProtectedItemValue();
-            }
-            else if(protectedItemClass == ProtectedItem.Classes.class) 
-            {
-                return "Classes" + getProtectedItemValue();
-            }
-            
-            return "<UNKNOWN>";
+            String string = classToDisplayMap.get( protectedItemClass );
+            if(string == null) string = "<UNKNOWN>";
+            return string + getProtectedItemValue();
         }
         
         private String getProtectedItemValue()
         {
             String s = protectedItemValue;
-            s = s.replace( '\r', ' ' );
-            s = s.replace( '\n', ' ' );
-            s = ": " + s;
-            if(s.length() > 40)
+            if(s.length() > 0)
             {
-                String temp = s;
-                s = temp.substring( 0, 20 );
-                s = s + "...";
-                s = s + temp.substring( temp.length() - 20, temp.length() );
+                s = s.replace( '\r', ' ' );
+                s = s.replace( '\n', ' ' );
+                s = ": " + s;
+                if(s.length() > 40)
+                {
+                    String temp = s;
+                    s = temp.substring( 0, 20 );
+                    s = s + "...";
+                    s = s + temp.substring( temp.length() - 20, temp.length() );
+                }
             }
             return s;
         }

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java Thu Dec 28 01:38:47 2006
@@ -24,7 +24,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
 import org.apache.directory.shared.ldap.aci.ACIItemParser;
@@ -99,8 +101,35 @@
         new UserClassWrapper(UserClass.Subtree.class) // subtree { { base \"ou=people\" } }
     };
     
-    private class UserClassWrapper
+    /**
+     * The UserClassWrapper is used as input for the table viewer. 
+     * The user class values are always stored as raw string value.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    public static class UserClassWrapper
     {
+        
+        public static final Map<Class, String> classToItemMap = new HashMap<Class, String>();
+        static
+        {
+            classToItemMap.put( UserClass.AllUsers.class, "allUsers" );
+            classToItemMap.put( UserClass.ThisEntry.class, "thisEntry" );
+            classToItemMap.put( UserClass.Name.class, "name" );
+            classToItemMap.put( UserClass.UserGroup.class, "userGroup" );
+            classToItemMap.put( UserClass.Subtree.class, "subtree" );
+        }
+        public static final Map<Class, String> classToDisplayMap = new HashMap<Class, String>();
+        static
+        {
+            classToDisplayMap.put( UserClass.AllUsers.class, "All Users" );
+            classToDisplayMap.put( UserClass.ThisEntry.class, "This Entry" );
+            classToDisplayMap.put( UserClass.Name.class, "Name" );
+            classToDisplayMap.put( UserClass.UserGroup.class, "User Group" );
+            classToDisplayMap.put( UserClass.Subtree.class, "Subtree" );
+        }
+        
         private static final String DUMMY = 
             "{ identificationTag \"id1\", precedence 1, authenticationLevel simple, "
             + "itemOrUserFirst userFirst: { userClasses  { #item# #value# }, "
@@ -126,29 +155,7 @@
         
         public UserClass getUserClass() throws ParseException
         {
-            String type = "";
-            
-            if(userClassClass == UserClass.AllUsers.class) 
-            {
-                type = "allUsers";
-            }
-            else if(userClassClass == UserClass.ThisEntry.class) 
-            {
-                type = "thisEntry";
-            }
-            else if(userClassClass == UserClass.Name.class) 
-            {
-                type = "name";
-            }
-            else if(userClassClass == UserClass.UserGroup.class) 
-            {
-                type = "userGroup";
-            }
-            else if(userClassClass == UserClass.Subtree.class) 
-            {
-                type = "subtree";
-            }
-              
+            String type = classToItemMap.get( userClassClass );
             String spec = DUMMY;
             spec = spec.replaceAll( "#item#", type );
             spec = spec.replaceAll( "#value#", userClassValue );
@@ -160,38 +167,15 @@
         
         public String toString()
         {
-            if(userClassClass == UserClass.AllUsers.class) 
-            {
-                return "All Users";
-            }
-            else if(userClassClass == UserClass.ThisEntry.class) 
-            {
-                return "This Entry";
-            }
-            else if(userClassClass == UserClass.Name.class) 
-            {
-                return "Name" + getUserClassValue();
-            }
-            else if(userClassClass == UserClass.UserGroup.class) 
-            {
-                return "User Group" + getUserClassValue();
-            }
-            else if(userClassClass == UserClass.Subtree.class) 
-            {
-                return "Subtree" + getUserClassValue();
-            }
-            
-            return "<UNKNOWN>";
+            String string = classToDisplayMap.get( userClassClass );
+            if(string == null) string = "<UNKNOWN>";
+            return string + getUserClassValue();
         }
         private String getUserClassValue()
         {
-            if(userClassValue == null)
-            {
-                return "";
-            }
-            else 
+            String s = userClassValue;
+            if(s.length() > 0)
             {
-                String s = userClassValue;
                 s = s.replace( '\r', ' ' );
                 s = s.replace( '\n', ' ' );
                 s = ": " + s;
@@ -202,8 +186,8 @@
                     s = s + "...";
                     s = s + temp.substring( temp.length() - 20, temp.length() );
                 }
-                return s;
             }
+            return s;
         }
     }
     

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserPermissionsComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserPermissionsComposite.java?view=diff&rev=490684&r1=490683&r2=490684
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserPermissionsComposite.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserPermissionsComposite.java Thu Dec 28 01:38:47 2006
@@ -23,10 +23,13 @@
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 
 import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
 import org.apache.directory.ldapstudio.aciitemeditor.dialogs.UserPermissionDialog;
+import org.apache.directory.shared.ldap.aci.GrantAndDenial;
+import org.apache.directory.shared.ldap.aci.ProtectedItem;
 import org.apache.directory.shared.ldap.aci.UserPermission;
 import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
@@ -112,16 +115,47 @@
             }
             else 
             {
-                String s = userPermission.toString();
+                StringBuffer buffer = new StringBuffer();
+                if(userPermission.getPrecedence() > -1)
+                {
+                    buffer.append( '(' );
+                    buffer.append( userPermission.getPrecedence() );
+                    buffer.append( ')' );
+                    buffer.append( ' ' );
+                }
+                for(Iterator<ProtectedItem> it = ((Collection<ProtectedItem>)userPermission.getProtectedItems()).iterator(); it.hasNext(); )
+                {
+                    ProtectedItem item = it.next();
+                    String s = ACIItemProtectedItemsComposite.ProtectedItemWrapper.classToDisplayMap.get( item.getClass() );
+                    buffer.append( s );
+                    
+                    if(it.hasNext())
+                    {
+                        buffer.append( ',' );
+                    }
+                }
+                buffer.append( ": " );
+                for(Iterator<GrantAndDenial> it = ((Collection<GrantAndDenial>)userPermission.getGrantsAndDenials()).iterator(); it.hasNext(); )
+                {
+                    GrantAndDenial gd = it.next();
+                    String s = (gd.isGrant() ? "+" : "-") + gd.getMicroOperation().getName();
+                    buffer.append( s );
+                    
+                    if(it.hasNext())
+                    {
+                        buffer.append( ',' );
+                    }
+                }
+                
+                String s = buffer.toString();
                 s = s.replace( '\r', ' ' );
                 s = s.replace( '\n', ' ' );
-                s = ": " + s;
-                if(s.length() > 40)
+                if(s.length() > 50)
                 {
                     String temp = s;
-                    s = temp.substring( 0, 20 );
+                    s = temp.substring( 0, 25 );
                     s = s + "...";
-                    s = s + temp.substring( temp.length() - 20, temp.length() );
+                    s = s + temp.substring( temp.length() - 25, temp.length() );
                 }
                 return s;
             }