You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by fe...@apache.org on 2007/11/05 17:48:54 UTC

svn commit: r592079 [16/17] - in /directory/sandbox/felixk/studio-ldapbrowser-common: ./ META-INF/ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/directory/ src/main/java/org/apache/directory/studio/...

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/wizards/AttributeWizard.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/wizards/AttributeWizard.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/wizards/AttributeWizard.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/wizards/AttributeWizard.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,225 @@
+/*
+ *  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.studio.ldapbrowser.common.wizards;
+
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+
+/**
+ * The AttributeWizard is used to create a new attribute or
+ * to modify an existing attribute description. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class AttributeWizard extends Wizard implements INewWizard
+{
+
+    /** The type page. */
+    private AttributeTypeWizardPage typePage;
+
+    /** The options page. */
+    private AttributeOptionsWizardPage optionsPage;
+
+    /** The initial show subschema attributes only. */
+    private boolean initialShowSubschemaAttributesOnly;
+
+    /** The initial hide existing attributes. */
+    private boolean initialHideExistingAttributes;
+
+    /** The initial attribute description. */
+    private String initialAttributeDescription;
+
+    /** The initial entry. */
+    private IEntry initialEntry;
+
+    /** The final attribute description. */
+    private String finalAttributeDescription = null;
+
+
+    /**
+     * Creates a new instance of AttributeWizard with an empty
+     * attriute description.
+     */
+    public AttributeWizard()
+    {
+        super.setWindowTitle( "New Attribute" );
+        super.setNeedsProgressMonitor( false );
+        this.initialShowSubschemaAttributesOnly = true;
+        this.initialHideExistingAttributes = true;
+        this.initialAttributeDescription = "";
+        this.initialEntry = null;
+    }
+
+
+    /**
+     * Creates a new instance of AttributeWizard with the given initial attribute desription
+     * 
+     * @param title the title
+     * @param entry the entry
+     * @param showSubschemaAttributesOnly the show subschema attributes only
+     * @param hideExistingAttributes the hide existing attributes
+     * @param attributeDescription the attribute description
+     */
+    public AttributeWizard( String title, boolean showSubschemaAttributesOnly, boolean hideExistingAttributes,
+        String attributeDescription, IEntry entry )
+    {
+        super.setWindowTitle( title );
+        super.setNeedsProgressMonitor( false );
+        this.initialShowSubschemaAttributesOnly = showSubschemaAttributesOnly;
+        this.initialHideExistingAttributes = hideExistingAttributes;
+        this.initialAttributeDescription = attributeDescription;
+        this.initialEntry = entry;
+    }
+
+
+    /**
+     * Gets the id.
+     * 
+     * @return the id
+     */
+    public static String getId()
+    {
+        return AttributeWizard.class.getName();
+    }
+
+
+    /**
+     * {@inheritDoc}}
+     */
+    public void init( IWorkbench workbench, IStructuredSelection selection )
+    {
+    }
+
+
+    /**
+     * {@inheritDoc}}
+     */
+    public void addPages()
+    {
+        if ( initialEntry != null )
+        {
+            typePage = new AttributeTypeWizardPage( AttributeTypeWizardPage.class.getName(), initialEntry,
+                initialAttributeDescription, initialShowSubschemaAttributesOnly, initialHideExistingAttributes, this );
+            addPage( typePage );
+
+            optionsPage = new AttributeOptionsWizardPage( AttributeOptionsWizardPage.class.getName(),
+                initialAttributeDescription, this );
+            addPage( optionsPage );
+        }
+        else
+        {
+            IWizardPage page = new DummyWizardPage();
+            addPage( page );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void createPageControls( Composite pageContainer )
+    {
+        super.createPageControls( pageContainer );
+
+        // set help context ID
+        PlatformUI.getWorkbench().getHelpSystem().setHelp( typePage.getControl(),
+            BrowserCommonActivator.PLUGIN_ID + "." + "tools_attribute_wizard" );
+        PlatformUI.getWorkbench().getHelpSystem().setHelp( optionsPage.getControl(),
+            BrowserCommonActivator.PLUGIN_ID + "." + "tools_attribute_wizard" );
+    }
+
+    /** 
+     * A dummy wizard page to show the user that no entry is selected.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    class DummyWizardPage extends WizardPage
+    {
+
+        /**
+         * Creates a new instance of DummyWizardPage.
+         */
+        protected DummyWizardPage()
+        {
+            super( "" );
+            super.setTitle( "No entry selected" );
+            super.setDescription( "In order to use the attribute creation wizard please select an entry." );
+            // super.setImageDescriptor(BrowserUIPlugin.getDefault().getImageDescriptor(BrowserUIConstants.IMG_ATTRIBUTE_WIZARD));
+            super.setPageComplete( true );
+        }
+
+
+        /**
+         * {@inheritDoc}
+         */
+        public void createControl( Composite parent )
+        {
+            Composite composite = new Composite( parent, SWT.NONE );
+            GridLayout gl = new GridLayout( 1, false );
+            composite.setLayout( gl );
+            composite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+
+            setControl( composite );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean performFinish()
+    {
+        finalAttributeDescription = getAttributeDescription();
+        return true;
+    }
+
+
+    /**
+     * Gets the attribute description.
+     * 
+     * @return the attribute description
+     */
+    public String getAttributeDescription()
+    {
+        if ( finalAttributeDescription != null )
+        {
+            return finalAttributeDescription;
+        }
+
+        return typePage.getAttributeType() + optionsPage.getAttributeOptions();
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/wizards/AttributeWizard.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogBinaryValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogBinaryValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogBinaryValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogBinaryValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,184 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+
+
+/**
+ * 
+ * Abstract base class for value editors that handle binary values
+ * in a dialog. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractDialogBinaryValueEditor extends AbstractDialogValueEditor
+{
+
+    /**
+     * Creates a new instance of AbstractDialogBinaryValueEditor.
+     */
+    protected AbstractDialogBinaryValueEditor()
+    {
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation of getDisplayValue just returns a note,
+     * that the value is binary and the size of the data.
+     */
+    public String getDisplayValue( IValue value )
+    {
+        if ( showRawValues() )
+        {
+            return getPrintableString( value );
+        }
+        else
+        {
+            if ( value == null )
+            {
+                return "NULL";
+            }
+            else if ( value.isBinary() )
+            {
+                byte[] data = value.getBinaryValue();
+                return "Binary Data (" + data.length + " Bytes)";
+            }
+            else
+            {
+                return "Invalid Data";
+            }
+        }
+    }
+
+
+    /**
+     * Helper method, returns a printable string if the value
+     * is binary.
+     * 
+     * @param value the value
+     * 
+     * @return the printable string
+     */
+    public static String getPrintableString( IValue value )
+    {
+        if ( value == null )
+        {
+            return "NULL";
+        }
+        else if ( value.isBinary() )
+        {
+            byte[] data = value.getBinaryValue();
+            StringBuffer sb = new StringBuffer();
+            for ( int i = 0; data != null && i < data.length && i < 128; i++ )
+            {
+                if ( data[i] > 32 && data[i] < 127 )
+                    sb.append( ( char ) data[i] );
+                else
+                    sb.append( '.' );
+            }
+            return sb.toString();
+        }
+        else if ( value.isString() )
+        {
+            return value.getStringValue();
+        }
+        else
+        {
+            return "NULL";
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation returns IValue.EMPTY_BINARY_VALUE if
+     * the attribute is binary.
+     */
+    protected Object getEmptyRawValue( IAttribute attribute )
+    {
+        if ( attribute.isBinary() )
+        {
+            return IValue.EMPTY_BINARY_VALUE;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation returns the binary (byte[]) value 
+     * of the given value. 
+     */
+    public Object getRawValue( IValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        else if ( value.isString() )
+        {
+            return value.getBinaryValue();
+        }
+        else if ( value.isBinary() )
+        {
+            return value.getBinaryValue();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation always return the binary value
+     * as byte[].
+     */
+    public Object getStringOrBinaryValue( Object rawValue )
+    {
+        if ( rawValue == null )
+        {
+            return null;
+        }
+        else if ( rawValue instanceof byte[] )
+        {
+            return rawValue;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogBinaryValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogStringValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogStringValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogStringValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogStringValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,150 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+
+
+/**
+ * 
+ * Abstract base class for value editors that handle string values
+ * in a dialog. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractDialogStringValueEditor extends AbstractDialogValueEditor
+{
+
+    /**
+     * Creates a new instance of AbstractDialogStringValueEditor.
+     */
+    protected AbstractDialogStringValueEditor()
+    {
+        super();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation just returns the raw value
+     */
+    public String getDisplayValue( IValue value )
+    {
+        Object obj = this.getRawValue( value );
+        return obj == null ? "NULL" : obj.toString();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation returns IValue.EMPTY_STRING_VALUE if
+     * the attribute is string.
+     */
+    protected Object getEmptyRawValue( IAttribute attribute )
+    {
+        if ( attribute.isString() )
+        {
+            return IValue.EMPTY_STRING_VALUE;
+        }
+        else
+        {
+            return IValue.EMPTY_BINARY_VALUE;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation returns the string value 
+     * of the given value. 
+     */
+    public Object getRawValue( IValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        else if ( value.isString() )
+        {
+            return value.getStringValue();
+        }
+        else if ( value.isBinary() )
+        {
+            return isEditable( value.getBinaryValue() ) ? value.getStringValue() : null;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * Small helper.
+     */
+    private boolean isEditable( byte[] b )
+    {
+        if ( b == null )
+        {
+            return false;
+        }
+
+        for ( int i = 0; i < b.length; i++ )
+        {
+            if ( !( b[i] == '\n' || b[i] == '\r' || ( b[i] >= '\u0020' && b[i] <= '\u007F' ) ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation always return the string value
+     * as String.
+     */
+    public Object getStringOrBinaryValue( Object rawValue )
+    {
+        if ( rawValue == null )
+        {
+            return null;
+        }
+        else if ( rawValue instanceof String )
+        {
+            return rawValue;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogStringValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,290 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants;
+import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * Abstract base class for value editors that handle values
+ * in a dialog. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractDialogValueEditor extends CellEditor implements IValueEditor
+{
+
+    /** The value to handle */
+    private Object value;
+
+    /** The shell, used to open the editor */
+    private Shell shell;
+
+    /** The name of this value editor */
+    private String name;
+
+    /** The image of this value editor */
+    private ImageDescriptor imageDescriptor;
+
+
+    /**
+     * 
+     * Creates a new instance of AbstractDialogEditor.
+     */
+    protected AbstractDialogValueEditor()
+    {
+    }
+
+
+    /**
+     * Returns true if the user wishes to show raw values rather than
+     * user-friendly values. If true the getDisplayValue() methods 
+     * shouldnot modify the value.
+     *
+     * @return true if raw values should be displayed
+     */
+    protected boolean showRawValues()
+    {
+        return BrowserCommonActivator.getDefault().getPreferenceStore()
+            .getBoolean( BrowserCommonConstants.PREFERENCE_SHOW_RAW_VALUES );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation simple returns itself.
+     */
+    public CellEditor getCellEditor()
+    {
+        return this;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This is a dialog editor, it doesn't create a control. 
+     * It just extracts and saves the shell reference from parent.
+     */
+    protected final Control createControl( Composite parent )
+    {
+        this.shell = parent.getShell();
+        return null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This is a dialog editor, doesn't set focus. 
+     */
+    protected final void doSetFocus()
+    {
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Returns the value object stored in a member.
+     */
+    protected final Object doGetValue()
+    {
+        return this.value;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Stores the value object in a member.
+     */
+    protected final void doSetValue( Object value )
+    {
+        if ( value != null && value instanceof IValue.EmptyValue )
+        {
+            IValue.EmptyValue emptyValue = ( IValue.EmptyValue ) value;
+            if ( emptyValue.isBinary() )
+                value = emptyValue.getBinaryValue();
+            else
+                value = emptyValue.getStringValue();
+        }
+        this.value = value;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * The activate method is called from the JFace framework
+     * to start editing. 
+     */
+    public final void activate()
+    {
+        boolean save = this.openDialog( shell );
+        //doSetValue( newValue );
+        if ( !save || this.value == null )
+        {
+            this.value = null;
+            fireCancelEditor();
+        }
+        else
+        {
+            fireApplyEditorValue();
+            deactivate();
+        }
+    }
+
+
+    /**
+     * Opens the edit dialog. 
+     * Call getValue() to get the current value to edit. 
+     * Call setValue() to set the new value after editing. 
+     *
+     * @param shell The shell to use to open the dialog
+     * @return true if the new value should be stored, false
+     *         to cancel the editor.
+     */
+    protected abstract boolean openDialog( Shell shell );
+
+
+    /**
+     * Returns a raw value that represents an empty value.
+     * 
+     * @param attribute the attribute
+     * @return a raw value that represents an empty value
+     */
+    protected abstract Object getEmptyRawValue( IAttribute attribute );
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation of getDisplayValue() returns a 
+     * comma-separated list of all values. 
+     */
+    public String getDisplayValue( AttributeHierarchy attributeHierarchy )
+    {
+        if ( attributeHierarchy == null )
+        {
+            return "NULL";
+        }
+
+        List<IValue> valueList = new ArrayList<IValue>();
+        for ( Iterator it = attributeHierarchy.iterator(); it.hasNext(); )
+        {
+            IAttribute attribute = ( IAttribute ) it.next();
+            valueList.addAll( Arrays.asList( attribute.getValues() ) );
+        }
+
+        StringBuffer sb = new StringBuffer();
+        for ( Iterator<IValue> it = valueList.iterator(); it.hasNext(); )
+        {
+            IValue value = it.next();
+            sb.append( getDisplayValue( value ) );
+            if ( it.hasNext() )
+                sb.append( ", " );
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation calls getEmptyRawValue(IAttribute) if there are no values
+     * in attributeHierarchy and getRawValue(IValue) if attributeHierarchy
+     * contains exactly one value. Otherwise null is returned.
+     */
+    public Object getRawValue( AttributeHierarchy attributeHierarchy )
+    {
+        if ( attributeHierarchy == null )
+        {
+            return null;
+        }
+        else if ( attributeHierarchy.size() == 1 && attributeHierarchy.getAttribute().getValueSize() == 0 )
+        {
+            return getEmptyRawValue( attributeHierarchy.getAttribute() );
+        }
+        else if ( attributeHierarchy.size() == 1 && attributeHierarchy.getAttribute().getValueSize() == 1 )
+        {
+            return getRawValue( attributeHierarchy.getAttribute().getValues()[0] );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValueEditorName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getValueEditorName()
+    {
+        return name;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValueEditorImageDescriptor( ImageDescriptor imageDescriptor )
+    {
+        this.imageDescriptor = imageDescriptor;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ImageDescriptor getValueEditorImageDescriptor()
+    {
+        return imageDescriptor;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractDialogValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractInPlaceStringValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractInPlaceStringValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractInPlaceStringValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractInPlaceStringValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,298 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants;
+import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.TextCellEditor;
+
+
+/**
+ * 
+ * Abstract base class for value editors that handle string values
+ * withing the table or tree control. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractInPlaceStringValueEditor extends TextCellEditor implements IValueEditor
+{
+
+    /** The name of this value editor */
+    private String name;
+
+    /** The image of this value editor */
+    private ImageDescriptor imageDescriptor;
+
+
+    /**
+     * Creates a new instance of AbstractInPlaceStringValueEditor.
+     */
+    protected AbstractInPlaceStringValueEditor()
+    {
+        super();
+    }
+
+
+    /**
+     * Returns true if the user wishes to show raw values rather than
+     * user-friendly values. If true the getDisplayValue() methods 
+     * shouldnot modify the value.
+     *
+     * @return true if raw values should be displayed
+     */
+    protected boolean showRawValues()
+    {
+        return BrowserCommonActivator.getDefault().getPreferenceStore()
+            .getBoolean( BrowserCommonConstants.PREFERENCE_SHOW_RAW_VALUES );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation of getDisplayValue() returns a 
+     * comma-separated list of all values. 
+     */
+    public String getDisplayValue( AttributeHierarchy attributeHierarchy )
+    {
+        if ( attributeHierarchy == null )
+        {
+            return "NULL";
+        }
+
+        List<IValue> valueList = new ArrayList<IValue>();
+        for ( Iterator it = attributeHierarchy.iterator(); it.hasNext(); )
+        {
+            IAttribute attribute = ( IAttribute ) it.next();
+            valueList.addAll( Arrays.asList( attribute.getValues() ) );
+        }
+
+        StringBuffer sb = new StringBuffer();
+        for ( Iterator<IValue> it = valueList.iterator(); it.hasNext(); )
+        {
+            IValue value = it.next();
+            sb.append( getDisplayValue( value ) );
+            if ( it.hasNext() )
+                sb.append( ", " );
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation just returns the raw value
+     */
+    public String getDisplayValue( IValue value )
+    {
+        Object obj = this.getRawValue( value );
+        return obj == null ? "NULL" : obj.toString();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation returns IValue.EMPTY_xx_VALUE if there are no values
+     * in attributeHierarchy or calls getRawValue(IValue) if attributeHierarchy
+     * contains exactly one value. Otherwise null is returned.
+     */
+    public Object getRawValue( AttributeHierarchy attributeHierarchy )
+    {
+        if ( attributeHierarchy == null )
+        {
+            return null;
+        }
+        else if ( attributeHierarchy.size() == 1 && attributeHierarchy.getAttribute().getValueSize() == 0 )
+        {
+            if ( attributeHierarchy.getAttribute().isString() )
+            {
+                return IValue.EMPTY_STRING_VALUE;
+            }
+            else
+            {
+                return IValue.EMPTY_BINARY_VALUE;
+            }
+        }
+        else if ( attributeHierarchy.size() == 1 && attributeHierarchy.getAttribute().getValueSize() == 1 )
+        {
+            return getRawValue( attributeHierarchy.getAttribute().getValues()[0] );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation returns the string value 
+     * of the given value. 
+     */
+    public Object getRawValue( IValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        else if ( value.isString() )
+        {
+            return value.getStringValue();
+        }
+        else if ( value.isBinary() )
+        {
+            return isEditable( value.getBinaryValue() ) ? value.getStringValue() : null;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * Small helper.
+     */
+    private boolean isEditable( byte[] b )
+    {
+        if ( b == null )
+        {
+            return false;
+        }
+
+        for ( int i = 0; i < b.length; i++ )
+        {
+            if ( !( b[i] == '\n' || b[i] == '\r' || ( b[i] >= '\u0020' && b[i] <= '\u007F' ) ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation always return the string value
+     * as String.
+     */
+    public Object getStringOrBinaryValue( Object rawValue )
+    {
+        if ( rawValue == null )
+        {
+            return null;
+        }
+        else if ( rawValue instanceof String )
+        {
+            return rawValue;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public CellEditor getCellEditor()
+    {
+        return this;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected Object doGetValue()
+    {
+        return "".equals( text.getText() ) ? null : text.getText();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void doSetValue( Object value )
+    {
+        if ( value != null && value instanceof IValue.EmptyValue )
+        {
+            value = ( ( IValue.EmptyValue ) value ).getStringValue();
+        }
+        super.doSetValue( value );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValueEditorName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getValueEditorName()
+    {
+        return name;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValueEditorImageDescriptor( ImageDescriptor imageDescriptor )
+    {
+        this.imageDescriptor = imageDescriptor;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ImageDescriptor getValueEditorImageDescriptor()
+    {
+        return imageDescriptor;
+    }
+
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/AbstractInPlaceStringValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/HexValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/HexValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/HexValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/HexValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,62 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import org.apache.directory.studio.ldapbrowser.common.dialogs.HexDialog;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * The default editor for binary values. Uses the HexDialog.
+ * 
+ * The HexDialog is currently only able to save and load binary data
+ * to and from file. It is not possible to edit the data in the dialog
+ * directly.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class HexValueEditor extends AbstractDialogBinaryValueEditor
+{
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation opens the HexDialog.
+     */
+    protected boolean openDialog( Shell shell )
+    {
+        Object value = getValue();
+        if ( value != null && value instanceof byte[] )
+        {
+            byte[] initialData = ( byte[] ) value;
+            HexDialog dialog = new HexDialog( shell, initialData );
+            if ( dialog.open() == HexDialog.OK && dialog.getData() != null )
+            {
+                setValue( dialog.getData() );
+                return true;
+            }
+        }
+        return false;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/HexValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/IValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/IValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/IValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/IValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,189 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * A ValueEditor knows how to display and edit values of a LDAP attribute.
+ * ValueEditors are used from the entry editor or search result editor 
+ * to display and edit values in a user-friendly way.  
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface IValueEditor
+{
+
+    /**
+     * Returns the string representation of the given attribute hierarchy 
+     * presented to the user.
+     * <p>
+     * This method is called from the search result editor. A attribute hierarchy may
+     * contain multiple attributes each with multiple values. It is common that
+     * a ValueEditor returns a comma-separated list.
+     * 
+     * @param attributeHierarchy the attribute hierarchy
+     * @return the string representation of the attribute hierarchy
+     */
+    public abstract String getDisplayValue( AttributeHierarchy attributeHierarchy );
+
+
+    /**
+     * Returns the string representation of the given value 
+     * presented to the user.
+     * <p>
+     * This method is called from the entry editor.
+     * 
+     * @param value the value
+     * @return the string representation of the value
+     */
+    public abstract String getDisplayValue( IValue value );
+
+
+    /**
+     * Returns the raw value if this value editor can handle the given 
+     * attribute hierarchy. The returned value is used as input for 
+     * the CellEditor returned by getCellEditor().
+     * <p>
+     * If this value editor can't handle the given attribute hierarchy
+     * it must return null. 
+     * <p>
+     * Note: It is also possilbe that the attribute hierarchy doesn't contain
+     * a value. This means the value is up to be created.
+     * <p>
+     * This method is called from the search result editor. It is common
+     * to return null if the attribute hierarchy contains more than 
+     * one value.
+     * 
+     * @param attributeHierarchy the attribute hierarchy
+     * @return the raw value of the attribute hierarchy or null
+     */
+    public abstract Object getRawValue( AttributeHierarchy attributeHierarchy );
+
+
+    /**
+     * Returns the raw value if this value editor can handle the given 
+     * value. The returned value is used as input for the CellEditor 
+     * returned by getCellEditor().
+     * <p>
+     * If this value editor can't handle the given value it must 
+     * return null. 
+     * <p>
+     * Note: It is also possible that the value is empty!
+     * <p>
+     * This method is called from the entry editor. 
+     * 
+     * @param value the value
+     * @return the raw value of the value or null
+     */
+    public abstract Object getRawValue( IValue value );
+
+
+    /**
+     * Returns the String or binary byte[] value of the given raw value. 
+     * The return value is used to create,  modify or delete the value
+     * in directory.
+     * <p>
+     * This method is called after editing has been finished. The 
+     * given rawValue is the one returned by the CellEditor. 
+     * 
+     * @param rawValue the raw value return from cell editor
+     * @return the String or byte[] value
+     */
+    public abstract Object getStringOrBinaryValue( Object rawValue );
+
+
+    /**
+     * Returns the editors name, previously set with
+     * setValueEditorName().
+     * 
+     * @return the editors name
+     */
+    public abstract String getValueEditorName();
+
+
+    /**
+     * Sets the editors name. 
+     * 
+     * This method is called during initialization of the 
+     * value editor, the name specified in value editor
+     * extension is assigned. 
+     *
+     * @param name the editors name
+     */
+    public abstract void setValueEditorName( String name );
+
+
+    /**
+     * Returns the editors image, previously set with
+     * setValueEditorImageDescriptor().
+     * 
+     * @return the editors image
+     */
+    public abstract ImageDescriptor getValueEditorImageDescriptor();
+
+
+    /**
+     * Sets the editors image.
+     * 
+     * This method is called during initialization of the 
+     * value editor, the icon specified in value editor
+     * extension is assigned. 
+     *
+     * @param imageDescriptor the editors image
+     */
+    public abstract void setValueEditorImageDescriptor( ImageDescriptor imageDescriptor );
+
+
+    /**
+     * Creates the control for this value editor under the given parent control.
+     * 
+     * @param parent the parent control
+     */
+    public abstract void create( Composite parent );
+
+
+    /**
+     * Disposes of this value editor and frees any associated SWT resources.
+     */
+    public abstract void dispose();
+
+
+    /**
+     * Returns the JFace CellEditor that is able to handle values returned by
+     * one of the getRawValue() or the getEmptyRawValue() methods.
+     * 
+     * The object returned by the CellEditor's getValue() method is
+     * then sent to the getStringOrBinary() method to get the 
+     * directory value.
+     * 
+     * @return the JFace CellEditor
+     * 
+     */
+    public abstract CellEditor getCellEditor();
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/IValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/InPlaceTextValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/InPlaceTextValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/InPlaceTextValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/InPlaceTextValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,35 @@
+/*
+ *  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.studio.valueeditors;
+
+
+
+
+/**
+ * The default editor for string values.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class InPlaceTextValueEditor extends AbstractInPlaceStringValueEditor
+{
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/InPlaceTextValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/MultivaluedValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/MultivaluedValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/MultivaluedValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/MultivaluedValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,268 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.studio.ldapbrowser.common.dialogs.MultivaluedDialog;
+import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+
+/**
+ * Special ValueEditor to handle attributes with multiple values in a dialog.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MultivaluedValueEditor extends CellEditor implements IValueEditor
+{
+
+    /** The value to handle */
+    private Object value;
+
+    /** The parent composite, used to instanciate a new control */
+    private Composite parent;
+
+    /** The name of this value editor */
+    private String name;
+
+    /** The image of this value editor */
+    private ImageDescriptor imageDescriptor;
+
+    /** The value editor manager, used to get proper value editors */
+    protected ValueEditorManager valueEditorManager;
+
+
+    /**
+     * Creates a new instance of MultivaluedValueEditor.
+     *
+     * @param parent the parent composite
+     * @param valueEditorManager the value editor manager, used to get
+     *                           proper value editors
+     */
+    public MultivaluedValueEditor( Composite parent, ValueEditorManager valueEditorManager )
+    {
+        super( parent );
+        this.parent = parent;
+        this.valueEditorManager = valueEditorManager;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This is a dialog editor, it doesn't create a control. 
+     */
+    protected Control createControl( Composite parent )
+    {
+        return null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Returns the value object stored in a member.
+     */
+    protected final Object doGetValue()
+    {
+        return this.value;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This is a dialog editor, doesn't set focus. 
+     */
+    protected void doSetFocus()
+    {
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Stores the value object in a member.
+     */
+    protected void doSetValue( Object value )
+    {
+        this.value = value;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Opens the MulitvaluedDialog. Expects that an AttributeHierarchy
+     * object is in value member. 
+     */
+    public void activate()
+    {
+        if ( this.getValue() != null && this.getValue() instanceof AttributeHierarchy )
+        {
+            AttributeHierarchy ah = ( AttributeHierarchy ) this.getValue();
+            if ( ah != null )
+            {
+                MultivaluedDialog dialog = new MultivaluedDialog( this.parent.getShell(), ah );
+                dialog.open();
+            }
+        }
+
+        fireCancelEditor();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Returns this.
+     */
+    public CellEditor getCellEditor()
+    {
+        return this;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation of getDisplayValue() returns a 
+     * comma-separated list of all values. 
+     */
+    public String getDisplayValue( AttributeHierarchy attributeHierarchy )
+    {
+
+        List<IValue> valueList = new ArrayList<IValue>();
+        for ( Iterator it = attributeHierarchy.iterator(); it.hasNext(); )
+        {
+            IAttribute attribute = ( IAttribute ) it.next();
+            valueList.addAll( Arrays.asList( attribute.getValues() ) );
+        }
+
+        StringBuffer sb = new StringBuffer();
+        if ( valueList.size() > 1 )
+            sb.append( valueList.size() + " values: " );
+        for ( Iterator it = valueList.iterator(); it.hasNext(); )
+        {
+            IValue value = ( IValue ) it.next();
+            IValueEditor vp = this.valueEditorManager.getCurrentValueEditor( value );
+            sb.append( vp.getDisplayValue( value ) );
+            if ( it.hasNext() )
+                sb.append( ", " );
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * It doesn't make sense to use the MultivaluedValueEditor with a single value.
+     * Returns an empty string.
+     */
+    public String getDisplayValue( IValue value )
+    {
+        return "";
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Returns the attributeHierarchy.
+     */
+    public Object getRawValue( AttributeHierarchy attributeHierarchy )
+    {
+        return attributeHierarchy;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * It doesn't make sense to use the MultivaluedValueEditor with a single value.
+     * Returns null.
+     */
+    public Object getRawValue( IValue value )
+    {
+        return null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * Modification is performed in the concrete single-ValueEditors. No need 
+     * to return a value.
+     */
+    public Object getStringOrBinaryValue( Object rawValue )
+    {
+        return null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValueEditorName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getValueEditorName()
+    {
+        return name;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValueEditorImageDescriptor( ImageDescriptor imageDescriptor )
+    {
+        this.imageDescriptor = imageDescriptor;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ImageDescriptor getValueEditorImageDescriptor()
+    {
+        return imageDescriptor;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/MultivaluedValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/TextValueEditor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/TextValueEditor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/TextValueEditor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/TextValueEditor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,57 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import org.apache.directory.studio.ldapbrowser.common.dialogs.TextDialog;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * The default editor for string values.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class TextValueEditor extends AbstractDialogStringValueEditor
+{
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation opens the TextDialog.
+     */
+    public boolean openDialog( Shell shell )
+    {
+        Object value = getValue();
+        if ( value != null && value instanceof String )
+        {
+            TextDialog dialog = new TextDialog( shell, ( String ) value );
+            if ( dialog.open() == TextDialog.OK && !"".equals( dialog.getText() ) )
+            {
+                setValue( dialog.getText() );
+                return true;
+            }
+        }
+        return false;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/TextValueEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/ValueEditorManager.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/ValueEditorManager.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/ValueEditorManager.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/ValueEditorManager.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,754 @@
+/*
+ *  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.studio.valueeditors;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.jobs.CreateValuesJob;
+import org.apache.directory.studio.ldapbrowser.core.jobs.DeleteAttributesValueJob;
+import org.apache.directory.studio.ldapbrowser.core.jobs.ModifyValueJob;
+import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Attribute;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.AttributeTypeDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.LdapSyntaxDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+import org.apache.directory.studio.ldapbrowser.core.utils.LdifUtils;
+import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+/**
+ * A ValueEditorManager is used to manage value editors. It provides methods to get
+ * the best or alternative value editors for a given attribute or value. It takes
+ * user preferences into account when determine the best value editor. At least
+ * it provides default text and binary value editors. 
+ * 
+ * The available value editors are specified by the extension point
+ * <code>org.apache.directory.studio.valueeditors</code>. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ValueEditorManager
+{
+    /** The extension point ID for value editors */
+    private static final String EXTENSION_POINT = "org.apache.directory.studio.valueeditors";
+
+    /** The composite used to create the value editors **/
+    private Composite parent;
+
+    /** 
+     * The value editor explicitly selected by the user. If this
+     * member is not null it is always returned as current value editor.
+     */
+    private IValueEditor userSelectedValueEditor;
+
+    /** The special value editor for multi-valued attributes */
+    private MultivaluedValueEditor multiValuedValueEditor;
+
+    /** The default string editor for single-line values */
+    private IValueEditor defaultStringSingleLineValueEditor;
+
+    /** The default string editor for multi-line values */
+    private IValueEditor defaultStringMultiLineValueEditor;
+
+    /** The default binary editor */
+    private IValueEditor defaultBinaryValueEditor;
+
+    /** A Map wich all available value editors. */
+    private Map<String, IValueEditor> class2ValueEditors;
+
+
+    /**
+     * Creates a new instance of ValueEditorManager.
+     *
+     * @param parent the composite used to create the value editors
+     */
+    public ValueEditorManager( Composite parent )
+    {
+        this.parent = parent;
+        userSelectedValueEditor = null;
+
+        // init value editor map
+        class2ValueEditors = new HashMap<String, IValueEditor>();
+        Collection<IValueEditor> valueEditors = createValueEditors( parent );
+        for ( IValueEditor valueEditor : valueEditors )
+        {
+            class2ValueEditors.put( valueEditor.getClass().getName(), valueEditor );
+        }
+
+        // special case: multivalued editor
+        multiValuedValueEditor = new MultivaluedValueEditor( this.parent, this );
+        multiValuedValueEditor.setValueEditorName( "Mulitvalued Editor" );
+        multiValuedValueEditor.setValueEditorImageDescriptor( BrowserCommonActivator.getDefault().getImageDescriptor(
+            BrowserCommonConstants.IMG_MULTIVALUEDEDITOR ) );
+
+        // get default editors from value editor map
+        defaultStringSingleLineValueEditor = class2ValueEditors.get( InPlaceTextValueEditor.class.getName() );
+        defaultStringMultiLineValueEditor = class2ValueEditors.get( TextValueEditor.class.getName() );
+        defaultBinaryValueEditor = class2ValueEditors.get( HexValueEditor.class.getName() );
+    }
+
+
+    /**
+     * Disposes all value editors.
+     */
+    public void dispose()
+    {
+        if ( this.parent != null )
+        {
+            this.userSelectedValueEditor = null;
+            this.multiValuedValueEditor.dispose();
+            this.defaultStringSingleLineValueEditor.dispose();
+            this.defaultStringMultiLineValueEditor.dispose();
+            this.defaultBinaryValueEditor.dispose();
+
+            for ( IValueEditor ve : class2ValueEditors.values() )
+            {
+                ve.dispose();
+            }
+
+            this.parent = null;
+        }
+    }
+
+
+    /**
+     * Sets the value editor explicitly selected by the user. Set 
+     * userSelectedValueEditor to null to remove the selection.
+     *
+     * @param userSelectedValueEditor the user selected value editor, may be null.
+     */
+    public void setUserSelectedValueEditor( IValueEditor userSelectedValueEditor )
+    {
+        this.userSelectedValueEditor = userSelectedValueEditor;
+    }
+
+
+    /**
+     * Returns the current (best) value editor for the given attribute.
+     * 
+     * <ol>
+     *  <li>If a user selected value editor is selected, this is returned.
+     *  <li>If a specific value editor is defined for the attribute type this 
+     *      value editor is returned. See preferences. 
+     *  <li>If a specific value editor is defined for the attribute's syntax this 
+     *      value editor is returned. See preferences. 
+     *  <li>Otherwise a default value editor is returned. If the attribute is 
+     *      binary the default Hex Editor is returned. Otherwise the default 
+     *      Text Editor is returned.
+     * </ol>
+     *
+     * @param schema the schema
+     * @param attributeType the attribute type
+     * @return the current value editor
+     */
+    public IValueEditor getCurrentValueEditor( Schema schema, String attributeType )
+    {
+
+        // check user-selected (forced) value editor
+        if ( this.userSelectedValueEditor != null )
+        {
+            return this.userSelectedValueEditor;
+        }
+
+        // check attribute preferences
+        AttributeTypeDescription atd = schema.getAttributeTypeDescription( attributeType );
+        Map attributeValueEditorMap = BrowserCommonActivator.getDefault().getValueEditorsPreferences()
+            .getAttributeValueEditorMap();
+        if ( atd.getNumericOID() != null && attributeValueEditorMap.containsKey( atd.getNumericOID().toLowerCase() ) )
+        {
+            return ( IValueEditor ) this.class2ValueEditors.get( attributeValueEditorMap.get( atd.getNumericOID()
+                .toLowerCase() ) );
+        }
+        String[] names = atd.getNames();
+        for ( int i = 0; i < names.length; i++ )
+        {
+            if ( attributeValueEditorMap.containsKey( names[i].toLowerCase() ) )
+            {
+                return ( IValueEditor ) this.class2ValueEditors.get( attributeValueEditorMap.get( names[i]
+                    .toLowerCase() ) );
+            }
+        }
+
+        // check syntax preferences
+        LdapSyntaxDescription lsd = atd.getSyntaxDescription();
+        Map syntaxValueEditorMap = BrowserCommonActivator.getDefault().getValueEditorsPreferences()
+            .getSyntaxValueEditorMap();
+        if ( lsd.getNumericOID() != null && syntaxValueEditorMap.containsKey( lsd.getNumericOID().toLowerCase() ) )
+        {
+            return ( IValueEditor ) this.class2ValueEditors.get( syntaxValueEditorMap.get( lsd.getNumericOID()
+                .toLowerCase() ) );
+        }
+
+        // return default
+        if ( lsd.isBinary() )
+        {
+            return this.defaultBinaryValueEditor;
+        }
+        else
+        {
+            return this.defaultStringSingleLineValueEditor;
+        }
+
+    }
+
+
+    /**
+     * Returns the current (best) value editor for the given attribute.
+     * 
+     * @param entry the entry
+     * @param attributeType the attributge type
+     * @return the current value editor
+     * @see #getCurrentValueEditor( Schema, String )
+     */
+    public IValueEditor getCurrentValueEditor( IEntry entry, String attributeType )
+    {
+        return getCurrentValueEditor( entry.getBrowserConnection().getSchema(), attributeType );
+    }
+
+
+    /**
+     * Returns the current (best) value editor for the given value.
+     * 
+     * @param value the value
+     * @return the current value editor
+     * @see #getCurrentValueEditor( Schema, String )
+     */
+    public IValueEditor getCurrentValueEditor( IValue value )
+    {
+
+        IValueEditor ve = this.getCurrentValueEditor( value.getAttribute().getEntry(), value.getAttribute()
+            .getDescription() );
+
+        // here the value is known, we can check for single-line or multi-line
+        if ( ve == this.defaultStringSingleLineValueEditor )
+        {
+            if ( value.getStringValue().indexOf( '\n' ) == -1 && value.getStringValue().indexOf( '\r' ) == -1 )
+            {
+                ve = this.defaultStringSingleLineValueEditor;
+            }
+            else
+            {
+                ve = this.defaultStringMultiLineValueEditor;
+            }
+        }
+
+        return ve;
+    }
+
+
+    /**
+     * Returns the current (best) value editor for the given attribute.
+     * 
+     * @param attributeHierarchy the attribute hierarchy
+     * @return the current value editor
+     * @see #getCurrentValueEditor( Schema, String )
+     */
+    public IValueEditor getCurrentValueEditor( AttributeHierarchy attributeHierarchy )
+    {
+        if ( attributeHierarchy == null )
+        {
+            return null;
+        }
+        else if ( attributeHierarchy.size() == 1 && attributeHierarchy.getAttribute().getValueSize() == 0 )
+        {
+            return this.getCurrentValueEditor( attributeHierarchy.getAttribute().getEntry(), attributeHierarchy
+                .getAttribute().getDescription() );
+        }
+        else if ( attributeHierarchy.size() == 1
+            && attributeHierarchy.getAttribute().getValueSize() == 1
+            && attributeHierarchy.getAttributeDescription().equalsIgnoreCase(
+                attributeHierarchy.getAttribute().getValues()[0].getAttribute().getDescription() ) )
+        {
+            // special case objectClass and RDN: always return MV-editor
+            // perhaps this should be moved somewhere else
+            if ( attributeHierarchy.getAttribute().isObjectClassAttribute() )
+            {
+                return this.multiValuedValueEditor;
+            }
+            if ( attributeHierarchy.getAttribute().getValues()[0].isRdnPart() )
+            {
+                return this.multiValuedValueEditor;
+            }
+
+            return this.getCurrentValueEditor( attributeHierarchy.getAttribute().getValues()[0] );
+        }
+        else
+        {
+            return this.multiValuedValueEditor;
+        }
+    }
+
+
+    /**
+     * Returns alternative value editors for the given attribute. For now these
+     * are the three default editors.
+     *
+     * @param entry the entry
+     * @param attributeName the attribute
+     * @return alternative value editors
+     */
+    public IValueEditor[] getAlternativeValueEditors( IEntry entry, String attributeName )
+    {
+        Schema schema = entry.getBrowserConnection().getSchema();
+        return getAlternativeValueEditors( schema, attributeName );
+    }
+
+
+    /**
+     * Returns alternative value editors for the given attribute. For now these
+     * are the three default editors.
+     * 
+     * @param schema the schema
+     * @param attributeName the attribute
+     * @return alternative value editors
+     */
+    public IValueEditor[] getAlternativeValueEditors( Schema schema, String attributeName )
+    {
+        List<IValueEditor> alternativeList = new ArrayList<IValueEditor>();
+
+        AttributeTypeDescription atd = schema.getAttributeTypeDescription( attributeName );
+
+        if ( atd.getSyntaxDescription().isBinary() )
+        {
+            alternativeList.add( this.defaultBinaryValueEditor );
+            alternativeList.add( this.defaultStringSingleLineValueEditor );
+            alternativeList.add( this.defaultStringMultiLineValueEditor );
+        }
+        else if ( atd.getSyntaxDescription().isString() )
+        {
+            alternativeList.add( this.defaultStringSingleLineValueEditor );
+            alternativeList.add( this.defaultStringMultiLineValueEditor );
+            alternativeList.add( this.defaultBinaryValueEditor );
+        }
+
+        alternativeList.add( this.multiValuedValueEditor );
+
+        alternativeList.remove( getCurrentValueEditor( schema, attributeName ) );
+
+        return ( org.apache.directory.studio.valueeditors.IValueEditor[] ) alternativeList
+            .toArray( new IValueEditor[alternativeList.size()] );
+    }
+
+
+    /**
+     * Returns alternative value editors for the given value. For now these
+     * are the three default editors.
+     *
+     * @param value the value
+     * @return lternative value editors
+     */
+    public IValueEditor[] getAlternativeValueEditors( IValue value )
+    {
+        List<IValueEditor> alternativeList = new ArrayList<IValueEditor>();
+
+        if ( value.isBinary() )
+        {
+            alternativeList.add( this.defaultBinaryValueEditor );
+            alternativeList.add( this.defaultStringSingleLineValueEditor );
+            alternativeList.add( this.defaultStringMultiLineValueEditor );
+        }
+        else if ( value.isString() )
+        {
+            alternativeList.add( this.defaultStringSingleLineValueEditor );
+            alternativeList.add( this.defaultStringMultiLineValueEditor );
+            alternativeList.add( this.defaultBinaryValueEditor );
+        }
+
+        alternativeList.add( this.multiValuedValueEditor );
+
+        alternativeList.remove( getCurrentValueEditor( value ) );
+
+        return ( org.apache.directory.studio.valueeditors.IValueEditor[] ) alternativeList
+            .toArray( new IValueEditor[alternativeList.size()] );
+    }
+
+
+    /**
+     * Returns alternative value editors for the given value. For now these
+     * are the three default editors.
+     * 
+     * @param ah the attribute hierarchy
+     * @return alternative value editors
+     */
+    public IValueEditor[] getAlternativeValueEditors( AttributeHierarchy ah )
+    {
+        if ( ah == null )
+        {
+            return new IValueEditor[0];
+        }
+        else if ( ah.size() == 1 && ah.getAttribute().getValueSize() == 0 )
+        {
+            return this.getAlternativeValueEditors( ah.getAttribute().getEntry(), ah.getAttribute().getDescription() );
+        }
+        else if ( ah.size() == 1
+            && ah.getAttribute().getValueSize() == 1
+            && ah.getAttributeDescription().equalsIgnoreCase(
+                ah.getAttribute().getValues()[0].getAttribute().getDescription() ) )
+        {
+
+            // special case objectClass and RDN: no alternative to the MV-Editor
+            // perhaps this should be moved somewhere else
+            if ( ah.getAttribute().isObjectClassAttribute() )
+            {
+                return new IValueEditor[0];
+            }
+            if ( ah.getAttribute().getValues()[0].isRdnPart() )
+            {
+                return new IValueEditor[0];
+            }
+
+            return this.getAlternativeValueEditors( ah.getAttribute().getValues()[0] );
+        }
+        else
+        /* if(attribute.getValueSize() > 1) */{
+            return new IValueEditor[0];
+        }
+    }
+
+
+    /**
+     * Returns all available value editors.
+     *
+     * @return all available value editors
+     */
+    public IValueEditor[] getAllValueEditors()
+    {
+        // use a set to avoid double entries
+        Set<IValueEditor> list = new LinkedHashSet<IValueEditor>();
+
+        list.add( this.defaultStringSingleLineValueEditor );
+        list.add( this.defaultStringMultiLineValueEditor );
+        list.add( defaultBinaryValueEditor );
+
+        list.addAll( this.class2ValueEditors.values() );
+
+        list.add( this.multiValuedValueEditor );
+
+        return list.toArray( new IValueEditor[list.size()] );
+    }
+
+
+    /**
+     * Returns the default binary editor (a HexEditor).
+     *
+     * @return the default binary editor
+     */
+    public IValueEditor getDefaultBinaryValueEditor()
+    {
+        return defaultBinaryValueEditor;
+    }
+
+
+    /**
+     * Returns the default string editor (a TextEditor).
+     *
+     * @return the default string editor
+     */
+    public IValueEditor getDefaultStringValueEditor()
+    {
+        return defaultStringMultiLineValueEditor;
+    }
+
+
+    /**
+     * Returns the multi-valued editor.
+     *
+     * @return the multi-valued editor
+     */
+    public MultivaluedValueEditor getMultiValuedValueEditor()
+    {
+        return multiValuedValueEditor;
+    }
+
+
+    /**
+     * Creates the attribute with the given value at the entry.
+     * 
+     * It is called from a ICellModifier if no attribute of value exists and
+     * the raw value returned by the CellEditor isn't null.
+     * 
+     * @param newRawValue the new raw value
+     * @param entry the entry
+     * @param attributeDescription the attribute description
+     * 
+     * @throws ModelModificationException the model modification exception
+     */
+    public void createValue( IEntry entry, String attributeDescription, Object newRawValue )
+    {
+        if ( entry != null && attributeDescription != null && newRawValue != null
+            && ( newRawValue instanceof byte[] || newRawValue instanceof String ) )
+        {
+            if ( entry.getAttribute( attributeDescription ) != null )
+            {
+                IAttribute attribute = entry.getAttribute( attributeDescription );
+                if ( attribute != null )
+                {
+                    if ( attribute.getValueSize() == 0 )
+                    {
+                        new CreateValuesJob( attribute, newRawValue ).execute();
+                    }
+                    else if ( attribute.getValueSize() == 1 )
+                    {
+                        this.modifyValue( attribute.getValues()[0], newRawValue );
+                    }
+                }
+            }
+            else
+            {
+                EventRegistry.suspendEventFireingInCurrentThread();
+                IAttribute attribute = new Attribute( entry, attributeDescription );
+                entry.addAttribute( attribute );
+                EventRegistry.resumeEventFireingInCurrentThread();
+
+                Object newValue;
+                if ( entry.getBrowserConnection().getSchema().getAttributeTypeDescription( attributeDescription )
+                    .getSyntaxDescription().isString() )
+                {
+                    if ( newRawValue instanceof String )
+                    {
+                        newValue = ( String ) newRawValue;
+                    }
+                    else
+                    {
+                        newValue = LdifUtils.utf8decode( ( byte[] ) newRawValue );
+                    }
+                }
+                else
+                {
+                    if ( newRawValue instanceof String )
+                    {
+                        newValue = LdifUtils.utf8encode( ( String ) newRawValue );
+                    }
+                    else
+                    {
+                        newValue = ( byte[] ) newRawValue;
+                    }
+                }
+
+                new CreateValuesJob( attribute, newValue ).execute();
+            }
+        }
+    }
+
+
+    /**
+     * Modifies the value and sets the given raw value
+     * 
+     * It is called from a ICellModfier if the value exists and the raw
+     * value returned by the CellEditor isn't null.
+     * 
+     * @param oldValue the old value
+     * @param newRawValue the new raw value
+     */
+    public void modifyValue( IValue oldValue, Object newRawValue )
+    {
+        IAttribute attribute = oldValue.getAttribute();
+
+        boolean modify = false;
+        if ( oldValue != null && newRawValue != null && newRawValue instanceof byte[] )
+        {
+            byte[] newValue = ( byte[] ) newRawValue;
+            if ( !Utils.equals( oldValue.getBinaryValue(), newValue ) )
+            {
+                modify = true;
+            }
+        }
+        else if ( oldValue != null && newRawValue != null && newRawValue instanceof String )
+        {
+
+            String newValue = ( String ) newRawValue;
+            if ( !oldValue.getStringValue().equals( newValue ) )
+            {
+                modify = true;
+            }
+        }
+
+        if ( modify )
+        {
+            if ( oldValue.isEmpty() )
+            {
+                EventRegistry.suspendEventFireingInCurrentThread();
+                attribute.deleteEmptyValue();
+                EventRegistry.resumeEventFireingInCurrentThread();
+                new CreateValuesJob( attribute, newRawValue ).execute();
+            }
+            else
+            {
+                new ModifyValueJob( oldValue, newRawValue ).execute();
+            }
+        }
+    }
+
+
+    /**
+     * Deletes the attributes.
+     * 
+     * It is called from a ICellModfier if the attribute exists and the raw
+     * value returned by the CellEditor is null.
+     * 
+     * @param ah the attribute hierarchy
+     */
+    public void deleteAttribute( AttributeHierarchy ah )
+    {
+        new DeleteAttributesValueJob( ah ).execute();
+    }
+
+
+    /**
+     * Creates and returns the value editors specified by value editors extensions.
+     *
+     * @param parent the parent composite
+     * @return the value editors
+     */
+    private Collection<IValueEditor> createValueEditors( Composite parent )
+    {
+        Collection<IValueEditor> valueEditors = new ArrayList<IValueEditor>();
+
+        Collection<ValueEditorExtension> valueEditorProxys = getValueEditorProxys();
+        for ( ValueEditorExtension proxy : valueEditorProxys )
+        {
+            try
+            {
+                IValueEditor valueEditor = ( IValueEditor ) proxy.member.createExecutableExtension( "class" );
+                valueEditor.create( parent );
+                valueEditor.setValueEditorName( proxy.name );
+                valueEditor.setValueEditorImageDescriptor( proxy.icon );
+                valueEditors.add( valueEditor );
+            }
+            catch ( Exception e )
+            {
+                BrowserCommonActivator.getDefault().getLog().log(
+                    new Status( IStatus.ERROR, BrowserCommonActivator.PLUGIN_ID, 1, "Unable to create ValueEditor "
+                        + proxy.className, e ) );
+            }
+        }
+
+        return valueEditors;
+    }
+
+
+    /**
+     * Returns all value editor proxies specified by value editor extensions.
+     *
+     * @return the value editor proxies
+     */
+    public static Collection<ValueEditorExtension> getValueEditorProxys()
+    {
+        Collection<ValueEditorExtension> valueEditorProxies = new ArrayList<ValueEditorExtension>();
+
+        IExtensionRegistry registry = Platform.getExtensionRegistry();
+        IExtensionPoint extensionPoint = registry.getExtensionPoint( EXTENSION_POINT );
+        IConfigurationElement[] members = extensionPoint.getConfigurationElements();
+
+        // For each extension:
+        for ( int m = 0; m < members.length; m++ )
+        {
+            ValueEditorExtension proxy = new ValueEditorExtension();
+            valueEditorProxies.add( proxy );
+
+            IConfigurationElement member = members[m];
+            IExtension extension = member.getDeclaringExtension();
+            String extendingPluginId = extension.getNamespaceIdentifier();
+
+            proxy.member = member;
+            proxy.name = member.getAttribute( "name" );
+            String iconPath = member.getAttribute( "icon" );
+            proxy.icon = AbstractUIPlugin.imageDescriptorFromPlugin( extendingPluginId, iconPath );
+            if ( proxy.icon == null )
+            {
+                proxy.icon = ImageDescriptor.getMissingImageDescriptor();
+            }
+            proxy.className = member.getAttribute( "class" );
+
+            IConfigurationElement[] children = member.getChildren();
+            for ( int c = 0; c < children.length; c++ )
+            {
+                IConfigurationElement element = children[c];
+                String type = element.getName();
+                if ( "syntax".equals( type ) )
+                {
+                    String syntaxOID = element.getAttribute( "syntaxOID" );
+                    proxy.syntaxOids.add( syntaxOID );
+                }
+                else if ( "attribute".equals( type ) )
+                {
+                    String attributeType = element.getAttribute( "attributeType" );
+                    proxy.attributeTypes.add( attributeType );
+                }
+            }
+        }
+
+        return valueEditorProxies;
+    }
+
+    /**
+     * This class is a bean to hold the data defined in value editor extension 
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    public static class ValueEditorExtension
+    {
+
+        /** The name. */
+        public String name = null;
+
+        /** The icon. */
+        public ImageDescriptor icon = null;
+
+        /** The class name. */
+        public String className = null;
+
+        /** The syntax oids. */
+        public Collection<String> syntaxOids = new ArrayList<String>( 3 );
+
+        /** The attribute types. */
+        public Collection<String> attributeTypes = new ArrayList<String>( 3 );
+
+        /** The configuration element. */
+        private IConfigurationElement member = null;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/valueeditors/ValueEditorManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/atd.png
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/atd.png?rev=592079&view=auto
==============================================================================
Binary file - no diff available.

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/atd.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/attribute_add.gif
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/attribute_add.gif?rev=592079&view=auto
==============================================================================
Binary file - no diff available.

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/attribute_add.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/bookmark.gif
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/resources/resources/icons/bookmark.gif?rev=592079&view=auto
==============================================================================
Binary file - no diff available.