directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seelm...@apache.org
Subject svn commit: r545640 [1/2] - in /directory/studio/trunk: ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/valueeditors/ ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/dialogs/ l...
Date Fri, 08 Jun 2007 21:42:20 GMT
Author: seelmann
Date: Fri Jun  8 14:42:18 2007
New Revision: 545640

URL: http://svn.apache.org/viewvc?view=rev&rev=545640
Log:
Resolved DIRSTUDIO-47:
* Added support for extensible matching into parser and UI
* Disable OK Button and show error message when filter is invalid
* Added hover support

Added:
    directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/internal/model/DirectoryTypeDetector.java
    directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/LdapFilterExtensibleComponent.java
    directory/studio/trunk/ldapstudio-browser-core/src/test/java/org/apache/directory/ldastudio/browser/core/model/LdapFilterParserTest.java
Modified:
    directory/studio/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/valueeditors/SubtreeSpecificationDialog.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/dialogs/FilterWidgetDialog.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterAutoEditStrategy.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterContentAssistProcessor.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterDamagerRepairer.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterFormattingStrategy.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterSourceViewerConfiguration.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterTextHover.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidget.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidgetAutoEditStrategyAdapter.java
    directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/SearchPageWrapper.java
    directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/parser/LdapFilterParser.java
    directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/parser/LdapFilterScanner.java
    directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/parser/LdapFilterToken.java
    directory/studio/trunk/ldapstudio-browser-ui/src/main/java/org/apache/directory/ldapstudio/browser/ui/dialogs/properties/SearchPropertyPage.java
    directory/studio/trunk/ldapstudio-browser-ui/src/main/java/org/apache/directory/ldapstudio/browser/ui/search/SearchPage.java
    directory/studio/trunk/ldapstudio-browser-ui/src/main/java/org/apache/directory/ldapstudio/browser/ui/wizards/BatchOperationApplyOnWizardPage.java
    directory/studio/trunk/ldapstudio-browser-ui/src/main/java/org/apache/directory/ldapstudio/browser/ui/wizards/ExportBaseFromWizardPage.java

Modified: directory/studio/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/valueeditors/SubtreeSpecificationDialog.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/valueeditors/SubtreeSpecificationDialog.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/valueeditors/SubtreeSpecificationDialog.java (original)
+++ directory/studio/trunk/ldapstudio-aciitemeditor/src/main/java/org/apache/directory/ldapstudio/aciitemeditor/valueeditors/SubtreeSpecificationDialog.java Fri Jun  8 14:42:18 2007
@@ -146,7 +146,7 @@
     }
 
 
-    /* (non-Javadoc)
+    /** (non-Javadoc)
      * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
      */
     protected void configureShell( Shell newShell )
@@ -157,7 +157,7 @@
     }
 
 
-    /* (non-Javadoc)
+    /** (non-Javadoc)
      * @see org.eclipse.jface.dialogs.Dialog#okPressed()
      */
     protected void okPressed()
@@ -179,7 +179,7 @@
     }
 
 
-    /* (non-Javadoc)
+    /** (non-Javadoc)
      * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
      */
     protected Control createDialogArea( Composite parent )
@@ -493,6 +493,11 @@
         {
             subtreeSpecification = null;
             valid &= false;
+        }
+        
+        if ( refinementOrFilterVisible && filterButton.getSelection() )
+        {
+            valid &= filterWidget.getFilter() != null;
         }
 
         if ( getButton( IDialogConstants.OK_ID ) != null )

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/dialogs/FilterWidgetDialog.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/dialogs/FilterWidgetDialog.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/dialogs/FilterWidgetDialog.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/dialogs/FilterWidgetDialog.java Fri Jun  8 14:42:18 2007
@@ -23,6 +23,9 @@
 
 import org.apache.directory.ldapstudio.browser.common.BrowserCommonActivator;
 import org.apache.directory.ldapstudio.browser.common.BrowserCommonConstants;
+import org.apache.directory.ldapstudio.browser.common.widgets.BaseWidgetUtils;
+import org.apache.directory.ldapstudio.browser.common.widgets.WidgetModifyEvent;
+import org.apache.directory.ldapstudio.browser.common.widgets.WidgetModifyListener;
 import org.apache.directory.ldapstudio.browser.common.widgets.search.FilterWidget;
 import org.apache.directory.ldapstudio.browser.core.model.IConnection;
 import org.eclipse.jface.dialogs.Dialog;
@@ -32,6 +35,7 @@
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 
 
@@ -56,6 +60,9 @@
     /** The filter. */
     private String filter;
 
+    /** The error message label. */
+    private Label errorMessageLabel;
+
 
     /**
      * Creates a new instance of FilterWidgetDialog.
@@ -133,8 +140,32 @@
         filterWidget = new FilterWidget( connection, filter != null ? filter : "" );
         filterWidget.createWidget( inner );
         filterWidget.setFocus();
+        filterWidget.addWidgetModifyListener( new WidgetModifyListener()
+        {
+            public void widgetModified( WidgetModifyEvent event )
+            {
+                validate();
+            }
+        } );
+
+        errorMessageLabel = BaseWidgetUtils.createLabel( inner, "Please enter a valid filter.", 2 );
+
+        validate();
 
         return composite;
+    }
+
+
+    /**
+     * Validates the filter.
+     */
+    protected void validate()
+    {
+        if ( getButton( IDialogConstants.OK_ID ) != null )
+        {
+            getButton( IDialogConstants.OK_ID ).setEnabled( filterWidget.getFilter() != null );
+        }
+        errorMessageLabel.setText( filterWidget.getFilter() == null ? "Please enter a valid filter." : "" );
     }
 
 }

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterAutoEditStrategy.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterAutoEditStrategy.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterAutoEditStrategy.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterAutoEditStrategy.java Fri Jun  8 14:42:18 2007
@@ -57,17 +57,6 @@
      */
     public FilterAutoEditStrategy( LdapFilterParser parser )
     {
-        this.init( parser );
-    }
-
-
-    /**
-     * Init.
-     * 
-     * @param parser the parser
-     */
-    private void init( LdapFilterParser parser )
-    {
         this.parser = parser;
     }
 
@@ -79,7 +68,7 @@
     {
         super.customizeDocumentCommand( d, c );
         AutoEditParameters aep = new AutoEditParameters( c.text, c.offset, c.length, c.caretOffset, c.shiftsCaret );
-        customizeAutoEditParameters( aep );
+        customizeAutoEditParameters( d.get(), aep );
         c.offset = aep.offset;
         c.length = aep.length;
         c.text = aep.text;
@@ -91,12 +80,27 @@
     /**
      * Customizes auto edit parameters.
      * 
+     * @param currentFilter the current filter
      * @param aep the auto edit parameters
      */
-    public void customizeAutoEditParameters( AutoEditParameters aep )
+    public void customizeAutoEditParameters( String currentFilter, AutoEditParameters aep )
     {
+        parser.parse( currentFilter );
         LdapFilter filter = parser.getModel().getFilter( aep.offset );
-        //System.out.println(filter);
+
+        // check balanced parenthesis
+        int balanced = 0;
+        for ( int i = 0; i < currentFilter.length(); i++ )
+        {
+            if ( currentFilter.charAt( i ) == '(' )
+            {
+                balanced++;
+            }
+            else if ( currentFilter.charAt( i ) == ')' )
+            {
+                balanced--;
+            }
+        }
 
         if ( aep.length > 0 && ( aep.text == null || "".equals( aep.text ) ) )
         {
@@ -116,11 +120,12 @@
         if ( aep.length == 0 && aep.text != null && !"".equals( aep.text ) )
         {
             boolean isNewFilter = aep.text.equals( "(" );
+            boolean isNewNestedFilter = aep.text.equals( "&" ) || aep.text.equals( "|" ) || aep.text.equals( "!" );
             boolean isSurroundNew = false;
             boolean isSurroundNested = false;
             boolean isSurroundBeforeOtherFilter = false;
             boolean isSurroundAfterOtherFilter = false;
-            if ( aep.text.matches( "[a-zA-Z0-9-\\.&|!]+" ) && filter != null )
+            if ( aep.text.matches( "[a-zA-Z0-9-\\.&|!:]+" ) && filter != null )
             {
                 isSurroundNew = filter.getStartToken() == null && aep.offset == 0 && !aep.text.startsWith( "(" )
                     && !aep.text.endsWith( ")" );
@@ -184,13 +189,31 @@
                 aep.shiftsCaret = false;
             }
 
+            // add parenthesis for nested filters
+            if ( isNewNestedFilter )
+            {
+                aep.text = aep.text + "()";
+                aep.caretOffset = aep.offset + aep.text.length() - 1;
+                aep.shiftsCaret = false;
+            }
+
             // add closing parenthesis ')'
             if ( isNewFilter || isSurroundNew || isSurroundNested || isSurroundAfterOtherFilter
                 || isSurroundBeforeOtherFilter )
             {
-                aep.text = aep.text + ")";
-                aep.caretOffset = aep.offset + aep.text.length() - 1;
-                aep.shiftsCaret = false;
+                if ( balanced == 0 )
+                {
+                    aep.text = aep.text + ")";
+                    if( aep.caretOffset == -1 )
+                    {
+                        aep.caretOffset = aep.offset + aep.text.length() - 1;
+                        aep.shiftsCaret = false;
+                    }
+                    
+                    System.out.println(aep.text + ", " + aep.caretOffset);
+                    //aep.caretOffset = aep.offset + aep.text.length() - 1;
+                    //aep.shiftsCaret = false;
+                }
             }
 
             // translate tab to IDENT_STRING

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterContentAssistProcessor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterContentAssistProcessor.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterContentAssistProcessor.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterContentAssistProcessor.java Fri Jun  8 14:42:18 2007
@@ -23,15 +23,23 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
 
 import org.apache.directory.ldapstudio.browser.common.BrowserCommonActivator;
 import org.apache.directory.ldapstudio.browser.common.BrowserCommonConstants;
 import org.apache.directory.ldapstudio.browser.core.model.IAttribute;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilter;
+import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterExtensibleComponent;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterItemComponent;
 import org.apache.directory.ldapstudio.browser.core.model.filter.parser.LdapFilterParser;
 import org.apache.directory.ldapstudio.browser.core.model.filter.parser.LdapFilterToken;
+import org.apache.directory.ldapstudio.browser.core.model.schema.AttributeTypeDescription;
+import org.apache.directory.ldapstudio.browser.core.model.schema.MatchingRuleDescription;
+import org.apache.directory.ldapstudio.browser.core.model.schema.ObjectClassDescription;
 import org.apache.directory.ldapstudio.browser.core.model.schema.Schema;
 import org.eclipse.jface.fieldassist.IContentProposal;
 import org.eclipse.jface.fieldassist.IContentProposalProvider;
@@ -60,6 +68,25 @@
     IContentProposalProvider
 {
 
+    private static final Comparator<String> nameAndOidComparator = new Comparator<String>()
+    {
+        public int compare( String s1, String s2 )
+        {
+            if ( s1.matches( "[0-9\\.]+" ) && !s2.matches( "[0-9\\.]+" ) )
+            {
+                return 1;
+            }
+            else if ( !s1.matches( "[0-9\\.]+" ) && s2.matches( "[0-9\\.]+" ) )
+            {
+                return -1;
+            }
+            else
+            {
+                return s1.compareToIgnoreCase( s2 );
+            }
+        }
+    };
+
     /** The parser. */
     private LdapFilterParser parser;
 
@@ -72,6 +99,18 @@
     /** The schema, used to retrieve attributeType and objectClass information. */
     private Schema schema;
 
+    /** The possible attribute types. */
+    private Map<String, AttributeTypeDescription> possibleAttributeTypes;
+
+    /** The possible filter types. */
+    private Map<String, String> possibleFilterTypes;
+
+    /** The possible object classes. */
+    private Map<String, ObjectClassDescription> possibleObjectClasses;
+
+    /** The possible matching rules. */
+    private Map<String, MatchingRuleDescription> possibleMatchingRules;
+
 
     /**
      * Creates a new instance of FilterContentAssistProcessor.
@@ -95,9 +134,15 @@
         this.parser = parser;
         this.sourceViewer = sourceViewer;
 
-        this.autoActivationCharacters = new char[1 + 26 + 26];
+        this.autoActivationCharacters = new char[7 + 10 + 26 + 26];
         this.autoActivationCharacters[0] = '(';
-        int i = 1;
+        this.autoActivationCharacters[1] = ')';
+        this.autoActivationCharacters[2] = '&';
+        this.autoActivationCharacters[3] = '|';
+        this.autoActivationCharacters[4] = '!';
+        this.autoActivationCharacters[5] = ':';
+        this.autoActivationCharacters[6] = '.';
+        int i = 7;
         for ( char c = 'a'; c <= 'z'; c++, i++ )
         {
             this.autoActivationCharacters[i] = c;
@@ -106,6 +151,10 @@
         {
             this.autoActivationCharacters[i] = c;
         }
+        for ( char c = '0'; c <= '9'; c++, i++ )
+        {
+            this.autoActivationCharacters[i] = c;
+        }
     }
 
 
@@ -117,6 +166,53 @@
     public void setSchema( Schema schema )
     {
         this.schema = schema;
+
+        possibleAttributeTypes = new TreeMap<String, AttributeTypeDescription>( nameAndOidComparator );
+        possibleFilterTypes = new LinkedHashMap<String, String>();
+        possibleObjectClasses = new TreeMap<String, ObjectClassDescription>( nameAndOidComparator );
+        possibleMatchingRules = new TreeMap<String, MatchingRuleDescription>( nameAndOidComparator );
+
+        if ( schema != null )
+        {
+            AttributeTypeDescription[] attributeTypeDescriptions = schema.getAttributeTypeDescriptions();
+            for ( int i = 0; i < attributeTypeDescriptions.length; i++ )
+            {
+                AttributeTypeDescription description = attributeTypeDescriptions[i];
+                possibleAttributeTypes.put( description.getNumericOID(), description );
+                for ( int k = 0; k < description.getNames().length; k++ )
+                {
+                    possibleAttributeTypes.put( description.getNames()[k], description );
+                }
+            }
+
+            possibleFilterTypes.put( "=", "= (equals)" );
+            possibleFilterTypes.put( "=*", "=* (present)" );
+            possibleFilterTypes.put( "<=", "<= (less than or equals)" );
+            possibleFilterTypes.put( ">=", ">= (greater than or equals)" );
+            possibleFilterTypes.put( "~=", "~= (approximately)" );
+
+            ObjectClassDescription[] objectClassDescriptions = schema.getObjectClassDescriptions();
+            for ( int i = 0; i < objectClassDescriptions.length; i++ )
+            {
+                ObjectClassDescription description = objectClassDescriptions[i];
+                possibleObjectClasses.put( description.getNumericOID(), description );
+                for ( int k = 0; k < description.getNames().length; k++ )
+                {
+                    possibleObjectClasses.put( description.getNames()[k], description );
+                }
+            }
+
+            MatchingRuleDescription[] matchingRuleDescriptions = schema.getMatchingRuleDescriptions();
+            for ( int i = 0; i < matchingRuleDescriptions.length; i++ )
+            {
+                MatchingRuleDescription description = matchingRuleDescriptions[i];
+                possibleMatchingRules.put( description.getNumericOID(), description );
+                for ( int k = 0; k < description.getNames().length; k++ )
+                {
+                    possibleMatchingRules.put( description.getNames()[k], description );
+                }
+            }
+        }
     }
 
 
@@ -199,8 +295,6 @@
      */
     private ICompletionProposal[] computeCompletionProposals( int offset )
     {
-        String[] possibleAttributeTypes = schema == null ? new String[0] : schema.getAttributeTypeDescriptionNames();
-        Arrays.sort( possibleAttributeTypes );
         String[] possibleObjectClasses = schema == null ? new String[0] : schema.getObjectClassDescriptionNames();
         Arrays.sort( possibleObjectClasses );
 
@@ -208,12 +302,9 @@
         LdapFilter filter = parser.getModel().getFilter( offset );
         if ( filter != null )
         {
-            String attributeType = null;
-
-            // case 1: open curly started, show templates and all attribute types
+            // case 0: open curly started, show templates and all attribute types
             if ( filter.getStartToken() != null && filter.getFilterComponent() == null )
             {
-
                 if ( sourceViewer != null )
                 {
                     ICompletionProposal[] templateProposals = super.computeCompletionProposals( sourceViewer, offset );
@@ -222,127 +313,285 @@
                         proposalList.addAll( Arrays.asList( templateProposals ) );
                     }
                 }
+                addPossibleAttributeTypes( proposalList, "", offset );
+            }
 
-                for ( int k = 0; k < possibleAttributeTypes.length; k++ )
+            // case A: simple filter
+            if ( filter.getFilterComponent() != null && filter.getFilterComponent() instanceof LdapFilterItemComponent )
+            {
+                LdapFilterItemComponent fc = ( LdapFilterItemComponent ) filter.getFilterComponent();
+
+                // case A1: editing attribute type: show matching attribute types
+                if ( fc.getStartToken().getOffset() <= offset
+                    && offset <= fc.getStartToken().getOffset() + fc.getStartToken().getLength() )
                 {
-                    ICompletionProposal proposal = new CompletionProposal( possibleAttributeTypes[k], offset, 0,
-                        possibleAttributeTypes[k].length(), getAttributeTypeImage(), null, null, schema
-                            .getAttributeTypeDescription( possibleAttributeTypes[k] ).getLine().getUnfoldedValue() );
-                    proposalList.add( proposal );
+                    addPossibleAttributeTypes( proposalList, fc.getAttributeToken().getValue(), fc.getAttributeToken()
+                        .getOffset() );
+                }
+
+                String attributeType = null;
+                if ( schema != null && schema.hasAttributeTypeDescription( fc.getAttributeToken().getValue() ) )
+                {
+                    attributeType = fc.getAttributeToken().getValue();
+                }
+
+                // case A2: after attribte type: show possible filter types and extensible match options
+                if ( attributeType != null )
+                {
+                    if ( ( fc.getAttributeToken().getOffset() <= offset || fc.getFilterToken() != null )
+                        && offset <= fc.getAttributeToken().getOffset() + fc.getAttributeToken().getLength()
+                            + ( fc.getFilterToken() != null ? fc.getFilterToken().getLength() : 0 ) )
+                    {
+                        //String attributeType = fc.getAttributeToken().getValue();
+                        String filterType = fc.getFilterToken() != null ? fc.getFilterToken().getValue() : "";
+                        int filterTypeOffset = fc.getAttributeToken().getOffset() + fc.getAttributeToken().getLength();
+                        addPossibleFilterTypes( proposalList, attributeType, filterType, filterTypeOffset );
+                    }
+                }
+
+                // case A3: editing objectClass attribute: show matching object classes
+                if ( attributeType != null && IAttribute.OBJECTCLASS_ATTRIBUTE.equalsIgnoreCase( attributeType ) )
+                {
+                    if ( ( fc.getValueToken() != null && fc.getValueToken().getOffset() <= offset || fc
+                        .getFilterToken() != null )
+                        && offset <= fc.getAttributeToken().getOffset() + fc.getAttributeToken().getLength()
+                            + ( fc.getFilterToken() != null ? fc.getFilterToken().getLength() : 0 )
+                            + ( fc.getValueToken() != null ? fc.getValueToken().getLength() : 0 ) )
+                    {
+                        addPossibleObjectClasses( proposalList, fc.getValueToken() == null ? "" : fc.getValueToken()
+                            .getValue(), fc.getValueToken() == null ? offset : fc.getValueToken().getOffset() );
+                    }
                 }
             }
 
-            // case 2: editing attribute type: show matching attribute types
-            else if ( filter.getFilterComponent() instanceof LdapFilterItemComponent
-                && filter.getFilterComponent().getStartToken().getOffset() <= offset
-                && offset <= filter.getFilterComponent().getStartToken().getOffset()
-                    + filter.getFilterComponent().getStartToken().getLength() )
+            // case B: extensible filter
+            if ( filter.getFilterComponent() != null
+                && filter.getFilterComponent() instanceof LdapFilterExtensibleComponent )
             {
-                LdapFilterItemComponent fc = ( LdapFilterItemComponent ) filter.getFilterComponent();
-                for ( int k = 0; k < possibleAttributeTypes.length; k++ )
+                LdapFilterExtensibleComponent fc = ( LdapFilterExtensibleComponent ) filter.getFilterComponent();
+
+                // case B1: editing extensible attribute type: show matching attribute types
+                if ( fc.getAttributeToken() != null && fc.getAttributeToken().getOffset() <= offset
+                    && offset <= fc.getAttributeToken().getOffset() + fc.getAttributeToken().getLength() )
                 {
-                    if ( possibleAttributeTypes[k].equalsIgnoreCase( fc.getAttributeToken().getValue() ) )
+                    addPossibleAttributeTypes( proposalList, fc.getAttributeToken().getValue(), fc.getAttributeToken()
+                        .getOffset() );
+                }
+
+                // case B2: editing dn
+                if ( fc.getDnAttrToken() != null && fc.getDnAttrToken().getOffset() <= offset
+                    && offset <= fc.getDnAttrToken().getOffset() + fc.getDnAttrToken().getLength() )
+                {
+                    addDnAttr( proposalList, fc.getDnAttrToken().getValue(), fc.getDnAttrToken().getOffset() );
+                }
+
+                // case B3: editing matching rule
+                if ( fc.getMatchingRuleColonToken() != null
+                    && fc.getMatchingRuleToken() == null
+                    && fc.getMatchingRuleColonToken().getOffset() <= offset
+                    && offset <= fc.getMatchingRuleColonToken().getOffset()
+                        + fc.getMatchingRuleColonToken().getLength() )
+                {
+                    if ( fc.getDnAttrColonToken() == null )
                     {
+                        addDnAttr( proposalList, "", offset );
                     }
-                    else if ( possibleAttributeTypes[k].startsWith( fc.getAttributeToken().getValue() ) )
+                    addPossibleMatchingRules( proposalList, "", offset, fc.getEqualsColonToken(), fc.getEqualsToken() );
+                }
+                if ( fc.getMatchingRuleToken() != null && fc.getMatchingRuleToken().getOffset() <= offset
+                    && offset <= fc.getMatchingRuleToken().getOffset() + fc.getMatchingRuleToken().getLength() )
+                {
+                    if ( fc.getDnAttrColonToken() == null )
                     {
-                        ICompletionProposal proposal = new CompletionProposal( possibleAttributeTypes[k], fc
-                            .getAttributeToken().getOffset(), fc.getAttributeToken().getLength(),
-                            possibleAttributeTypes[k].length(), getAttributeTypeImage(), null, null, schema
-                                .getAttributeTypeDescription( possibleAttributeTypes[k] ).getLine().getUnfoldedValue() );
-                        proposalList.add( proposal );
+                        addDnAttr( proposalList, fc.getMatchingRuleToken().getValue(), fc.getMatchingRuleToken()
+                            .getOffset() );
                     }
+
+                    String matchingRuleValue = fc.getMatchingRuleToken().getValue();
+                    addPossibleMatchingRules( proposalList, matchingRuleValue, fc.getMatchingRuleToken().getOffset(),
+                        fc.getEqualsColonToken(), fc.getEqualsToken() );
                 }
             }
+        }
 
-            if ( filter.getFilterComponent() instanceof LdapFilterItemComponent )
+        return proposalList.toArray( new ICompletionProposal[0] );
+    }
+
+
+    /**
+     * Adds the possible attribute types to the proposal list.
+     * 
+     * @param proposalList the proposal list
+     * @param attributeType the current attribute type
+     * @param offset the offset
+     */
+    private void addPossibleAttributeTypes( List<ICompletionProposal> proposalList, String attributeType, int offset )
+    {
+        if ( schema != null )
+        {
+            for ( String possibleAttributeType : possibleAttributeTypes.keySet() )
             {
-                LdapFilterItemComponent fc = ( LdapFilterItemComponent ) filter.getFilterComponent();
-                for ( int k = 0; k < possibleAttributeTypes.length; k++ )
+                AttributeTypeDescription description = possibleAttributeTypes.get( possibleAttributeType );
+                if ( possibleAttributeType.toUpperCase().startsWith( attributeType.toUpperCase() ) )
                 {
-                    if ( possibleAttributeTypes[k].equalsIgnoreCase( fc.getAttributeToken().getValue() ) )
+                    String replacementString = possibleAttributeType;
+                    String displayString = possibleAttributeType;
+                    if ( displayString.equals( description.getNumericOID() ) )
                     {
-                        attributeType = fc.getAttributeToken().getValue();
-                        break;
+                        displayString += " (" + description.toString() + ")";
                     }
+                    else
+                    {
+                        displayString += " (" + description.getNumericOID() + ")";
+                    }
+
+                    ICompletionProposal proposal = new CompletionProposal( replacementString, offset, attributeType
+                        .length(), replacementString.length(), getAttributeTypeImage(), displayString, null, schema
+                        .getAttributeTypeDescription( possibleAttributeType ).getLine().getUnfoldedValue() );
+                    proposalList.add( proposal );
                 }
             }
+        }
+    }
+
+
+    /**
+     * Adds the possible attribute types to the proposal list.
+     * 
+     * @param proposalList the proposal list
+     * @param attributeType the current attribute type
+     * @param offset the offset
+     */
+    private void addPossibleFilterTypes( List<ICompletionProposal> proposalList, String attributeType,
+        String filterType, int offset )
+    {
+        if ( schema != null )
+        {
+            Map<String, String> copy = new LinkedHashMap<String, String>( possibleFilterTypes );
+            if ( schema.getAttributeTypeDescription( attributeType ).getEqualityMatchingRuleDescriptionOIDTransitive() == null )
+            {
+                copy.remove( "=" );
+                copy.remove( "~=" );
+            }
+            if ( schema.getAttributeTypeDescription( attributeType ).getOrderingMatchingRuleDescriptionOIDTransitive() == null )
+            {
+                copy.remove( "<=" );
+                copy.remove( ">=" );
+            }
 
-            // case 3: after attribte type: show possible assertion types
-            if ( attributeType != null && filter.getFilterComponent() instanceof LdapFilterItemComponent )
+            for ( String possibleFilterType : copy.keySet() )
             {
-                LdapFilterItemComponent fc = ( LdapFilterItemComponent ) filter.getFilterComponent();
-                if ( ( fc.getAttributeToken().getOffset() <= offset || fc.getFilterToken() != null )
-                    && offset <= fc.getAttributeToken().getOffset() + fc.getAttributeToken().getLength()
-                        + ( fc.getFilterToken() != null ? fc.getFilterToken().getLength() : 0 ) )
-                {
-                    LdapFilterToken filterTypeToken = fc.getFilterToken();
-
-                    // determine matching assertion types depending on the schema's attribute type description
-                    List<String> possibleAssertionTypes = new ArrayList<String>( Arrays.asList( new String[]
-                        { "=", "=*", "<=", ">=", "~=" } ) );
-                    if ( schema != null )
-                    {
-                        if ( schema.getAttributeTypeDescription( attributeType )
-                            .getEqualityMatchingRuleDescriptionOIDTransitive() == null )
-                        {
-                            possibleAssertionTypes.remove( "=" );
-                            possibleAssertionTypes.remove( "~=" );
-                        }
-                        if ( schema.getAttributeTypeDescription( attributeType )
-                            .getOrderingMatchingRuleDescriptionOIDTransitive() == null )
-                        {
-                            possibleAssertionTypes.remove( "<=" );
-                            possibleAssertionTypes.remove( ">=" );
-                        }
-                    }
-                    for ( String possibleAssertionType : possibleAssertionTypes )
-                    {
-                        if ( filterTypeToken == null
-                            || !possibleAssertionType.equalsIgnoreCase( filterTypeToken.getValue() ) )
-                        {
-                            ICompletionProposal proposal = new CompletionProposal( possibleAssertionType, fc
-                                .getAttributeToken().getOffset()
-                                + fc.getAttributeToken().getLength(), filterTypeToken != null ? filterTypeToken
-                                .getLength() : 0, possibleAssertionType.length(), null, null, null, null );
-                            proposalList.add( proposal );
-                        }
+                String replacementString = possibleFilterType;
+                String displayString = copy.get( possibleFilterType );
+
+                ICompletionProposal proposal = new CompletionProposal( replacementString, offset, filterType.length(),
+                    possibleFilterType.length(), getFilterTypeImage(), displayString, null, null );
+                proposalList.add( proposal );
+            }
+        }
+    }
+
+
+    /**
+     * Adds the possible object classes to the proposal list.
+     * 
+     * @param proposalList the proposal list
+     * @param objectClasses the object class
+     * @param offset the offset
+     */
+    private void addPossibleObjectClasses( List<ICompletionProposal> proposalList, String objectClass, int offset )
+    {
+        if ( schema != null )
+        {
+            for ( String possibleObjectClass : possibleObjectClasses.keySet() )
+            {
+                ObjectClassDescription description = possibleObjectClasses.get( possibleObjectClass );
+                if ( possibleObjectClass.toUpperCase().startsWith( objectClass.toUpperCase() ) )
+                {
+                    String replacementString = possibleObjectClass;
+                    String displayString = possibleObjectClass;
+                    if ( displayString.equals( description.getNumericOID() ) )
+                    {
+                        displayString += " (" + description.toString() + ")";
+                    }
+                    else
+                    {
+                        displayString += " (" + description.getNumericOID() + ")";
                     }
+
+                    ICompletionProposal proposal = new CompletionProposal( replacementString, offset, objectClass
+                        .length(), replacementString.length(), getObjectClassImage(), displayString, null, schema
+                        .getObjectClassDescription( possibleObjectClass ).getLine().getUnfoldedValue() );
+                    proposalList.add( proposal );
                 }
             }
+        }
+    }
 
-            // case 4: editing objectClass attribute: show matching object classes
-            if ( attributeType != null && IAttribute.OBJECTCLASS_ATTRIBUTE.equalsIgnoreCase( attributeType )
-                && filter.getFilterComponent() instanceof LdapFilterItemComponent )
+
+    /**
+     * Adds the possible matching rules (that fits to the given attribute type) to the proposal list.
+     * 
+     * @param proposalList the proposal list
+     * @param matchingRule the matching rule
+     * @param offset the offset
+     */
+    private void addPossibleMatchingRules( List<ICompletionProposal> proposalList, String matchingRule, int offset,
+        LdapFilterToken equalsColonToken, LdapFilterToken equalsToken )
+    {
+        if ( schema != null )
+        {
+            for ( String possibleMatchingRule : possibleMatchingRules.keySet() )
             {
-                LdapFilterItemComponent fc = ( LdapFilterItemComponent ) filter.getFilterComponent();
-                if ( ( fc.getValueToken() != null && fc.getValueToken().getOffset() <= offset || fc.getFilterToken() != null )
-                    && offset <= fc.getAttributeToken().getOffset() + fc.getAttributeToken().getLength()
-                        + ( fc.getFilterToken() != null ? fc.getFilterToken().getLength() : 0 )
-                        + ( fc.getValueToken() != null ? fc.getValueToken().getLength() : 0 ) )
+                if ( possibleMatchingRule.toUpperCase().startsWith( matchingRule.toUpperCase() ) )
                 {
-                    LdapFilterToken valueToken = fc.getValueToken();
-                    for ( int k = 0; k < possibleObjectClasses.length; k++ )
+                    MatchingRuleDescription description = schema.getMatchingRuleDescription( possibleMatchingRule );
+                    String replacementString = possibleMatchingRule;
+                    if ( equalsColonToken == null )
+                    {
+                        replacementString += ":";
+                    }
+                    if ( equalsToken == null )
                     {
-                        if ( fc.getValueToken() == null
-                            || possibleObjectClasses[k].startsWith( fc.getValueToken().getValue() ) )
-                        {
-                            ICompletionProposal proposal = new CompletionProposal( possibleObjectClasses[k], fc
-                                .getAttributeToken().getOffset()
-                                + fc.getAttributeToken().getLength() + fc.getFilterToken().getLength(),
-                                valueToken != null ? valueToken.getLength() : 0, possibleObjectClasses[k].length(),
-                                getObjectClassImage(), null, null, schema.getObjectClassDescription(
-                                    possibleObjectClasses[k] ).getLine().getUnfoldedValue() );
-                            proposalList.add( proposal );
-                        }
+                        replacementString += "=";
                     }
+                    String displayString = possibleMatchingRule;
+                    if ( displayString.equals( description.getNumericOID() ) )
+                    {
+                        displayString += " (" + description.toString() + ")";
+                    }
+                    else
+                    {
+                        displayString += " (" + description.getNumericOID() + ")";
+                    }
+
+                    ICompletionProposal proposal = new CompletionProposal( replacementString, offset, matchingRule
+                        .length(), replacementString.length(), getMatchingRuleImage(), displayString, null, schema
+                        .getMatchingRuleDescription( possibleMatchingRule ).getLine().getUnfoldedValue() );
+                    proposalList.add( proposal );
                 }
             }
         }
+    }
 
-        //System.out.println(proposalList);
 
-        return proposalList.toArray( new ICompletionProposal[0] );
+    /**
+     * Adds the dn: proposal to the proposal list.
+     * 
+     * @param proposalList the proposal list
+     * @param dnAttr the dn attr
+     * @param offset the offset
+     */
+    private void addDnAttr( List<ICompletionProposal> proposalList, String dnAttr, int offset )
+    {
+        if ( "dn".toUpperCase().startsWith( dnAttr.toUpperCase() ) )
+        {
+            String replacementString = "dn:";
+            String displayString = "dn: ()";
+            ICompletionProposal proposal = new CompletionProposal( replacementString, offset, dnAttr.length(),
+                replacementString.length(), null, displayString, null, null );
+            proposalList.add( proposal );
+        }
     }
 
 
@@ -358,6 +607,17 @@
 
 
     /**
+     * Gets the filter type image.
+     * 
+     * @return the filter type image
+     */
+    private Image getFilterTypeImage()
+    {
+        return BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_FILTER_EDITOR );
+    }
+
+
+    /**
      * Gets the object class image.
      * 
      * @return the object class image
@@ -365,6 +625,17 @@
     private Image getObjectClassImage()
     {
         return BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_OCD );
+    }
+
+
+    /**
+     * Gets the matching rule image.
+     * 
+     * @return the matching rule image
+     */
+    private Image getMatchingRuleImage()
+    {
+        return BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_MRD );
     }
 
 

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterDamagerRepairer.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterDamagerRepairer.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterDamagerRepairer.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterDamagerRepairer.java Fri Jun  8 14:42:18 2007
@@ -131,9 +131,15 @@
                 case LdapFilterToken.LESS:
                 case LdapFilterToken.APROX:
                 case LdapFilterToken.PRESENT:
+                case LdapFilterToken.EXTENSIBLE_DNATTR_COLON:
+                case LdapFilterToken.EXTENSIBLE_MATCHINGRULEOID_COLON:
+                case LdapFilterToken.EXTENSIBLE_EQUALS_COLON:
                     this.addStyleRange( presentation, tokens[i], FILTER_TYPE_TEXT_ATTRIBUTE );
                     break;
                 case LdapFilterToken.ATTRIBUTE:
+                case LdapFilterToken.EXTENSIBLE_ATTRIBUTE:
+                case LdapFilterToken.EXTENSIBLE_DNATTR:
+                case LdapFilterToken.EXTENSIBLE_MATCHINGRULEOID:
                     this.addStyleRange( presentation, tokens[i], ATTRIBUTE_TEXT_ATTRIBUTE );
                     break;
                 case LdapFilterToken.VALUE:

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterFormattingStrategy.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterFormattingStrategy.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterFormattingStrategy.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterFormattingStrategy.java Fri Jun  8 14:42:18 2007
@@ -24,6 +24,7 @@
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapAndFilterComponent;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilter;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterComponent;
+import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterExtensibleComponent;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterItemComponent;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapNotFilterComponent;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapOrFilterComponent;
@@ -107,6 +108,10 @@
         if ( fc instanceof LdapFilterItemComponent )
         {
             sb.append( '(' ).append( ( ( LdapFilterItemComponent ) fc ).toString() ).append( ')' );
+        }
+        else if ( fc instanceof LdapFilterExtensibleComponent )
+        {
+            sb.append( '(' ).append( ( ( LdapFilterExtensibleComponent ) fc ).toString() ).append( ')' );
         }
         else if ( fc instanceof LdapNotFilterComponent )
         {

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterSourceViewerConfiguration.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterSourceViewerConfiguration.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterSourceViewerConfiguration.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterSourceViewerConfiguration.java Fri Jun  8 14:42:18 2007
@@ -24,8 +24,11 @@
 import org.apache.directory.ldapstudio.browser.common.widgets.DialogContentAssistant;
 import org.apache.directory.ldapstudio.browser.core.model.IConnection;
 import org.apache.directory.ldapstudio.browser.core.model.filter.parser.LdapFilterParser;
+import org.eclipse.jface.text.DefaultInformationControl;
 import org.eclipse.jface.text.IAutoEditStrategy;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
 import org.eclipse.jface.text.ITextHover;
 import org.eclipse.jface.text.contentassist.IContentAssistant;
 import org.eclipse.jface.text.formatter.ContentFormatter;
@@ -36,6 +39,8 @@
 import org.eclipse.jface.text.reconciler.MonoReconciler;
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
 
 
 /**
@@ -107,6 +112,7 @@
     {
         this.connection = connection;
         contentAssistProcessor.setSchema( connection == null ? null : connection.getSchema() );
+        textHover.setSchema( connection == null ? null : connection.getSchema() );
     }
 
 
@@ -137,6 +143,7 @@
         if ( textHover == null )
         {
             textHover = new FilterTextHover( parser );
+            textHover.setSchema( connection == null ? null : connection.getSchema() );
         }
         return textHover;
     }
@@ -209,8 +216,26 @@
             contentAssistant.setContentAssistProcessor( contentAssistProcessor, IDocument.DEFAULT_CONTENT_TYPE );
             contentAssistant.enableAutoActivation( true );
             contentAssistant.setAutoActivationDelay( 100 );
+
+            contentAssistant.setContextInformationPopupOrientation( IContentAssistant.CONTEXT_INFO_ABOVE );
+            contentAssistant.setInformationControlCreator( getInformationControlCreator( sourceViewer ) );
+
         }
         return contentAssistant;
     }
 
+
+    /**
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getInformationControlCreator(org.eclipse.jface.text.source.ISourceViewer)
+     */
+    public IInformationControlCreator getInformationControlCreator( ISourceViewer sourceViewer )
+    {
+        return new IInformationControlCreator()
+        {
+            public IInformationControl createInformationControl( Shell parent )
+            {
+                return new DefaultInformationControl( parent, SWT.WRAP, null );
+            }
+        };
+    }
 }

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterTextHover.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterTextHover.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterTextHover.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/filtereditor/FilterTextHover.java Fri Jun  8 14:42:18 2007
@@ -21,9 +21,16 @@
 package org.apache.directory.ldapstudio.browser.common.filtereditor;
 
 
+import org.apache.directory.ldapstudio.browser.core.model.IAttribute;
 import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilter;
+import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterExtensibleComponent;
+import org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterItemComponent;
 import org.apache.directory.ldapstudio.browser.core.model.filter.parser.LdapFilterParser;
 import org.apache.directory.ldapstudio.browser.core.model.filter.parser.LdapFilterToken;
+import org.apache.directory.ldapstudio.browser.core.model.schema.AttributeTypeDescription;
+import org.apache.directory.ldapstudio.browser.core.model.schema.MatchingRuleDescription;
+import org.apache.directory.ldapstudio.browser.core.model.schema.ObjectClassDescription;
+import org.apache.directory.ldapstudio.browser.core.model.schema.Schema;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextHover;
 import org.eclipse.jface.text.ITextViewer;
@@ -42,6 +49,9 @@
     /** The filter parser. */
     private LdapFilterParser parser;
 
+    /** The schema, used to retrieve attributeType and objectClass information. */
+    private Schema schema;
+
 
     /**
      * Creates a new instance of FilterTextHover.
@@ -55,10 +65,79 @@
 
 
     /**
+     * Sets the schema, used to retrieve attributeType and objectClass information.
+     * 
+     * @param schema the schema
+     */
+    public void setSchema( Schema schema )
+    {
+        this.schema = schema;
+    }
+
+
+    /**
      * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
      */
     public String getHoverInfo( ITextViewer textViewer, IRegion hoverRegion )
     {
+        // check attribute type, object class or matching rule values
+        if ( schema != null )
+        {
+            LdapFilter filter = parser.getModel().getFilter( hoverRegion.getOffset() );
+
+            if ( filter.getFilterComponent() instanceof LdapFilterItemComponent )
+            {
+                LdapFilterItemComponent fc = ( LdapFilterItemComponent ) filter.getFilterComponent();
+                if ( fc.getAttributeToken() != null
+                    && fc.getAttributeToken().getOffset() <= hoverRegion.getOffset()
+                    && hoverRegion.getOffset() <= fc.getAttributeToken().getOffset()
+                        + fc.getAttributeToken().getLength() )
+                {
+                    String attributeType = fc.getAttributeToken().getValue();
+                    AttributeTypeDescription attributeTypeDescription = schema
+                        .getAttributeTypeDescription( attributeType );
+                    return attributeTypeDescription.getLine() != null ? attributeTypeDescription.getLine()
+                        .getUnfoldedValue() : null;
+                }
+                if ( fc.getAttributeToken() != null
+                    && IAttribute.OBJECTCLASS_ATTRIBUTE.equalsIgnoreCase( fc.getAttributeToken().getValue() )
+                    && fc.getValueToken() != null && fc.getValueToken().getOffset() <= hoverRegion.getOffset()
+                    && hoverRegion.getOffset() <= fc.getValueToken().getOffset() + fc.getValueToken().getLength() )
+                {
+                    String objectClass = fc.getValueToken().getValue();
+                    ObjectClassDescription objectClassDescription = schema.getObjectClassDescription( objectClass );
+                    return objectClassDescription.getLine() != null ? objectClassDescription.getLine()
+                        .getUnfoldedValue() : null;
+                }
+            }
+            if ( filter.getFilterComponent() instanceof LdapFilterExtensibleComponent )
+            {
+                LdapFilterExtensibleComponent fc = ( LdapFilterExtensibleComponent ) filter.getFilterComponent();
+                if ( fc.getAttributeToken() != null
+                    && fc.getAttributeToken().getOffset() <= hoverRegion.getOffset()
+                    && hoverRegion.getOffset() <= fc.getAttributeToken().getOffset()
+                        + fc.getAttributeToken().getLength() )
+                {
+                    String attributeType = fc.getAttributeToken().getValue();
+                    AttributeTypeDescription attributeTypeDescription = schema
+                        .getAttributeTypeDescription( attributeType );
+                    return attributeTypeDescription.getLine() != null ? attributeTypeDescription.getLine()
+                        .getUnfoldedValue() : null;
+                }
+                if ( fc.getMatchingRuleToken() != null
+                    && fc.getMatchingRuleToken().getOffset() <= hoverRegion.getOffset()
+                    && hoverRegion.getOffset() <= fc.getMatchingRuleToken().getOffset()
+                        + fc.getMatchingRuleToken().getLength() )
+                {
+                    String matchingRule = fc.getMatchingRuleToken().getValue();
+                    MatchingRuleDescription matchingRuleDescription = schema.getMatchingRuleDescription( matchingRule );
+                    return matchingRuleDescription.getLine() != null ? matchingRuleDescription.getLine()
+                        .getUnfoldedValue() : null;
+                }
+            }
+        }
+
+        // check invalid tokens
         LdapFilter[] invalidFilters = parser.getModel().getInvalidFilters();
         for ( int i = 0; i < invalidFilters.length; i++ )
         {
@@ -75,6 +154,7 @@
             }
         }
 
+        // check error tokens
         LdapFilterToken[] tokens = parser.getModel().getTokens();
         for ( int i = 0; i < tokens.length; i++ )
         {

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidget.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidget.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidget.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidget.java Fri Jun  8 14:42:18 2007
@@ -37,6 +37,8 @@
 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;
@@ -48,7 +50,7 @@
 
 /**
  * The FileterWidget could be used to specify an LDAP filter. 
- * It is composed of a text with a content assit to enter 
+ * It is composed of a combo with a content assist to enter 
  * a filter and a button to open a {@link FilterDialog}.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
@@ -78,6 +80,9 @@
     /** The inital filter. */
     private String initalFilter;
 
+    /** The filter parser. */
+    private LdapFilterParser parser;
+
 
     /**
      * Creates a new instance of FilterWidget.
@@ -129,9 +134,15 @@
         filterComboField.addFieldDecoration( fieldDecoration, SWT.TOP | SWT.LEFT, true );
         filterComboField.getLayoutControl().setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false ) );
         filterCombo = ( Combo ) filterComboField.getControl();
+        filterCombo.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                notifyListeners();
+            }
+        } );
 
-        // content proposal adapter
-        LdapFilterParser parser = new LdapFilterParser();
+        parser = new LdapFilterParser();
         contentAssistProcessor = new FilterContentAssistProcessor( parser );
         filterCPA = new ContentProposalAdapter( filterCombo, new ComboContentAdapter(), contentAssistProcessor,
             KeyStroke.getInstance( SWT.CTRL, ' ' ), null );
@@ -172,13 +183,14 @@
 
 
     /**
-     * Gets the filter.
+     * Gets the filter or null if the filter is invalid. 
      * 
-     * @return the filter
+     * @return the filter or null if the filter is invalid
      */
     public String getFilter()
     {
-        return filterCombo.getText();
+        parser.parse( filterCombo.getText() );
+        return parser.getModel().isValid() ? filterCombo.getText() : null;
     }
 
 
@@ -200,9 +212,13 @@
      */
     public void setConnection( IConnection connection )
     {
-        this.connection = connection;
-        contentAssistProcessor.setSchema( connection == null ? null : connection.getSchema() );
-        filterCPA.setAutoActivationCharacters( contentAssistProcessor.getCompletionProposalAutoActivationCharacters() );
+        if ( this.connection != connection )
+        {
+            this.connection = connection;
+            contentAssistProcessor.setSchema( connection == null ? null : connection.getSchema() );
+            filterCPA.setAutoActivationCharacters( contentAssistProcessor
+                .getCompletionProposalAutoActivationCharacters() );
+        }
     }
 
 

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidgetAutoEditStrategyAdapter.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidgetAutoEditStrategyAdapter.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidgetAutoEditStrategyAdapter.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/FilterWidgetAutoEditStrategyAdapter.java Fri Jun  8 14:42:18 2007
@@ -51,9 +51,6 @@
     /** The combo. */
     private Combo combo;
 
-    /** The filter parser. */
-    private LdapFilterParser parser;
-
     /** The old texts. */
     private List<String> oldTexts;
 
@@ -73,7 +70,6 @@
     public FilterWidgetAutoEditStrategyAdapter( Combo combo, LdapFilterParser parser )
     {
         this.combo = combo;
-        this.parser = parser;
 
         this.oldTexts = new ArrayList<String>();
         this.verifyEvents = new ArrayList<VerifyEvent>();
@@ -108,7 +104,7 @@
         if ( !inApplyComboCustomization )
         {
             String oldText = combo.getText();
-            parser.parse( oldText );
+            //parser.parse( oldText );
 
             oldTexts.add( oldText );
             verifyEvents.add( e );
@@ -138,7 +134,7 @@
 
             // apply auto edit strategy
             AutoEditParameters autoEditParameters = new AutoEditParameters( text, offset, length, -1, true );
-            autoEditStrategy.customizeAutoEditParameters( autoEditParameters );
+            autoEditStrategy.customizeAutoEditParameters( oldText, autoEditParameters );
 
             // get current selection
             Point oldSelection = combo.getSelection();

Modified: directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/SearchPageWrapper.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/SearchPageWrapper.java?view=diff&rev=545640&r1=545639&r2=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/SearchPageWrapper.java (original)
+++ directory/studio/trunk/ldapstudio-browser-common/src/main/java/org/apache/directory/ldapstudio/browser/common/widgets/search/SearchPageWrapper.java Fri Jun  8 14:42:18 2007
@@ -659,7 +659,7 @@
             searchModified = true;
             searchBaseWidget.saveDialogSettings();
         }
-        if ( filterWidget != null )
+        if ( filterWidget != null && filterWidget.getFilter() != null )
         {
             if ( !filterWidget.getFilter().equals( search.getFilter() ) )
             {
@@ -815,9 +815,9 @@
 
 
     /**
-     * Checks if is valid.
+     * Checks if the search page parameters are valid.
      * 
-     * @return true, if is valid
+     * @return true, it the search page parameters are valid
      */
     public boolean isValid()
     {
@@ -833,7 +833,7 @@
         {
             return false;
         }
-        if ( filterWidget != null && "".equals( filterWidget.getFilter() ) )
+        if ( filterWidget != null && filterWidget.getFilter() == null )
         {
             return false;
         }
@@ -842,6 +842,35 @@
     }
 
 
+    
+    /**
+     * Gets the error message or null if the search page is valid.
+     * 
+     * @return the error message or null if the search page is valid
+     */
+    public String getErrorMessage()
+    {
+        if ( connectionWidget != null && connectionWidget.getConnection() == null )
+        {
+            return "Please select a connection.";
+        }
+        if ( searchBaseWidget != null && searchBaseWidget.getDn() == null )
+        {
+            return "Please enter a valid search base DN.";
+        }
+        if ( searchNameText != null && "".equals( searchNameText.getText() ) )
+        {
+            return "Please enter a search name.";
+        }
+        if ( filterWidget != null && filterWidget.getFilter() == null )
+        {
+            return "Please enter a valid filter.";
+        }
+        
+        return null;
+    }
+    
+    
     /**
      * Sets the enabled state of the widget.
      * 

Added: directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/internal/model/DirectoryTypeDetector.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/internal/model/DirectoryTypeDetector.java?view=auto&rev=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/internal/model/DirectoryTypeDetector.java (added)
+++ directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/internal/model/DirectoryTypeDetector.java Fri Jun  8 14:42:18 2007
@@ -0,0 +1,15 @@
+
+package org.apache.directory.ldapstudio.browser.core.internal.model;
+
+import org.apache.directory.ldapstudio.browser.core.model.IRootDSE;
+
+public interface DirectoryTypeDetector
+{
+    /**
+     * Tries to detect the directory type from the given Root DSE.
+     * 
+     * @param rootDSE the Root DSE
+     * @return the directory type or null if unknown
+     */
+    public String detectDirectoryType( IRootDSE rootDSE );
+}

Added: directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/LdapFilterExtensibleComponent.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/LdapFilterExtensibleComponent.java?view=auto&rev=545640
==============================================================================
--- directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/LdapFilterExtensibleComponent.java (added)
+++ directory/studio/trunk/ldapstudio-browser-core/src/main/java/org/apache/directory/ldapstudio/browser/core/model/filter/LdapFilterExtensibleComponent.java Fri Jun  8 14:42:18 2007
@@ -0,0 +1,499 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.ldapstudio.browser.core.model.filter;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.directory.ldapstudio.browser.core.model.filter.parser.LdapFilterToken;
+
+
+/**
+ * The LdapFilterExtensibleComponent represents a extensible filter.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdapFilterExtensibleComponent extends LdapFilterComponent
+{
+    private LdapFilterToken attributeToken;
+
+    private LdapFilterToken dnAttrColonToken;
+    private LdapFilterToken dnAttrToken;
+
+    private LdapFilterToken matchingRuleColonToken;
+    private LdapFilterToken matchingRuleToken;
+
+    private LdapFilterToken equalsColonToken;
+    private LdapFilterToken equalsToken;
+
+    private LdapFilterToken valueToken;
+
+
+    /**
+     * Creates a new instance of LdapFilterExtensibleComponent.
+     * 
+     * @param parent the parent filter
+     */
+    public LdapFilterExtensibleComponent( LdapFilter parent )
+    {
+        super( parent );
+    }
+
+
+    /**
+     * Sets the attribute token.
+     * 
+     * @param attributeToken the attribute token
+     * 
+     * @return true, if set attribute token
+     */
+    public boolean setAttributeToken( LdapFilterToken attributeToken )
+    {
+        if ( this.attributeToken == null && attributeToken != null
+            && attributeToken.getType() == LdapFilterToken.EXTENSIBLE_ATTRIBUTE )
+        {
+            if ( super.getStartToken() == null )
+            {
+                super.setStartToken( attributeToken );
+            }
+            this.attributeToken = attributeToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the attribute token.
+     * 
+     * @return the attribute token
+     */
+    public LdapFilterToken getAttributeToken()
+    {
+        return attributeToken;
+    }
+
+
+    /**
+     * Sets the dn attr colon token.
+     * 
+     * @param dnAttrColonToken the dn attr colon token
+     * 
+     * @return true, if set dn attr colon token
+     */
+    public boolean setDnAttrColonToken( LdapFilterToken dnAttrColonToken )
+    {
+        if ( this.dnAttrColonToken == null && dnAttrColonToken != null
+            && dnAttrColonToken.getType() == LdapFilterToken.EXTENSIBLE_DNATTR_COLON )
+        {
+            if ( super.getStartToken() == null )
+            {
+                super.setStartToken( dnAttrColonToken );
+            }
+            this.dnAttrColonToken = dnAttrColonToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the dn attr colon token.
+     * 
+     * @return the dn attr colon token
+     */
+    public LdapFilterToken getDnAttrColonToken()
+    {
+        return dnAttrColonToken;
+    }
+
+
+    /**
+     * Sets the dn attr token.
+     * 
+     * @param dnAttrToken the dn attr token
+     * 
+     * @return true, if set dn attr token
+     */
+    public boolean setDnAttrToken( LdapFilterToken dnAttrToken )
+    {
+        if ( this.dnAttrToken == null && dnAttrToken != null
+            && dnAttrToken.getType() == LdapFilterToken.EXTENSIBLE_DNATTR )
+        {
+            this.dnAttrToken = dnAttrToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the dn attr token.
+     * 
+     * @return the dn attr token
+     */
+    public LdapFilterToken getDnAttrToken()
+    {
+        return dnAttrToken;
+    }
+
+
+    /**
+     * Sets the matching rule colon token.
+     * 
+     * @param matchingRuleColonToken the matching rule colon token
+     * 
+     * @return true, if set matching rule colon token
+     */
+    public boolean setMatchingRuleColonToken( LdapFilterToken matchingRuleColonToken )
+    {
+        if ( this.matchingRuleColonToken == null && matchingRuleColonToken != null
+            && matchingRuleColonToken.getType() == LdapFilterToken.EXTENSIBLE_MATCHINGRULEOID_COLON )
+        {
+            if ( super.getStartToken() == null )
+            {
+                super.setStartToken( matchingRuleColonToken );
+            }
+            this.matchingRuleColonToken = matchingRuleColonToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the matching rule colon token.
+     * 
+     * @return the matching rule colon token
+     */
+    public LdapFilterToken getMatchingRuleColonToken()
+    {
+        return matchingRuleColonToken;
+    }
+
+
+    /**
+     * Sets the matching rule token.
+     * 
+     * @param matchingRuleToken the matching rule token
+     * 
+     * @return true, if set matching rule token
+     */
+    public boolean setMatchingRuleToken( LdapFilterToken matchingRuleToken )
+    {
+        if ( this.matchingRuleToken == null && matchingRuleToken != null
+            && matchingRuleToken.getType() == LdapFilterToken.EXTENSIBLE_MATCHINGRULEOID )
+        {
+            this.matchingRuleToken = matchingRuleToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the matching rule token.
+     * 
+     * @return the matching rule token
+     */
+    public LdapFilterToken getMatchingRuleToken()
+    {
+        return matchingRuleToken;
+    }
+
+
+    /**
+     * Sets the equals colon token.
+     * 
+     * @param equalsColonToken the equals colon token
+     * 
+     * @return true, if set equals colon token
+     */
+    public boolean setEqualsColonToken( LdapFilterToken equalsColonToken )
+    {
+        if ( this.equalsColonToken == null && equalsColonToken != null
+            && equalsColonToken.getType() == LdapFilterToken.EXTENSIBLE_EQUALS_COLON )
+        {
+            this.equalsColonToken = equalsColonToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the equals colon token.
+     * 
+     * @return the equals colon token
+     */
+    public LdapFilterToken getEqualsColonToken()
+    {
+        return equalsColonToken;
+    }
+
+
+    /**
+     * Sets the equals token.
+     * 
+     * @param equalsToken the equals token
+     * 
+     * @return true, if set equals token
+     */
+    public boolean setEqualsToken( LdapFilterToken equalsToken )
+    {
+        if ( this.equalsToken == null && equalsToken != null && equalsToken.getType() == LdapFilterToken.EQUAL )
+        {
+            this.equalsToken = equalsToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the equals token.
+     * 
+     * @return the equals token
+     */
+    public LdapFilterToken getEqualsToken()
+    {
+        return equalsToken;
+    }
+
+
+    /**
+     * Sets the value token.
+     * 
+     * @param valueToken the value token
+     * 
+     * @return true, if set value token
+     */
+    public boolean setValueToken( LdapFilterToken valueToken )
+    {
+        if ( this.valueToken == null && valueToken != null && valueToken.getType() == LdapFilterToken.VALUE )
+        {
+            this.valueToken = valueToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the value token.
+     * 
+     * @return the value token
+     */
+    public LdapFilterToken getValueToken()
+    {
+        return this.valueToken;
+    }
+
+
+    /**
+     * @see org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterComponent#isValid()
+     */
+    public boolean isValid()
+    {
+        return startToken != null
+            && equalsColonToken != null
+            & equalsToken != null
+            && valueToken != null
+            &&
+
+            ( ( attributeToken != null
+                && ( ( dnAttrColonToken == null && dnAttrToken == null ) || ( dnAttrColonToken != null && dnAttrToken != null ) ) && ( ( matchingRuleColonToken == null && matchingRuleToken == null ) || ( matchingRuleColonToken != null && matchingRuleToken != null ) ) ) || ( attributeToken == null
+                && ( ( dnAttrColonToken == null && dnAttrToken == null ) || ( dnAttrColonToken != null && dnAttrToken != null ) )
+                && matchingRuleColonToken != null && matchingRuleToken != null ) );
+    }
+
+
+    /**
+     * @see org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterComponent#getTokens()
+     */
+    public LdapFilterToken[] getTokens()
+    {
+        // collect tokens
+        List<LdapFilterToken> tokenList = new ArrayList<LdapFilterToken>();
+        if ( this.attributeToken != null )
+        {
+            tokenList.add( this.attributeToken );
+        }
+        if ( this.dnAttrColonToken != null )
+        {
+            tokenList.add( this.dnAttrColonToken );
+        }
+        if ( this.dnAttrToken != null )
+        {
+            tokenList.add( this.dnAttrToken );
+        }
+        if ( this.matchingRuleColonToken != null )
+        {
+            tokenList.add( this.matchingRuleColonToken );
+        }
+        if ( this.matchingRuleToken != null )
+        {
+            tokenList.add( this.matchingRuleToken );
+        }
+        if ( this.equalsColonToken != null )
+        {
+            tokenList.add( this.equalsColonToken );
+        }
+        if ( this.equalsToken != null )
+        {
+            tokenList.add( this.equalsToken );
+        }
+        if ( this.valueToken != null )
+        {
+            tokenList.add( this.valueToken );
+        }
+
+        // sort tokens
+        LdapFilterToken[] tokens = tokenList.toArray( new LdapFilterToken[tokenList.size()] );
+        Arrays.sort( tokens );
+
+        // return
+        return tokens;
+    }
+
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return ( attributeToken != null ? startToken.getValue() : "" )
+            + ( dnAttrColonToken != null ? dnAttrColonToken.getValue() : "" )
+            + ( dnAttrToken != null ? dnAttrToken.getValue() : "" )
+            + ( matchingRuleColonToken != null ? matchingRuleColonToken.getValue() : "" )
+            + ( matchingRuleToken != null ? matchingRuleToken.getValue() : "" )
+            + ( equalsColonToken != null ? equalsColonToken.getValue() : "" )
+            + ( equalsToken != null ? equalsToken.getValue() : "" )
+            + ( valueToken != null ? valueToken.getValue() : "" );
+    }
+
+
+    /**
+     * @see org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterComponent#addFilter(org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilter)
+     */
+    public boolean addFilter( LdapFilter filter )
+    {
+        return false;
+    }
+
+
+    /**
+     * @see org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterComponent#getInvalidFilters()
+     */
+    public LdapFilter[] getInvalidFilters()
+    {
+        if ( isValid() )
+        {
+            return new LdapFilter[0];
+        }
+        else
+        {
+            return new LdapFilter[]
+                { parent };
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterComponent#getFilter(int)
+     */
+    public LdapFilter getFilter( int offset )
+    {
+        if ( startToken != null && startToken.getOffset() <= offset
+            && offset < startToken.getOffset() + toString().length() )
+        {
+            return parent;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.ldapstudio.browser.core.model.filter.LdapFilterComponent#getInvalidCause()
+     */
+    public String getInvalidCause()
+    {
+        if ( dnAttrColonToken != null && dnAttrToken == null )
+        {
+            return "Missing dn";
+        }
+        else if ( matchingRuleColonToken != null && matchingRuleToken == null )
+        {
+            return "Missing matching rule";
+        }
+        else if ( equalsColonToken == null )
+        {
+            return "Missing colon";
+        }
+        else if ( equalsToken == null )
+        {
+            return "Missing equals";
+        }
+        else if ( attributeToken == null )
+        {
+            return "Missing attribute type";
+        }
+        else if ( valueToken != null )
+        {
+            return "Missing value";
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+}



Mime
View raw message