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/30 20:19:07 UTC

svn commit: r491293 [2/3] - in /directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor: ./ META-INF/ icons/ lib/ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/directory/ldapstudio/aciitemeditor/ ...

Modified: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java?view=diff&rev=491293&r1=491291&r2=491293
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java (original)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemItemPermissionsComposite.java Sat Dec 30 11:19:04 2006
@@ -20,12 +20,12 @@
 package org.apache.directory.ldapstudio.aciitemeditor.widgets;
 
 
-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.Activator;
 import org.apache.directory.ldapstudio.aciitemeditor.dialogs.ItemPermissionDialog;
 import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
 import org.apache.directory.shared.ldap.aci.GrantAndDenial;
@@ -51,8 +51,7 @@
 
 
 /**
- * This composite contains GUI elements to edit ACI item item permissions.
-
+ * This composite contains GUI elements to add, edit and delete ACI item permissions.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
@@ -62,126 +61,141 @@
 
     /** The inner composite for all the content */
     private Composite composite = null;
-    
+
     /** The description label */
     private Label label = null;
-    
+
     /** The table control for the table viewer */
     private Table table = null;
-    
+
     /** The table viewer containing all item classes */
     private TableViewer tableViewer = null;
-    
+
     /** The composite containing the buttons */
     private Composite buttonComposite = null;
-    
+
     /** The add button */
     private Button addButton = null;
-    
+
     /** The select all button */
     private Button editButton = null;
-    
+
     /** The deselect all button */
     private Button deleteButton = null;
-    
-    /** The selected item permissions, also input of the table viewer */
-    List<ItemPermissionWrapper> itemPermissionWrappers = new ArrayList<ItemPermissionWrapper>();
-    
-    
+
+    /** The selected item permissions, input of the table viewer */
+    private List<ItemPermissionWrapper> itemPermissionWrappers = new ArrayList<ItemPermissionWrapper>();
+
+    /**
+     * ItemPermissionWrappers are used as input of the table viewer.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
     private class ItemPermissionWrapper
     {
         /** The item permission bean. */
         private ItemPermission itemPermission;
-        
+
+
         /**
          * Creates a new instance of ItemPermissionWrapper.
          *
          * @param itemClassClass
          */
-        public ItemPermissionWrapper( ItemPermission itemPermission )
+        private ItemPermissionWrapper( ItemPermission itemPermission )
         {
             this.itemPermission = itemPermission;
         }
-        
+
+
+        /**
+         * Returns a user-friedly string, displayed in the table.
+         */
         public String toString()
         {
-            return getItemPermissionValue();
-        }
-        private String getItemPermissionValue()
-        {
-            if(itemPermission == null)
+            if ( itemPermission == null )
             {
-                return "<UNKNOWN>";
+                return "<UNKNOWN>"; //$NON-NLS-1$
             }
-            else 
+            else
             {
                 StringBuffer buffer = new StringBuffer();
-                if(itemPermission.getPrecedence() > -1)
+                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(); )
+                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())
+
+                    if ( it.hasNext() )
                     {
                         buffer.append( ',' );
                     }
                 }
-                buffer.append( ": " );
-                for(Iterator<GrantAndDenial> it = ((Collection<GrantAndDenial>)itemPermission.getGrantsAndDenials()).iterator(); 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( gd.isGrant() ? '+' : '-' );
+                    buffer.append( gd.getMicroOperation().getName() );
+
+                    if ( it.hasNext() )
                     {
                         buffer.append( ',' );
                     }
                 }
-                
-                
+
                 String s = buffer.toString();
                 s = s.replace( '\r', ' ' );
                 s = s.replace( '\n', ' ' );
-                if(s.length() > 50)
+                if ( s.length() > 50 )
                 {
                     String temp = s;
                     s = temp.substring( 0, 25 );
-                    s = s + "...";
+                    s = s + "..."; //$NON-NLS-1$
                     s = s + temp.substring( temp.length() - 25, temp.length() );
                 }
                 return s;
             }
         }
     }
-    
-    
+
+
+    /**
+     * 
+     * Creates a new instance of ACIItemItemPermissionsComposite.
+     *
+     * @param parent
+     * @param style
+     */
     public ACIItemItemPermissionsComposite( Composite parent, int style )
     {
         super( parent, style );
-        
+
         GridLayout layout = new GridLayout();
         layout.horizontalSpacing = 0;
         layout.verticalSpacing = 0;
         layout.marginHeight = 0;
         layout.marginWidth = 0;
         setLayout( layout );
-        
-        createComposite();
 
         GridData layoutData = new GridData();
         layoutData.horizontalAlignment = GridData.FILL;
         layoutData.grabExcessHorizontalSpace = true;
         layoutData.verticalAlignment = GridData.CENTER;
         setLayoutData( layoutData );
+
+        createComposite();
     }
 
 
@@ -191,33 +205,33 @@
      */
     private void createComposite()
     {
-        
+
         GridData labelGridData = new GridData();
         labelGridData.horizontalSpan = 2;
         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.verticalSpan = 1;
         gridData.verticalAlignment = GridData.BEGINNING;
-        
+
         composite = new Composite( this, SWT.NONE );
-        composite.setLayoutData(gridData);
-        composite.setLayout(gridLayout);
-        
-        label = new Label(composite, SWT.NONE);
-        label.setText("Item Permissions:");
-        label.setLayoutData(labelGridData);
-        
+        composite.setLayoutData( gridData );
+        composite.setLayout( gridLayout );
+
+        label = new Label( composite, SWT.NONE );
+        label.setText( Messages.getString( "ACIItemItemPermissionsComposite.description" ) ); //$NON-NLS-1$
+        label.setLayoutData( labelGridData );
+
         createTable();
-        
+
         createButtonComposite();
     }
 
@@ -250,16 +264,17 @@
                 itemPermissionSelected();
             }
         } );
-        
-        tableViewer.addDoubleClickListener( new IDoubleClickListener(){
+
+        tableViewer.addDoubleClickListener( new IDoubleClickListener()
+        {
             public void doubleClick( DoubleClickEvent event )
             {
                 editItemPermission();
             }
         } );
     }
-    
-    
+
+
     /**
      * This method initializes buttons  
      *
@@ -270,17 +285,20 @@
         deleteButtonGridData.horizontalAlignment = GridData.FILL;
         deleteButtonGridData.grabExcessHorizontalSpace = false;
         deleteButtonGridData.verticalAlignment = GridData.BEGINNING;
-        
+        deleteButtonGridData.widthHint = Activator.getButtonWidth( this );
+
         GridData editButtonGridData = new GridData();
         editButtonGridData.horizontalAlignment = GridData.FILL;
         editButtonGridData.grabExcessHorizontalSpace = false;
         editButtonGridData.verticalAlignment = GridData.BEGINNING;
-        
+        editButtonGridData.widthHint = Activator.getButtonWidth( this );
+
         GridData addButtonGridData = new GridData();
         addButtonGridData.horizontalAlignment = GridData.FILL;
         addButtonGridData.grabExcessHorizontalSpace = false;
         addButtonGridData.verticalAlignment = GridData.BEGINNING;
-        
+        addButtonGridData.widthHint = Activator.getButtonWidth( this );
+
         GridLayout gridLayout = new GridLayout();
         gridLayout.marginWidth = 0;
         gridLayout.marginHeight = 0;
@@ -289,54 +307,61 @@
         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 );
-        
-        addButton = new Button(buttonComposite, SWT.NONE);
-        addButton.setText("Add...");
-        addButton.setLayoutData(addButtonGridData);
-        addButton.addSelectionListener( new SelectionAdapter(){
+
+        addButton = new Button( buttonComposite, SWT.NONE );
+        addButton.setText( Messages.getString( "ACIItemItemPermissionsComposite.add.button" ) ); //$NON-NLS-1$
+        addButton.setLayoutData( addButtonGridData );
+        addButton.addSelectionListener( new SelectionAdapter()
+        {
             public void widgetSelected( SelectionEvent e )
             {
                 addItemPermission();
             }
         } );
-        
-        editButton = new Button(buttonComposite, SWT.NONE);
-        editButton.setText("Edit...");
-        editButton.setLayoutData(editButtonGridData);
-        editButton.addSelectionListener( new SelectionAdapter(){
+
+        editButton = new Button( buttonComposite, SWT.NONE );
+        editButton.setText( Messages.getString( "ACIItemItemPermissionsComposite.edit.button" ) ); //$NON-NLS-1$
+        editButton.setLayoutData( editButtonGridData );
+        editButton.addSelectionListener( new SelectionAdapter()
+        {
             public void widgetSelected( SelectionEvent e )
             {
                 editItemPermission();
             }
         } );
         editButton.setEnabled( false );
-        
-        deleteButton = new Button(buttonComposite, SWT.NONE);
-        deleteButton.setText("Delete");
-        deleteButton.setLayoutData(deleteButtonGridData);
-        deleteButton.addSelectionListener( new SelectionAdapter(){
+
+        deleteButton = new Button( buttonComposite, SWT.NONE );
+        deleteButton.setText( Messages.getString( "ACIItemItemPermissionsComposite.delete.button" ) ); //$NON-NLS-1$
+        deleteButton.setLayoutData( deleteButtonGridData );
+        deleteButton.addSelectionListener( new SelectionAdapter()
+        {
             public void widgetSelected( SelectionEvent e )
             {
                 deleteItemPermission();
             }
         } );
         deleteButton.setEnabled( false );
-        
+
     }
-    
 
-    
+
+    /**
+     * Shows or hides this composite.
+     * 
+     * @see org.eclipse.swt.widgets.control#setVisible(boolean)
+     */
     public void setVisible( boolean visible )
     {
         super.setVisible( visible );
-        ((GridData)getLayoutData()).heightHint = visible ? -1 : 0;
+        ( ( GridData ) getLayoutData() ).heightHint = visible ? -1 : 0;
     }
-    
-    
+
+
     /**
      * Sets the item permissions. 
      *
@@ -344,24 +369,25 @@
      */
     public void setItemPermissions( Collection<ItemPermission> itemPermissions )
     {
+        itemPermissionWrappers.clear();
+
         for ( ItemPermission itemPermission : itemPermissions )
         {
-            ItemPermissionWrapper itemPermissionWrapper = new ItemPermissionWrapper(itemPermission);
-            
+            ItemPermissionWrapper itemPermissionWrapper = new ItemPermissionWrapper( itemPermission );
+
             itemPermissionWrappers.add( itemPermissionWrapper );
         }
 
         tableViewer.refresh();
     }
 
-    
+
     /**
      * Returns the item permissions as selected by the user.
      *
      * @return the item permissions
-     * @throws ParseException 
      */
-    public Collection<ItemPermission> getItemPermissions() throws ParseException
+    public Collection<ItemPermission> getItemPermissions()
     {
         Collection<ItemPermission> itemPermissions = new ArrayList<ItemPermission>();
 
@@ -372,74 +398,84 @@
 
         return itemPermissions;
     }
-    
+
+
     /**
      * 
      * @return the item permission that is selected in the table viewer, or null.
      */
-    private ItemPermissionWrapper getSelectedItemPermissionWrapper() 
+    private ItemPermissionWrapper getSelectedItemPermissionWrapper()
     {
         ItemPermissionWrapper itemPermissionWrapper = null;
-        
+
         IStructuredSelection selection = ( IStructuredSelection ) tableViewer.getSelection();
         if ( !selection.isEmpty() )
         {
             Object element = selection.getFirstElement();
             if ( element instanceof ItemPermissionWrapper )
             {
-                itemPermissionWrapper = (ItemPermissionWrapper) element;
+                itemPermissionWrapper = ( ItemPermissionWrapper ) element;
             }
         }
-        
+
         return itemPermissionWrapper;
     }
-    
-    
-    private void addItemPermission() 
+
+
+    /**
+     * Opens the ItemPermissionDialog and adds the composed 
+     * item permission to the list.
+     */
+    private void addItemPermission()
     {
         ItemPermissionDialog dialog = new ItemPermissionDialog( getShell(), null );
         if ( dialog.open() == TextDialog.OK && dialog.getItemPermission() != null )
         {
-            ItemPermissionWrapper itemPermissionWrapper = new ItemPermissionWrapper(dialog.getItemPermission());
+            ItemPermissionWrapper itemPermissionWrapper = new ItemPermissionWrapper( dialog.getItemPermission() );
             itemPermissionWrappers.add( itemPermissionWrapper );
-            
+
             tableViewer.refresh();
         }
     }
-    
-    
-    private void editItemPermission() 
+
+
+    /**
+     * Opens the ItemPermissionDialog with the currently selected
+     * item permission and puts the modified item permission into the list.
+     */
+    private void editItemPermission()
     {
         ItemPermissionWrapper oldItemPermissionWrapper = getSelectedItemPermissionWrapper();
-        if(oldItemPermissionWrapper != null)
+        if ( oldItemPermissionWrapper != null )
         {
             ItemPermissionDialog dialog = new ItemPermissionDialog( getShell(), oldItemPermissionWrapper.itemPermission );
             if ( dialog.open() == TextDialog.OK )
             {
-                // remove old
-                itemPermissionWrappers.remove( oldItemPermissionWrapper );
-                
-                // create and add new
-                ItemPermissionWrapper newItemPermissionWrapper = new ItemPermissionWrapper(dialog.getItemPermission());
-                itemPermissionWrappers.add( newItemPermissionWrapper );
-                
+                oldItemPermissionWrapper.itemPermission = dialog.getItemPermission();
                 tableViewer.refresh();
             }
         }
     }
-    
-    
-    private void deleteItemPermission() 
+
+
+    /**
+     * Deletes the currently selected item permission from list.
+     */
+    private void deleteItemPermission()
     {
         ItemPermissionWrapper itemPermissionWrapper = getSelectedItemPermissionWrapper();
-        if(itemPermissionWrapper != null)
+        if ( itemPermissionWrapper != null )
         {
             itemPermissionWrappers.remove( itemPermissionWrapper );
             tableViewer.refresh();
         }
     }
-    
-    
+
+
+    /**
+     * Called when an item permission is selected in table viewer.
+     * Updates the enabled/disabled state of the buttons.
+     */
     private void itemPermissionSelected()
     {
         ItemPermissionWrapper itemPermissionWrapper = getSelectedItemPermissionWrapper();

Added: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java?view=auto&rev=491293
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java (added)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemProtectedItemsComposite.java Sat Dec 30 11:19:04 2006
@@ -0,0 +1,639 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.ldapstudio.aciitemeditor.widgets;
+
+
+import java.text.ParseException;
+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.Activator;
+import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
+import org.apache.directory.shared.ldap.aci.ACIItemParser;
+import org.apache.directory.shared.ldap.aci.ItemFirstACIItem;
+import org.apache.directory.shared.ldap.aci.ProtectedItem;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.osgi.util.NLS;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+
+
+/**
+ * This composite contains GUI elements to edit ACI item protected items.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ACIItemProtectedItemsComposite extends Composite
+{
+
+    /** The inner composite for all the content */
+    private Composite composite = null;
+
+    /** The description label */
+    private Label label = null;
+
+    /** The table control for the table viewer */
+    private Table table = null;
+
+    /** The table viewer containing all protected items */
+    private CheckboxTableViewer tableViewer = null;
+
+    /** The composite containing the buttons */
+    private Composite buttonComposite = null;
+
+    /** The edit button */
+    private Button editButton = null;
+
+    /** The select all button */
+    private Button selectAllButton = null;
+
+    /** The deselect all button */
+    private Button deselectAllButton = null;
+
+    /** The reverse button */
+    private Button reverseSelectionButton = null;
+
+    /** The possible protected items, used as input for the table viewer */
+    private ProtectedItemWrapper[] protectedItemWrappers = new ProtectedItemWrapper[]
+        { new ProtectedItemWrapper( ProtectedItem.Entry.class ), // null
+            new ProtectedItemWrapper( ProtectedItem.AllUserAttributeTypes.class ), // null
+            new ProtectedItemWrapper( ProtectedItem.AttributeType.class ), // attributeType { 1.2.3, cn }
+            new ProtectedItemWrapper( ProtectedItem.AllAttributeValues.class ), // allAttributeValues { 1.2.3, cn }
+            new ProtectedItemWrapper( ProtectedItem.AllUserAttributeTypesAndValues.class ), // null
+            new ProtectedItemWrapper( ProtectedItem.AttributeValue.class ), // attributeValue { ou=people, cn=Ersin }
+            new ProtectedItemWrapper( ProtectedItem.SelfValue.class ), // selfValue { 1.2.3, cn }
+            new ProtectedItemWrapper( ProtectedItem.RangeOfValues.class ), // rangeOfValues (cn=ErsinEr)
+            new ProtectedItemWrapper( ProtectedItem.MaxValueCount.class ), // maxValueCount { { type 10.11.12, maxCount 10 }, { maxCount 20, type 11.12.13  } }
+            new ProtectedItemWrapper( ProtectedItem.MaxImmSub.class ), // maxImmSub 3
+            new ProtectedItemWrapper( ProtectedItem.RestrictedBy.class ), // restrictedBy { { type 10.11.12, valuesIn ou }, { valuesIn cn, type 11.12.13  } }
+            new ProtectedItemWrapper( ProtectedItem.Classes.class ), // classes and : { item: xyz , or:{item:X,item:Y}   }
+        };
+
+    /**
+     * The ProtectedItemWrapper is used as input for the table viewer. 
+     * The protected item values are always stored as raw string value.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    static class ProtectedItemWrapper
+    {
+        /** This map contains all possible protected item identifiers */
+        static final Map<Class, String> classToItemMap = new HashMap<Class, String>();
+        static
+        {
+            classToItemMap.put( ProtectedItem.Entry.class, "entry" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.AllUserAttributeTypes.class, "allUserAttributeTypes" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.AttributeType.class, "attributeType" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.AllAttributeValues.class, "allAttributeValues" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.AllUserAttributeTypesAndValues.class, "allUserAttributeTypesAndValues" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.AttributeValue.class, "attributeValue" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.SelfValue.class, "selfValue" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.RangeOfValues.class, "rangeOfValues" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.MaxValueCount.class, "maxValueCount" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.MaxImmSub.class, "maxImmSub" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.RestrictedBy.class, "restrictedBy" ); //$NON-NLS-1$
+            classToItemMap.put( ProtectedItem.Classes.class, "classes" ); //$NON-NLS-1$
+        }
+
+        /** This map contains all protected item display values */
+        static final Map<Class, String> classToDisplayMap = new HashMap<Class, String>();
+        static
+        {
+            classToDisplayMap.put( ProtectedItem.Entry.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.entry.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.AllUserAttributeTypes.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.allUserAttributeTypes.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.AttributeType.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.attributeType.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.AllAttributeValues.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.allAttributeValues.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.AllUserAttributeTypesAndValues.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.allUserAttributeTypesAndValues.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.AttributeValue.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.attributeValue.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.SelfValue.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.selfValue.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.RangeOfValues.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.rangeOfValues.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.MaxValueCount.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.maxValueCount.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.MaxImmSub.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.maxImmSub.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.RestrictedBy.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.restrictedBy.label" ) ); //$NON-NLS-1$
+            classToDisplayMap.put( ProtectedItem.Classes.class, Messages
+                .getString( "ACIItemProtectedItemsComposite.protectedItem.classes.label" ) ); //$NON-NLS-1$
+        }
+
+        /** A dummy ACI to check syntax of the protectedItemValue */
+        private static final String DUMMY = "{ identificationTag \"id1\", precedence 1, authenticationLevel simple, " //$NON-NLS-1$
+            + "itemOrUserFirst itemFirst: { protectedItems  { #item# #value# }, " //$NON-NLS-1$
+            + "itemPermissions { { userClasses { allUsers }, grantsAndDenials { grantRead } } } } }"; //$NON-NLS-1$ 
+
+        /** The class of the protected item, never null. */
+        private final Class protectedItemClass;
+
+        /** The protected item as string, may be empty. */
+        private String protectedItemValue;
+
+
+        /**
+         * Creates a new instance of ProtectedItemWrapper.
+         *
+         * @param protectedItemClass
+         */
+        private ProtectedItemWrapper( Class protectedItemClass )
+        {
+            this.protectedItemClass = protectedItemClass;
+            this.protectedItemValue = ""; //$NON-NLS-1$
+        }
+
+
+        /**
+         * Creates a new protected item object. Therefore it uses the 
+         * dummy ACI, injects the protected item and its value, parses
+         * the ACI and extracts the protected item from the parsed bean.
+         *
+         * @return
+         * @throws ParseException
+         */
+        private ProtectedItem getProtectedItem() throws ParseException
+        {
+            String type = classToItemMap.get( protectedItemClass );
+            String spec = DUMMY;
+            spec = spec.replaceAll( "#item#", type ); //$NON-NLS-1$
+            spec = spec.replaceAll( "#value#", protectedItemValue ); //$NON-NLS-1$
+            ACIItemParser parser = Activator.getDefault().getACIItemParser();
+            ItemFirstACIItem aci = null;
+            try
+            {
+                aci = ( ItemFirstACIItem ) parser.parse( spec );
+            }
+            catch ( ParseException e )
+            {
+
+                String msg = NLS
+                    .bind(
+                        Messages.getString( "ACIItemProtectedItemsComposite.error.message" ), new String[] { type, protectedItemValue } ); //$NON-NLS-1$
+                throw new ParseException( msg, 0 );
+            }
+            ProtectedItem item = ( ProtectedItem ) aci.getProtectedItems().iterator().next();
+            return item;
+        }
+
+
+        /**
+         * Returns a user-friedly string, displayed in the table.
+         */
+        public String toString()
+        {
+            String string = classToDisplayMap.get( protectedItemClass );
+            if ( string == null )
+                string = "<UNKNOWN>"; //$NON-NLS-1$
+            return string + getProtectedItemValue();
+        }
+
+
+        /**
+         * Helper to format the value
+         */
+        private String getProtectedItemValue()
+        {
+            String s = protectedItemValue;
+            if ( s.length() > 0 )
+            {
+                s = s.replace( '\r', ' ' );
+                s = s.replace( '\n', ' ' );
+                s = ": " + s; //$NON-NLS-1$
+                if ( s.length() > 40 )
+                {
+                    String temp = s;
+                    s = temp.substring( 0, 20 );
+                    s = s + "..."; //$NON-NLS-1$
+                    s = s + temp.substring( temp.length() - 20, temp.length() );
+                }
+            }
+            return s;
+        }
+    }
+
+
+    /**
+     * Creates a new instance of ACIItemProtectedItemsComposite.
+     *
+     * @param parent
+     * @param style
+     */
+    public ACIItemProtectedItemsComposite( Composite parent, int style )
+    {
+        super( parent, style );
+
+        GridLayout layout = new GridLayout();
+        layout.horizontalSpacing = 0;
+        layout.verticalSpacing = 0;
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        setLayout( layout );
+
+        GridData layoutData = new GridData();
+        layoutData.horizontalAlignment = GridData.FILL;
+        layoutData.grabExcessHorizontalSpace = true;
+        layoutData.verticalAlignment = GridData.CENTER;
+        setLayoutData( layoutData );
+
+        createComposite();
+    }
+
+
+    /**
+     * This method initializes composite	
+     *
+     */
+    private void createComposite()
+    {
+
+        GridData labelGridData = new GridData();
+        labelGridData.horizontalSpan = 2;
+        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.verticalSpan = 1;
+        gridData.verticalAlignment = GridData.BEGINNING;
+
+        composite = new Composite( this, SWT.NONE );
+        composite.setLayoutData( gridData );
+        composite.setLayout( gridLayout );
+
+        label = new Label( composite, SWT.NONE );
+        label.setText( Messages.getString( "ACIItemProtectedItemsComposite.description" ) ); //$NON-NLS-1$
+        label.setLayoutData( labelGridData );
+
+        createTable();
+
+        createButtonComposite();
+    }
+
+
+    /**
+     * This method initializes table and table viewer
+     *
+     */
+    private void createTable()
+    {
+        GridData tableGridData = new GridData();
+        tableGridData.grabExcessHorizontalSpace = true;
+        tableGridData.verticalAlignment = GridData.FILL;
+        tableGridData.horizontalAlignment = GridData.FILL;
+        //tableGridData.heightHint = 100;
+
+        table = new Table( composite, SWT.BORDER | SWT.CHECK );
+        table.setHeaderVisible( false );
+        table.setLayoutData( tableGridData );
+        table.setLinesVisible( true );
+        tableViewer = new CheckboxTableViewer( table );
+        tableViewer.setContentProvider( new ArrayContentProvider() );
+        tableViewer.setLabelProvider( new ProtectedItemsLabelProvider() );
+        tableViewer.setInput( protectedItemWrappers );
+
+        tableViewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                protectedItemSelected();
+            }
+        } );
+        tableViewer.addCheckStateListener( new ICheckStateListener()
+        {
+            public void checkStateChanged( CheckStateChangedEvent event )
+            {
+                protectedItemChecked();
+            }
+        } );
+        tableViewer.addDoubleClickListener( new IDoubleClickListener()
+        {
+            public void doubleClick( DoubleClickEvent event )
+            {
+                if ( editButton.isEnabled() )
+                {
+                    editProtectedItem();
+                }
+            }
+        } );
+    }
+
+
+    /**
+     * This method initializes buttons	
+     *
+     */
+    private void createButtonComposite()
+    {
+        GridData reverseSelectionButtonGridData = new GridData();
+        reverseSelectionButtonGridData.horizontalAlignment = GridData.FILL;
+        reverseSelectionButtonGridData.grabExcessHorizontalSpace = false;
+        reverseSelectionButtonGridData.verticalAlignment = GridData.BEGINNING;
+        reverseSelectionButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridData deselectAllButtonGridData = new GridData();
+        deselectAllButtonGridData.horizontalAlignment = GridData.FILL;
+        deselectAllButtonGridData.grabExcessHorizontalSpace = false;
+        deselectAllButtonGridData.verticalAlignment = GridData.BEGINNING;
+        deselectAllButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridData selectAllButtonGridData = new GridData();
+        selectAllButtonGridData.horizontalAlignment = GridData.FILL;
+        selectAllButtonGridData.grabExcessHorizontalSpace = false;
+        selectAllButtonGridData.verticalAlignment = GridData.BEGINNING;
+        selectAllButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridData editButtonGridData = new GridData();
+        editButtonGridData.horizontalAlignment = GridData.FILL;
+        editButtonGridData.grabExcessHorizontalSpace = false;
+        editButtonGridData.verticalAlignment = GridData.BEGINNING;
+        editButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridLayout gridLayout = new GridLayout();
+        gridLayout.marginWidth = 0;
+        gridLayout.marginHeight = 0;
+        GridData gridData = new GridData();
+        gridData.horizontalAlignment = GridData.CENTER;
+        gridData.grabExcessHorizontalSpace = false;
+        gridData.grabExcessVerticalSpace = false;
+        gridData.verticalAlignment = GridData.FILL;
+
+        buttonComposite = new Composite( composite, SWT.NONE );
+        buttonComposite.setLayoutData( gridData );
+        buttonComposite.setLayout( gridLayout );
+
+        editButton = new Button( buttonComposite, SWT.NONE );
+        editButton.setText( Messages.getString( "ACIItemProtectedItemsComposite.edit.button" ) ); //$NON-NLS-1$
+        editButton.setLayoutData( editButtonGridData );
+        editButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                editProtectedItem();
+            }
+        } );
+        editButton.setEnabled( false );
+
+        selectAllButton = new Button( buttonComposite, SWT.NONE );
+        selectAllButton.setText( Messages.getString( "ACIItemProtectedItemsComposite.selectAll.button" ) ); //$NON-NLS-1$
+        selectAllButton.setLayoutData( selectAllButtonGridData );
+        selectAllButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                tableViewer.setCheckedElements( protectedItemWrappers );
+                tableViewer.refresh();
+            }
+        } );
+
+        deselectAllButton = new Button( buttonComposite, SWT.NONE );
+        deselectAllButton.setText( Messages.getString( "ACIItemProtectedItemsComposite.deselectAll.button" ) ); //$NON-NLS-1$
+        deselectAllButton.setLayoutData( deselectAllButtonGridData );
+        deselectAllButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                tableViewer.setCheckedElements( new ProtectedItem[0] );
+                tableViewer.refresh();
+            }
+        } );
+
+        reverseSelectionButton = new Button( buttonComposite, SWT.NONE );
+        reverseSelectionButton.setText( Messages.getString( "ACIItemProtectedItemsComposite.revers.button" ) ); //$NON-NLS-1$
+        reverseSelectionButton.setLayoutData( reverseSelectionButtonGridData );
+        reverseSelectionButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                List<Object> elements = new ArrayList<Object>();
+                elements.addAll( Arrays.asList( protectedItemWrappers ) );
+                elements.removeAll( Arrays.asList( tableViewer.getCheckedElements() ) );
+                tableViewer.setCheckedElements( elements.toArray() );
+                tableViewer.refresh();
+            }
+        } );
+
+    }
+
+    /**
+     * The label provider used for this table viewer.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    private class ProtectedItemsLabelProvider extends LabelProvider
+    {
+        /**
+         * Returns the error icon if the protected item is checked and invalid.
+         */
+        public Image getImage( Object element )
+        {
+            if ( element instanceof ProtectedItemWrapper )
+            {
+                ProtectedItemWrapper wrapper = ( ProtectedItemWrapper ) element;
+                if ( tableViewer.getChecked( wrapper ) )
+                {
+                    try
+                    {
+                        wrapper.getProtectedItem();
+                    }
+                    catch ( ParseException e )
+                    {
+                        return Activator.getDefault().getImage(
+                            Messages.getString( "ACIItemProtectedItemsComposite.error.icon" ) ); //$NON-NLS-1$
+                    }
+                }
+            }
+
+            return null;
+        }
+    }
+
+
+    /**
+     * Sets the protected items. 
+     *
+     * @param protectedItems
+     */
+    public void setProtectedItems( Collection<ProtectedItem> protectedItems )
+    {
+        for ( ProtectedItem item : protectedItems )
+        {
+            for ( ProtectedItemWrapper protectedItemWrapper : protectedItemWrappers )
+            {
+                if ( protectedItemWrapper.protectedItemClass == item.getClass() )
+                {
+                    StringBuffer buffer = new StringBuffer();
+                    item.printToBuffer( buffer );
+                    String s = buffer.toString();
+                    if ( s.indexOf( ' ' ) > -1 )
+                    {
+                        s = s.substring( s.indexOf( ' ' ), s.length() );
+                        protectedItemWrapper.protectedItemValue = s;
+                    }
+                    tableViewer.setChecked( protectedItemWrapper, true );
+                }
+            }
+        }
+
+        tableViewer.refresh();
+    }
+
+
+    /**
+     * Returns the protected items as selected by the user.
+     *
+     * @return the protected items
+     * @throws ParseException if the protected items or its values are not valid.
+     */
+    public Collection<ProtectedItem> getProtectedItems() throws ParseException
+    {
+
+        Collection<ProtectedItem> protectedItems = new ArrayList<ProtectedItem>();
+
+        for ( ProtectedItemWrapper protectedItemWrapper : protectedItemWrappers )
+        {
+            if ( tableViewer.getChecked( protectedItemWrapper ) )
+            {
+                ProtectedItem protectedItem = protectedItemWrapper.getProtectedItem();
+                protectedItems.add( protectedItem );
+            }
+        }
+
+        return protectedItems;
+    }
+
+
+    /**
+     * Shows or hides this composite.
+     * 
+     * @see org.eclipse.swt.widgets.control#setVisible(boolean)
+     */
+    public void setVisible( boolean visible )
+    {
+        super.setVisible( visible );
+        ( ( GridData ) getLayoutData() ).heightHint = visible ? -1 : 0;
+    }
+
+
+    /**
+     * 
+     * @return the protected item that is selected in the table viewer, or null.
+     */
+    private ProtectedItemWrapper getSelectedProtectedItemWrapper()
+    {
+        ProtectedItemWrapper protectedItemWrapper = null;
+
+        IStructuredSelection selection = ( IStructuredSelection ) tableViewer.getSelection();
+        if ( !selection.isEmpty() )
+        {
+            Object element = selection.getFirstElement();
+            if ( element instanceof ProtectedItemWrapper )
+            {
+                protectedItemWrapper = ( ProtectedItemWrapper ) element;
+            }
+        }
+
+        return protectedItemWrapper;
+    }
+
+
+    /**
+     * Called, when a protected item is selected in the table viewer.
+     * - enables/disables the edit button
+     *
+     */
+    private void protectedItemSelected()
+    {
+        ProtectedItemWrapper protectedItemWrapper = getSelectedProtectedItemWrapper();
+
+        if ( protectedItemWrapper == null || protectedItemWrapper.protectedItemClass == ProtectedItem.Entry.class
+            || protectedItemWrapper.protectedItemClass == ProtectedItem.AllUserAttributeTypes.class
+            || protectedItemWrapper.protectedItemClass == ProtectedItem.AllUserAttributeTypesAndValues.class )
+        {
+            editButton.setEnabled( false );
+        }
+        else
+        {
+            editButton.setEnabled( true );
+        }
+    }
+
+
+    /**
+     * Called, when a protected item checkbox is checked or unchecked.
+     */
+    private void protectedItemChecked()
+    {
+        tableViewer.refresh();
+    }
+
+
+    /**
+     * Called, when pushing the edit button. Opens the text editor.
+     *
+     */
+    private void editProtectedItem()
+    {
+        ProtectedItemWrapper protectedItemWrapper = getSelectedProtectedItemWrapper();
+
+        TextDialog dialog = new TextDialog( getShell(), protectedItemWrapper.protectedItemValue );
+        if ( dialog.open() == TextDialog.OK )
+        {
+            protectedItemWrapper.protectedItemValue = dialog.getText();
+            tableViewer.refresh();
+        }
+    }
+
+}

Added: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemSourceEditorComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemSourceEditorComposite.java?view=auto&rev=491293
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemSourceEditorComposite.java (added)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemSourceEditorComposite.java Sat Dec 30 11:19:04 2006
@@ -0,0 +1,149 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.ldapstudio.aciitemeditor.widgets;
+
+
+import java.text.ParseException;
+
+import org.apache.directory.ldapstudio.aciitemeditor.Activator;
+import org.apache.directory.shared.ldap.aci.ACIItemParser;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * This composite contains the source editor.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ACIItemSourceEditorComposite extends Composite
+{
+
+    /** The source editor */
+    private SourceViewer sourceEditor;
+
+
+    /**
+     * Creates a new instance of ACIItemSourceEditorComposite.
+     *
+     * @param parent
+     * @param style
+     */
+    public ACIItemSourceEditorComposite( Composite parent, int style )
+    {
+        super( parent, style );
+        setLayout( new FillLayout() );
+
+        createSourceEditor();
+    }
+
+
+    /**
+     * Creates and configures the source editor.
+     *
+     */
+    private void createSourceEditor()
+    {
+        // create source editor
+        sourceEditor = new SourceViewer( this, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL );
+
+        // setup basic configuration
+        // TODO: configuration with syntax highlighting, content assistent, ...
+        SourceViewerConfiguration configuration = new SourceViewerConfiguration();
+        sourceEditor.configure( configuration );
+
+        // set text font
+        Font font = JFaceResources.getFont( JFaceResources.TEXT_FONT );
+        sourceEditor.getTextWidget().setFont( font );
+
+        // setup document
+        IDocument document = new Document();
+        sourceEditor.setDocument( document );
+
+    }
+
+
+    /**
+     * Sets the input to the source editor.
+     * A syntax check is performed before setting the input, an 
+     * invalid syntax causes a ParseException.
+     *
+     * @param input the valid string representation of the ACI item
+     * @throws ParseException it the syntax check fails.
+     */
+    public void setInput( String input ) throws ParseException
+    {
+        ACIItemParser parser = Activator.getDefault().getACIItemParser();
+        parser.parse( input );
+
+        forceSetInput( input );
+    }
+
+
+    /**
+     * Set the input to the source editor without a syntax check.
+     *
+     * @param input The string representation of the ACI item, may be invalid
+     */
+    public void forceSetInput( String input )
+    {
+        sourceEditor.getDocument().set( input );
+    }
+
+
+    /**
+     * Returns the string representation of the ACI item.
+     * A syntax check is performed before returning the input, an 
+     * invalid syntax causes a ParseException.
+     *
+     * @return the valid string representation of the ACI item
+     * @throws ParseException it the syntax check fails.
+     */
+    public String getInput() throws ParseException
+    {
+        String input = forceGetInput();
+
+        ACIItemParser parser = Activator.getDefault().getACIItemParser();
+        parser.parse( input );
+
+        return input;
+    }
+
+
+    /**
+     * Returns the string representation of the ACI item without syntax check.
+     * In other words only the text in the source editor is returned.
+     *
+     * @return the string representation of the ACI item, may be invalid
+     */
+    public String forceGetInput()
+    {
+        return sourceEditor.getDocument().get();
+    }
+
+}

Added: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemTabFolderComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemTabFolderComposite.java?view=auto&rev=491293
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemTabFolderComposite.java (added)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemTabFolderComposite.java Sat Dec 30 11:19:04 2006
@@ -0,0 +1,274 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.ldapstudio.aciitemeditor.widgets;
+
+
+import java.text.ParseException;
+
+import org.apache.directory.ldapstudio.aciitemeditor.Activator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+
+/**
+ * This composite contains the tabs with visual and source editor.
+ * It also manages the synchronization between these two tabs.
+ * 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ACIItemTabFolderComposite extends Composite
+{
+
+    /** The index of the visual tab */
+    public static final int VISUAL_TAB_INDEX = 0;
+
+    /** The index of the source tab */
+    public static final int SOURCE_TAB_INDEX = 1;
+
+    /** The tab folder */
+    private TabFolder tabFolder;
+
+    /** The visual tab */
+    private TabItem visualTab;
+
+    /** The inner container of the visual tab */
+    private Composite visualContainer;
+
+    /** The visual editor composite */
+    private ACIItemVisualEditorComposite visualComposite;
+
+    /** Tehe source tab */
+    private TabItem sourceTab;
+
+    /** The inner container of the visual tab */
+    private Composite sourceContainer;
+
+    /** The source editor composite */
+    private ACIItemSourceEditorComposite sourceComposite;
+
+
+    /**
+     * Creates a new instance of TabFolderComposite.
+     *
+     * @param parent
+     * @param style
+     */
+    public ACIItemTabFolderComposite( Composite parent, int style )
+    {
+        super( parent, style );
+        setLayoutData( new GridData( GridData.FILL_BOTH ) );
+        GridLayout layout = new GridLayout( 1, false );
+        layout.marginWidth = 0;
+        layout.marginHeight = 0;
+        setLayout( layout );
+
+        createTabFolder();
+
+        createVisualTab();
+
+        createSourceTab();
+
+        initListeners();
+    }
+
+
+    /**
+     * Initializes the listeners.
+     *
+     */
+    private void initListeners()
+    {
+        tabFolder.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                tabSelected();
+            }
+        } );
+    }
+
+
+    /**
+     * Creates the source tab and configures the source editor.
+     *
+     */
+    private void createSourceTab()
+    {
+        // create inner container
+        sourceContainer = new Composite( tabFolder, SWT.BORDER );
+        sourceContainer.setLayout( new FillLayout() );
+
+        // create source editor
+        sourceComposite = new ACIItemSourceEditorComposite( sourceContainer, SWT.NONE );
+
+        // create tab
+        sourceTab = new TabItem( tabFolder, SWT.NONE, SOURCE_TAB_INDEX );
+        sourceTab.setText( Messages.getString( "ACIItemTabFolderComposite.source.tab" ) ); //$NON-NLS-1$
+        sourceTab.setControl( sourceContainer );
+    }
+
+
+    /**
+     * Creates the visual tab and the GUI editor.
+     *
+     */
+    private void createVisualTab()
+    {
+        // create inner container
+        visualContainer = new Composite( tabFolder, SWT.NONE );
+        visualContainer.setLayout( new FillLayout() );
+
+        // create the visual ACIItem composite
+        visualComposite = new ACIItemVisualEditorComposite( visualContainer, SWT.NONE );
+
+        // create tab
+        visualTab = new TabItem( tabFolder, SWT.NONE, VISUAL_TAB_INDEX );
+        visualTab.setText( Messages.getString( "ACIItemTabFolderComposite.visual.tab" ) ); //$NON-NLS-1$
+        visualTab.setControl( visualContainer );
+    }
+
+
+    /**
+     * Creates the tab folder and the listeners.
+     *
+     */
+    private void createTabFolder()
+    {
+        tabFolder = new TabFolder( this, SWT.TOP );
+        GridLayout mainLayout = new GridLayout();
+        mainLayout.marginWidth = 0;
+        mainLayout.marginHeight = 0;
+        tabFolder.setLayout( mainLayout );
+        tabFolder.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+    }
+
+
+    /** 
+     * Called, when a tab is selected. This method manages the synchronization
+     * between visual and source editor.
+     */
+    private void tabSelected()
+    {
+        int index = tabFolder.getSelectionIndex();
+
+        if ( index == SOURCE_TAB_INDEX )
+        {
+            // switched to source tab: serialize visual and set to source
+            // on parse error: print message and return to visual tab
+            try
+            {
+                String input = visualComposite.getInput();
+                sourceComposite.setInput( input );
+            }
+            catch ( ParseException pe )
+            {
+                IStatus status = new Status( IStatus.ERROR, Activator.PLUGIN_ID, 1, Messages
+                    .getString( "ACIItemTabFolderComposite.error.onVisualEditor" ), pe ); //$NON-NLS-1$
+                ErrorDialog.openError( getShell(),
+                    Messages.getString( "ACIItemTabFolderComposite.error.title" ), null, status ); //$NON-NLS-1$
+                tabFolder.setSelection( VISUAL_TAB_INDEX );
+            }
+        }
+        else if ( index == VISUAL_TAB_INDEX )
+        {
+            // switched to visual tab: parse source and populate to visual
+            // on parse error: print message and return to source tab
+            try
+            {
+                String input = sourceComposite.getInput();
+                visualComposite.setInput( input );
+            }
+            catch ( ParseException pe )
+            {
+                IStatus status = new Status( IStatus.ERROR, Activator.PLUGIN_ID, 1, Messages
+                    .getString( "ACIItemTabFolderComposite.error.onSourceEditor" ), pe ); //$NON-NLS-1$
+                ErrorDialog.openError( getShell(),
+                    Messages.getString( "ACIItemTabFolderComposite.error.title" ), null, status ); //$NON-NLS-1$
+                tabFolder.setSelection( SOURCE_TAB_INDEX );
+            }
+        }
+    }
+
+
+    /**
+     * Sets the input to both the source editor and to the visual editor.
+     * If the syntax is invalid the source editor is activated. 
+     *
+     * @param input The string representation of the ACI item
+     */
+    public void setInput( String input )
+    {
+        // set input to source editor
+        sourceComposite.forceSetInput( input );
+
+        // set input to visual editor, on parse error switch to source editor
+        try
+        {
+            visualComposite.setInput( input );
+        }
+        catch ( ParseException pe )
+        {
+            IStatus status = new Status( IStatus.ERROR, Activator.PLUGIN_ID, 1, Messages
+                .getString( "ACIItemTabFolderComposite.error.onInput" ), pe ); //$NON-NLS-1$
+            ErrorDialog.openError( getShell(),
+                Messages.getString( "ACIItemTabFolderComposite.error.title" ), null, status ); //$NON-NLS-1$
+
+            tabFolder.setSelection( SOURCE_TAB_INDEX );
+        }
+    }
+
+
+    /**
+     * Returns the string representation of the ACI item.
+     * A syntax check is performed before returning the input, an 
+     * invalid syntax causes a ParseException.
+     *
+     * @return the valid string representation of the ACI item
+     * @throws ParseException it the syntax check fails.
+     */
+    public String getInput() throws ParseException
+    {
+        int index = tabFolder.getSelectionIndex();
+        if ( index == VISUAL_TAB_INDEX )
+        {
+            String input = visualComposite.getInput();
+            return input;
+        }
+        else
+        {
+            String input = sourceComposite.getInput();
+            return input;
+        }
+    }
+
+}

Added: directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java
URL: http://svn.apache.org/viewvc/directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java?view=auto&rev=491293
==============================================================================
--- directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java (added)
+++ directory/sandbox/seelmann/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/widgets/ACIItemUserClassesComposite.java Sat Dec 30 11:19:04 2006
@@ -0,0 +1,598 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.ldapstudio.aciitemeditor.widgets;
+
+
+import java.text.ParseException;
+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.Activator;
+import org.apache.directory.ldapstudio.aciitemeditor.dialogs.TextDialog;
+import org.apache.directory.shared.ldap.aci.ACIItemParser;
+import org.apache.directory.shared.ldap.aci.ProtectedItem;
+import org.apache.directory.shared.ldap.aci.UserClass;
+import org.apache.directory.shared.ldap.aci.UserFirstACIItem;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.osgi.util.NLS;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+
+
+/**
+ * This composite contains GUI elements to edit ACI item user classes.
+
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ACIItemUserClassesComposite extends Composite
+{
+
+    /** The inner composite for all the content */
+    private Composite composite = null;
+
+    /** The description label */
+    private Label label = null;
+
+    /** The table control for the table viewer */
+    private Table table = null;
+
+    /** The table viewer containing all user classes */
+    private CheckboxTableViewer tableViewer = null;
+
+    /** The composite containing the buttons */
+    private Composite buttonComposite = null;
+
+    /** The edit button */
+    private Button editButton = null;
+
+    /** The select all button */
+    private Button selectAllButton = null;
+
+    /** The deselect all button */
+    private Button deselectAllButton = null;
+
+    /** The reverse button */
+    private Button reverseSelectionButton = null;
+
+    /** The possible user classes, used as input for the table viewer */
+    private UserClassWrapper[] userClassWrappers = new UserClassWrapper[]
+        { new UserClassWrapper( UserClass.AllUsers.class ), // allUsers
+            new UserClassWrapper( UserClass.ThisEntry.class ), // thisEntry
+            new UserClassWrapper( UserClass.Name.class ), // name { "cn=abc", "cn=def" }
+            new UserClassWrapper( UserClass.UserGroup.class ), // userGroup { "cn=abc", "cn=def" }
+            new UserClassWrapper( UserClass.Subtree.class ) // subtree { { base \"ou=people\" } }
+        };
+
+    /**
+     * 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$
+     */
+    static class UserClassWrapper
+    {
+        /** This map contains all possible user class identifiers */
+        static final Map<Class, String> classToItemMap = new HashMap<Class, String>();
+        static
+        {
+            classToItemMap.put( UserClass.AllUsers.class, "allUsers" ); //$NON-NLS-1$
+            classToItemMap.put( UserClass.ThisEntry.class, "thisEntry" ); //$NON-NLS-1$
+            classToItemMap.put( UserClass.Name.class, "name" ); //$NON-NLS-1$
+            classToItemMap.put( UserClass.UserGroup.class, "userGroup" ); //$NON-NLS-1$
+            classToItemMap.put( UserClass.Subtree.class, "subtree" ); //$NON-NLS-1$
+        }
+
+        /** This map contains all user class display values */
+        static final Map<Class, String> classToDisplayMap = new HashMap<Class, String>();
+        static
+        {
+            classToDisplayMap.put( UserClass.AllUsers.class, Messages.getString("ACIItemUserClassesComposite.userClass.allUsers.label") ); //$NON-NLS-1$
+            classToDisplayMap.put( UserClass.ThisEntry.class, Messages.getString("ACIItemUserClassesComposite.userClass.thisEntry.label") ); //$NON-NLS-1$
+            classToDisplayMap.put( UserClass.Name.class, Messages.getString("ACIItemUserClassesComposite.userClass.name.label") ); //$NON-NLS-1$
+            classToDisplayMap.put( UserClass.UserGroup.class, Messages.getString("ACIItemUserClassesComposite.userClass.userGroup.label") ); //$NON-NLS-1$
+            classToDisplayMap.put( UserClass.Subtree.class, Messages.getString("ACIItemUserClassesComposite.userClass.subtree.label") ); //$NON-NLS-1$
+        }
+
+        /** A dummy ACI to check syntax of the userClassValue */
+        private static final String DUMMY = "{ identificationTag \"id1\", precedence 1, authenticationLevel simple, " //$NON-NLS-1$
+            + "itemOrUserFirst userFirst: { userClasses  { #class# #value# }, " //$NON-NLS-1$
+            + "userPermissions { { protectedItems { entry }, grantsAndDenials { grantRead } } } } }"; //$NON-NLS-1$
+
+        /** The class of the user class, never null. */
+        private final Class userClassClass;
+
+        /** The user class as string, may be empty. */
+        private String userClassValue;
+
+
+        /**
+         * Creates a new instance of UserClassWrapper.
+         *
+         * @param userClassClass
+         */
+        private UserClassWrapper( Class userClassClass )
+        {
+            this.userClassClass = userClassClass;
+            this.userClassValue = ""; //$NON-NLS-1$
+        }
+
+
+        private UserClass getUserClass() throws ParseException
+        {
+            String clazz = classToItemMap.get( userClassClass );
+            String spec = DUMMY;
+            spec = spec.replaceAll( "#class#", clazz ); //$NON-NLS-1$
+            spec = spec.replaceAll( "#value#", userClassValue ); //$NON-NLS-1$
+            ACIItemParser parser = new ACIItemParser( null );
+            UserFirstACIItem aci = null;
+            try
+            {
+                aci = ( UserFirstACIItem ) parser.parse( spec );
+            }
+            catch ( ParseException e )
+            {
+                String msg = NLS
+                .bind(
+                    Messages.getString( "ACIItemUserClassesComposite.error.message" ), new String[] { clazz, userClassValue } ); //$NON-NLS-1$
+            throw new ParseException( msg, 0 );
+            }
+            UserClass userClass = ( UserClass ) aci.getUserClasses().iterator().next();
+            return userClass;
+        }
+
+
+        /**
+         * Returns a user-friedly string, displayed in the table.
+         */
+        public String toString()
+        {
+            String string = classToDisplayMap.get( userClassClass );
+            if ( string == null )
+                string = "<UNKNOWN>"; //$NON-NLS-1$
+            return string + getUserClassValue();
+        }
+
+
+        /**
+         * Helper to format the value
+         */
+        private String getUserClassValue()
+        {
+            String s = userClassValue;
+            if ( s.length() > 0 )
+            {
+                s = s.replace( '\r', ' ' );
+                s = s.replace( '\n', ' ' );
+                s = ": " + s; //$NON-NLS-1$
+                if ( s.length() > 40 )
+                {
+                    String temp = s;
+                    s = temp.substring( 0, 20 );
+                    s = s + "..."; //$NON-NLS-1$
+                    s = s + temp.substring( temp.length() - 20, temp.length() );
+                }
+            }
+            return s;
+        }
+    }
+
+
+    /**
+     * Creates a new instance of ACIItemUserClassesComposite.
+     *
+     * @param parent
+     * @param style
+     */
+    public ACIItemUserClassesComposite( Composite parent, int style )
+    {
+        super( parent, style );
+
+        GridLayout layout = new GridLayout();
+        layout.horizontalSpacing = 0;
+        layout.verticalSpacing = 0;
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        setLayout( layout );
+
+        GridData layoutData = new GridData();
+        layoutData.horizontalAlignment = GridData.FILL;
+        layoutData.grabExcessHorizontalSpace = true;
+        layoutData.verticalAlignment = GridData.CENTER;
+        setLayoutData( layoutData );
+        
+        createComposite();
+    }
+
+
+    /**
+     * This method initializes composite    
+     *
+     */
+    private void createComposite()
+    {
+
+        GridData labelGridData = new GridData();
+        labelGridData.horizontalSpan = 2;
+        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.verticalSpan = 1;
+        gridData.verticalAlignment = GridData.BEGINNING;
+
+        composite = new Composite( this, SWT.NONE );
+        composite.setLayoutData( gridData );
+        composite.setLayout( gridLayout );
+
+        label = new Label( composite, SWT.NONE );
+        label.setText( Messages.getString("ACIItemUserClassesComposite.description") ); //$NON-NLS-1$
+        label.setLayoutData( labelGridData );
+
+        createTable();
+
+        createButtonComposite();
+    }
+
+
+    /**
+     * This method initializes table and table viewer
+     *
+     */
+    private void createTable()
+    {
+        GridData tableGridData = new GridData();
+        tableGridData.grabExcessHorizontalSpace = true;
+        tableGridData.verticalAlignment = GridData.FILL;
+        tableGridData.horizontalAlignment = GridData.FILL;
+        //tableGridData.heightHint = 100;
+
+        table = new Table( composite, SWT.BORDER | SWT.CHECK );
+        table.setHeaderVisible( false );
+        table.setLayoutData( tableGridData );
+        table.setLinesVisible( true );
+        tableViewer = new CheckboxTableViewer( table );
+        tableViewer.setContentProvider( new ArrayContentProvider() );
+        tableViewer.setLabelProvider( new UserClassesLabelProvider() );
+        tableViewer.setInput( userClassWrappers );
+
+        tableViewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                userClassSelected();
+            }
+        } );
+        tableViewer.addCheckStateListener( new ICheckStateListener()
+        {
+            public void checkStateChanged( CheckStateChangedEvent event )
+            {
+                userClassChecked();
+            }
+        } );
+        tableViewer.addDoubleClickListener( new IDoubleClickListener()
+        {
+            public void doubleClick( DoubleClickEvent event )
+            {
+                if ( editButton.isEnabled() )
+                {
+                    editUserClass();
+                }
+            }
+        } );
+    }
+
+
+    /**
+     * This method initializes buttons  
+     *
+     */
+    private void createButtonComposite()
+    {
+        GridData reverseSelectionButtonGridData = new GridData();
+        reverseSelectionButtonGridData.horizontalAlignment = GridData.FILL;
+        reverseSelectionButtonGridData.grabExcessHorizontalSpace = false;
+        reverseSelectionButtonGridData.verticalAlignment = GridData.BEGINNING;
+        reverseSelectionButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridData deselectAllButtonGridData = new GridData();
+        deselectAllButtonGridData.horizontalAlignment = GridData.FILL;
+        deselectAllButtonGridData.grabExcessHorizontalSpace = false;
+        deselectAllButtonGridData.verticalAlignment = GridData.BEGINNING;
+        deselectAllButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridData selectAllButtonGridData = new GridData();
+        selectAllButtonGridData.horizontalAlignment = GridData.FILL;
+        selectAllButtonGridData.grabExcessHorizontalSpace = false;
+        selectAllButtonGridData.verticalAlignment = GridData.BEGINNING;
+        selectAllButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridData editButtonGridData = new GridData();
+        editButtonGridData.horizontalAlignment = GridData.FILL;
+        editButtonGridData.grabExcessHorizontalSpace = false;
+        editButtonGridData.verticalAlignment = GridData.BEGINNING;
+        editButtonGridData.widthHint = Activator.getButtonWidth( this );
+
+        GridLayout gridLayout = new GridLayout();
+        gridLayout.marginWidth = 0;
+        gridLayout.marginHeight = 0;
+        GridData gridData = new GridData();
+        gridData.horizontalAlignment = GridData.CENTER;
+        gridData.grabExcessHorizontalSpace = false;
+        gridData.grabExcessVerticalSpace = false;
+        gridData.verticalAlignment = GridData.FILL;
+
+        buttonComposite = new Composite( composite, SWT.NONE );
+        buttonComposite.setLayoutData( gridData );
+        buttonComposite.setLayout( gridLayout );
+
+        editButton = new Button( buttonComposite, SWT.NONE );
+        editButton.setText( Messages.getString("ACIItemUserClassesComposite.edit.button") ); //$NON-NLS-1$
+        editButton.setLayoutData( editButtonGridData );
+        editButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                editUserClass();
+            }
+        } );
+        editButton.setEnabled( false );
+
+        selectAllButton = new Button( buttonComposite, SWT.NONE );
+        selectAllButton.setText( Messages.getString("ACIItemUserClassesComposite.selectAll.button") ); //$NON-NLS-1$
+        selectAllButton.setLayoutData( selectAllButtonGridData );
+        selectAllButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                tableViewer.setCheckedElements( userClassWrappers );
+                tableViewer.refresh();
+            }
+        } );
+
+        deselectAllButton = new Button( buttonComposite, SWT.NONE );
+        deselectAllButton.setText( Messages.getString("ACIItemUserClassesComposite.deselectAll.button") ); //$NON-NLS-1$
+        deselectAllButton.setLayoutData( deselectAllButtonGridData );
+        deselectAllButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                tableViewer.setCheckedElements( new ProtectedItem[0] );
+                tableViewer.refresh();
+            }
+        } );
+
+        reverseSelectionButton = new Button( buttonComposite, SWT.NONE );
+        reverseSelectionButton.setText( Messages.getString("ACIItemUserClassesComposite.revert.buton") ); //$NON-NLS-1$
+        reverseSelectionButton.setLayoutData( reverseSelectionButtonGridData );
+        reverseSelectionButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                List<Object> elements = new ArrayList<Object>();
+                elements.addAll( Arrays.asList( userClassWrappers ) );
+                elements.removeAll( Arrays.asList( tableViewer.getCheckedElements() ) );
+                tableViewer.setCheckedElements( elements.toArray() );
+                tableViewer.refresh();
+            }
+        } );
+
+    }
+
+    /**
+     * The label provider used for this table viewer.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    private class UserClassesLabelProvider extends LabelProvider
+    {
+        /**
+         * Returns the error icon if the user class is checked and invalid.
+         */
+        public Image getImage( Object element )
+        {
+            if ( element instanceof UserClassWrapper )
+            {
+                UserClassWrapper wrapper = ( UserClassWrapper ) element;
+                if ( tableViewer.getChecked( wrapper ) )
+                {
+                    try
+                    {
+                        wrapper.getUserClass();
+                    }
+                    catch ( ParseException e )
+                    {
+                        return Activator.getDefault().getImage( Messages.getString("ACIItemUserClassesComposite.error.icon") ); //$NON-NLS-1$
+                    }
+                }
+            }
+
+            return null;
+        }
+    }
+
+
+    /**
+     * Sets the user classes. 
+     *
+     * @param userClasses
+     */
+    public void setUserClasses( Collection<UserClass> userClasses )
+    {
+        for ( UserClass userClass : userClasses )
+        {
+            for ( UserClassWrapper userClassWrapper : userClassWrappers )
+            {
+                if ( userClassWrapper.userClassClass == userClass.getClass() )
+                {
+                    StringBuffer buffer = new StringBuffer();
+                    userClass.printToBuffer( buffer );
+                    String s = buffer.toString();
+                    if ( s.indexOf( ' ' ) > -1 )
+                    {
+                        s = s.substring( s.indexOf( ' ' ), s.length() );
+                        userClassWrapper.userClassValue = s;
+                    }
+                    tableViewer.setChecked( userClassWrapper, true );
+                }
+            }
+        }
+
+        tableViewer.refresh();
+    }
+
+
+    /**
+     * Returns the user classes as selected by the user.
+     *
+     * @return the user classes
+     * @throws ParseException if the user classes or its values are not valid.
+     */
+    public Collection<UserClass> getUserClasses() throws ParseException
+    {
+        Collection<UserClass> userClasses = new ArrayList<UserClass>();
+
+        for ( UserClassWrapper userClassWrapper : userClassWrappers )
+        {
+            if ( tableViewer.getChecked( userClassWrapper ) )
+            {
+                UserClass userClass = userClassWrapper.getUserClass();
+                userClasses.add( userClass );
+            }
+        }
+
+        return userClasses;
+    }
+
+
+    /**
+     * Shows or hides this composite.
+     * 
+     * @see org.eclipse.swt.widgets.control#setVisible(boolean)
+     */
+    public void setVisible( boolean visible )
+    {
+        super.setVisible( visible );
+        ( ( GridData ) getLayoutData() ).heightHint = visible ? -1 : 0;
+    }
+
+
+    /**
+     * 
+     * @return the user class that is selected in the table viewer, or null.
+     */
+    private UserClassWrapper getSelectedUserClassWrapper()
+    {
+        UserClassWrapper userClassWrapper = null;
+
+        IStructuredSelection selection = ( IStructuredSelection ) tableViewer.getSelection();
+        if ( !selection.isEmpty() )
+        {
+            Object element = selection.getFirstElement();
+            if ( element instanceof UserClassWrapper )
+            {
+                userClassWrapper = ( UserClassWrapper ) element;
+            }
+        }
+
+        return userClassWrapper;
+    }
+
+
+    /**
+     * Called, when a user class is selected in the table viewer.
+     * - enables/disables the edit button
+     *
+     */
+    private void userClassSelected()
+    {
+        UserClassWrapper userClassWrapper = getSelectedUserClassWrapper();
+
+        if ( userClassWrapper == null || userClassWrapper.userClassClass == UserClass.AllUsers.class
+            || userClassWrapper.userClassClass == UserClass.ThisEntry.class )
+        {
+            editButton.setEnabled( false );
+        }
+        else
+        {
+            editButton.setEnabled( true );
+        }
+    }
+
+
+    /**
+     * Called, when a user class checkbox is checked or unchecked.
+     *
+     */
+    private void userClassChecked()
+    {
+        tableViewer.refresh();
+    }
+
+
+    /**
+     * Called, when pushing the edit button. Opens the text editor.
+     *
+     */
+    private void editUserClass()
+    {
+        UserClassWrapper userClassWrapper = getSelectedUserClassWrapper();
+
+        TextDialog dialog = new TextDialog( getShell(), userClassWrapper.userClassValue );
+        if ( dialog.open() == TextDialog.OK )
+        {
+            userClassWrapper.userClassValue = dialog.getText();
+            tableViewer.refresh();
+        }
+
+    }
+
+}