Package org.apache.directory.studio.ldapbrowser.common.widgets

Source Code of org.apache.directory.studio.ldapbrowser.common.widgets.ModWidget$ValueLine

/*
*  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.widgets;


import java.util.ArrayList;
import java.util.Arrays;

import org.apache.directory.studio.ldapbrowser.core.BrowserCoreConstants;
import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.DecoratedField;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.fieldassist.IControlCreator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;


/**
* The ModWidget provides input elements to define an LDAP modify
* operation.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
public class ModWidget extends BrowserWidget implements ModifyListener
{

    /** The schema with the possible attribute types */
    private Schema schema;

    /** The shell */
    private Shell shell;

    /** The composite that contains the ModSpecs */
    private Composite modComposite;

    /** The list of ModSpecs */
    private ArrayList<ModSpec> modSpecList;

    /** The resulting LDIF */
    private String ldif;


    /**
     * Creates a new instance of ModWidget.
     *
     * @param schema the schema with the possible attribute types
     */
    public ModWidget( Schema schema )
    {
        this.schema = schema;
        this.modSpecList = new ArrayList<ModSpec>();
        this.ldif = null;
    }


    /**
     * Disposes this widget.
     */
    public void dispose()
    {
    }


    /**
     * Gets the ldif.
     *
     * @return the ldif
     */
    public String getLdif()
    {
        return ldif;
    }


    /**
     * Creates the contents.
     *
     * @param parent the parent composite
     *
     * @return the created composite
     */
    public Composite createContents( Composite parent )
    {
        shell = parent.getShell();

        modComposite = BaseWidgetUtils.createColumnContainer( parent, 3, 1 );
        addModSpec( modComposite, 0 );

        return modComposite;
    }


    /**
     * {@inheritDoc}
     */
    public void modifyText( ModifyEvent e )
    {
        validate();
    }


    /**
     * Validates the input elements.
     */
    public void validate()
    {
        for ( int i = 0; i < modSpecList.size(); i++ )
        {
            ModSpec modSpec = ( ModSpec ) modSpecList.get( i );
            if ( modSpecList.size() > 1 )
            {
                modSpec.modDeleteButton.setEnabled( true );
            }
            else
            {
                modSpec.modDeleteButton.setEnabled( false );
            }
            for ( int k = 0; k < modSpec.valueLineList.size(); k++ )
            {
                ValueLine valueLine = ( ValueLine ) modSpec.valueLineList.get( k );
                if ( modSpec.valueLineList.size() > 1 )
                {
                    valueLine.valueDeleteButton.setEnabled( true );
                }
                else
                {
                    valueLine.valueDeleteButton.setEnabled( false );
                }
            }
        }

        notifyListeners();
    }


    /**
     * Adds a modification spec at the given index.
     *
     * @param modComposite the composite
     * @param index the index
     */
    private void addModSpec( Composite modComposite, int index )
    {

        ModSpec[] modSpecs = ( ModSpec[] ) modSpecList.toArray( new ModSpec[modSpecList.size()] );

        if ( modSpecs.length > 0 )
        {
            for ( int i = 0; i < modSpecs.length; i++ )
            {
                ModSpec oldModSpec = modSpecs[i];

                // remember values
                String oldType = oldModSpec.modType.getText();
                String oldAttribute = oldModSpec.modAttributeCombo.getText();
                String[] oldValues = new String[oldModSpec.valueLineList.size()];
                for ( int k = 0; k < oldValues.length; k++ )
                {
                    oldValues[k] = ( ( ValueLine ) oldModSpec.valueLineList.get( k ) ).valueText.getText();
                }

                // delete old
                oldModSpec.modGroup.dispose();
                oldModSpec.modAddButton.dispose();
                oldModSpec.modDeleteButton.dispose();
                modSpecList.remove( oldModSpec );

                // add new
                ModSpec newModSpec = createModSpec( modComposite );
                modSpecList.add( newModSpec );

                // restore values
                newModSpec.modType.setText( oldType );
                newModSpec.modAttributeCombo.setText( oldAttribute );
                deleteValueLine( newModSpec, 0 );
                for ( int k = 0; k < oldValues.length; k++ )
                {
                    addValueLine( newModSpec, k );
                    ValueLine newValueLine = ( ValueLine ) newModSpec.valueLineList.get( k );
                    newValueLine.valueText.setText( oldValues[k] );
                }

                // check
                if ( index == i + 1 )
                {
                    ModSpec modSpec = createModSpec( modComposite );
                    modSpecList.add( modSpec );
                }
            }
        }
        else
        {
            ModSpec modSpec = createModSpec( modComposite );
            modSpecList.add( modSpec );
        }

        shell.layout( true, true );
    }


    /**
     * Creates and returns a modification spec.
     *
     * @param modComposite the composite
     *
     * @return the created modification spec
     */
    private ModSpec createModSpec( final Composite modComposite )
    {
        final ModSpec modSpec = new ModSpec();

        modSpec.modGroup = BaseWidgetUtils.createGroup( modComposite, "", 1 );
        Composite modSpecComposite = BaseWidgetUtils.createColumnContainer( modSpec.modGroup, 2, 1 );
        modSpec.modType = BaseWidgetUtils.createCombo( modSpecComposite, new String[]
            { "add", "replace", "delete" }, 0, 1 );
        modSpec.modType.addModifyListener( this );
        String[] attributeDescriptions = schema.getAttributeTypeDescriptionNames();
        Arrays.sort( attributeDescriptions );

        // attribute combo with field decoration
        final FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration(
            FieldDecorationRegistry.DEC_CONTENT_PROPOSAL );
        modSpec.modAttributeComboField = new DecoratedField( modSpecComposite, SWT.NONE, new IControlCreator()
        {
            public Control createControl( Composite parent, int style )
            {
                Combo combo = BaseWidgetUtils.createCombo( parent, new String[0], -1, 1 );
                combo.setVisibleItemCount( 20 );
                return combo;
            }
        } );
        modSpec.modAttributeComboField.addFieldDecoration( fieldDecoration, SWT.TOP | SWT.LEFT, true );
        modSpec.modAttributeComboField.getLayoutControl().setLayoutData(
            new GridData( SWT.FILL, SWT.CENTER, true, false ) );
        modSpec.modAttributeCombo = ( Combo ) modSpec.modAttributeComboField.getControl();
        modSpec.modAttributeCombo.setItems( attributeDescriptions );
        modSpec.modAttributeCombo.addModifyListener( this );

        // content proposal adapter
        modSpec.modAttributeCPA = new ContentProposalAdapter( modSpec.modAttributeCombo, new ComboContentAdapter(),
            new ListContentProposalProvider( attributeDescriptions ), null, null );
        modSpec.modAttributeCPA.setFilterStyle( ContentProposalAdapter.FILTER_NONE );
        modSpec.modAttributeCPA.setProposalAcceptanceStyle( ContentProposalAdapter.PROPOSAL_REPLACE );

        // add button with listener
        modSpec.modAddButton = new Button( modComposite, SWT.PUSH );
        modSpec.modAddButton.setText( "  +   " );
        modSpec.modAddButton.addSelectionListener( new SelectionAdapter()
        {
            public void widgetSelected( SelectionEvent e )
            {
                int index = modSpecList.size();
                for ( int i = 0; i < modSpecList.size(); i++ )
                {
                    ModSpec modSpec = modSpecList.get( i );
                    if ( modSpec.modAddButton == e.widget )
                    {
                        index = i + 1;
                    }
                }

                addModSpec( modComposite, index );

                validate();
            }
        } );

        // delete button with listener
        modSpec.modDeleteButton = new Button( modComposite, SWT.PUSH );
        modSpec.modDeleteButton.setText( "  \u2212  " ); // \u2013
        modSpec.modDeleteButton.addSelectionListener( new SelectionAdapter()
        {
            public void widgetSelected( SelectionEvent e )
            {
                int index = 0;
                for ( int i = 0; i < modSpecList.size(); i++ )
                {
                    ModSpec modSpec = modSpecList.get( i );
                    if ( modSpec.modDeleteButton == e.widget )
                    {
                        index = i;
                    }
                }

                deleteModSpec( modComposite, index );

                validate();
            }
        } );

        addValueLine( modSpec, 0 );

        return modSpec;
    }


    /**
     * Delets a modification spec.
     *
     * @param modComposite the composite
     * @param index the index
     */
    private void deleteModSpec( Composite modComposite, int index )
    {
        ModSpec modSpec = modSpecList.remove( index );
        if ( modSpec != null )
        {
            modSpec.modGroup.dispose();
            modSpec.modAddButton.dispose();
            modSpec.modDeleteButton.dispose();

            if ( !modComposite.isDisposed() )
            {
                shell.layout( true, true );
            }
        }
    }


    /**
     * Adds a value line to the given modification spec.
     *
     * @param modSpec the modification spec
     * @param index the index
     */
    private void addValueLine( ModSpec modSpec, int index )
    {

        ValueLine[] valueLines = modSpec.valueLineList.toArray( new ValueLine[modSpec.valueLineList.size()] );

        if ( valueLines.length > 0 )
        {
            for ( int i = 0; i < valueLines.length; i++ )
            {
                ValueLine oldValueLine = valueLines[i];

                // remember values
                String oldValue = oldValueLine.valueText.getText();

                // delete old
                oldValueLine.valueComposite.dispose();
                modSpec.valueLineList.remove( oldValueLine );

                // add new
                ValueLine newValueLine = createValueLine( modSpec );
                modSpec.valueLineList.add( newValueLine );

                // restore value
                newValueLine.valueText.setText( oldValue );

                // check
                if ( index == i + 1 )
                {
                    ValueLine valueLine = createValueLine( modSpec );
                    modSpec.valueLineList.add( valueLine );
                }
            }
        }
        else
        {
            ValueLine valueLine = createValueLine( modSpec );
            modSpec.valueLineList.add( valueLine );
        }

        shell.layout( true, true );
    }


    /**
     * Creates the value line.
     *
     * @param modSpec the modification spec
     *
     * @return the value line
     */
    private ValueLine createValueLine( final ModSpec modSpec )
    {
        final ValueLine valueLine = new ValueLine();

        // text field
        valueLine.valueComposite = BaseWidgetUtils.createColumnContainer( modSpec.modGroup, 3, 1 );
        valueLine.valueText = BaseWidgetUtils.createText( valueLine.valueComposite, "", 1 );
        valueLine.valueText.addModifyListener( this );

        // add button with listener
        valueLine.valueAddButton = new Button( valueLine.valueComposite, SWT.PUSH );
        valueLine.valueAddButton.setText( "  +   " );
        valueLine.valueAddButton.addSelectionListener( new SelectionAdapter()
        {
            public void widgetSelected( SelectionEvent e )
            {
                int index = modSpec.valueLineList.size();
                for ( int i = 0; i < modSpec.valueLineList.size(); i++ )
                {
                    ValueLine valueLine = modSpec.valueLineList.get( i );
                    if ( valueLine.valueAddButton == e.widget )
                    {
                        index = i + 1;
                    }
                }

                addValueLine( modSpec, index );

                validate();
            }
        } );

        // delete button with listener
        valueLine.valueDeleteButton = new Button( valueLine.valueComposite, SWT.PUSH );
        valueLine.valueDeleteButton.setText( "  \u2212  " ); // \u2013
        valueLine.valueDeleteButton.addSelectionListener( new SelectionAdapter()
        {
            public void widgetSelected( SelectionEvent e )
            {
                int index = 0;
                for ( int i = 0; i < modSpec.valueLineList.size(); i++ )
                {
                    ValueLine valueLine = modSpec.valueLineList.get( i );
                    if ( valueLine.valueDeleteButton == e.widget )
                    {
                        index = i;
                    }
                }

                deleteValueLine( modSpec, index );

                validate();
            }
        } );

        return valueLine;
    }


    /**
     * Delete value line.
     *
     * @param modSpec the mod spec
     * @param index the index
     */
    private void deleteValueLine( ModSpec modSpec, int index )
    {
        ValueLine valueLine = ( ValueLine ) modSpec.valueLineList.remove( index );
        if ( valueLine != null )
        {
            valueLine.valueComposite.dispose();

            if ( !modComposite.isDisposed() )
            {
                shell.layout( true, true );
            }
        }
    }


    /**
     * Gets the LDIF fragment.
     *
     * @return the LDIF fragment
     */
    public String getLdifFragment()
    {

        StringBuffer sb = new StringBuffer();
        sb.append( "changetype: modify" ).append( BrowserCoreConstants.LINE_SEPARATOR );

        ModSpec[] modSpecs = ( ModSpec[] ) modSpecList.toArray( new ModSpec[modSpecList.size()] );

        if ( modSpecs.length > 0 )
        {
            for ( int i = 0; i < modSpecs.length; i++ )
            {
                ModSpec modSpec = modSpecs[i];

                // get values
                String type = modSpec.modType.getText();
                String attribute = modSpec.modAttributeCombo.getText();
                String[] values = new String[modSpec.valueLineList.size()];
                for ( int k = 0; k < values.length; k++ )
                {
                    values[k] = ( ( ValueLine ) modSpec.valueLineList.get( k ) ).valueText.getText();
                }

                // build ldif
                sb.append( type ).append( ": " ).append( attribute ).append( BrowserCoreConstants.LINE_SEPARATOR );
                for ( int k = 0; k < values.length; k++ )
                {
                    if ( values[k].length() > 0 )
                    {
                        sb.append( attribute ).append( ": " ).append( values[k] ).append(
                            BrowserCoreConstants.LINE_SEPARATOR );
                    }
                }
                sb.append( "-" ).append( BrowserCoreConstants.LINE_SEPARATOR );
                // sb.append(BrowserCoreConstants.NEWLINE);
            }
        }

        return sb.toString();
    }

    /**
     * The Class ModSpec is a wrapper for all input elements
     * of an modification. It contains a combo for the modify
     * operation, a combo for the attribute to modify,
     * value lines and + and - buttons to add and remove
     * other modifications. It looks like this:
     * <pre>
     * ----------------------------------
     * | operation v | attribute type v |--------
     * ------------------------ --------| + | - |
     * | value                  | + | - |--------
     * ----------------------------------
     * </pre>
     */
    private class ModSpec
    {

        /** The mod group. */
        private Group modGroup;

        /** The mod type. */
        private Combo modType;

        /** The modification attribute field. */
        private DecoratedField modAttributeComboField;

        /** The modification attribute. */
        private Combo modAttributeCombo;

        /** The modification content proposal adapter */
        private ContentProposalAdapter modAttributeCPA;

        /** The mod add button. */
        private Button modAddButton;

        /** The mod delete button. */
        private Button modDeleteButton;

        /** The value line list. */
        private ArrayList<ValueLine> valueLineList = new ArrayList<ValueLine>();;
    }

    /**
     * The Class ValueLine is a wrapper for all input elements
     * of an value line. It contains an input field for the value
     * and + and - buttons to add and remove other value lines.
     * It looks like this:
     * <pre>
     * -------------------------------------
     * | value                     | + | - |
     * -------------------------------------
     * </pre>
     */
    private class ValueLine
    {

        /** The value composite. */
        private Composite valueComposite;

        /** The value text. */
        private Text valueText;

        /** The value add button. */
        private Button valueAddButton;

        /** The value delete button. */
        private Button valueDeleteButton;
    }

}
TOP

Related Classes of org.apache.directory.studio.ldapbrowser.common.widgets.ModWidget$ValueLine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.