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

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

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterContentAssistProcessor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterContentAssistProcessor.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterContentAssistProcessor.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterContentAssistProcessor.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,708 @@
+/*
+ *  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.filtereditor;
+
+
+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.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilter;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterExtensibleComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterItemComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterParser;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterToken;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.AttributeTypeDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.MatchingRuleDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.ObjectClassDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * The FilterContentAssistProcessor computes the content proposals for the filter editor.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class FilterContentAssistProcessor extends TemplateCompletionProcessor implements IContentAssistProcessor,
+    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;
+
+    /** The source viewer, may be null. */
+    private ISourceViewer sourceViewer;
+
+    /** The auto activation characters. */
+    private char[] autoActivationCharacters;
+
+    /** 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.
+     * 
+     * @param parser the parser
+     */
+    public FilterContentAssistProcessor( LdapFilterParser parser )
+    {
+        this( null, parser );
+    }
+
+
+    /**
+     * Creates a new instance of FilterContentAssistProcessor.
+     * 
+     * @param sourceViewer the source viewer
+     * @param parser the parser
+     */
+    public FilterContentAssistProcessor( ISourceViewer sourceViewer, LdapFilterParser parser )
+    {
+        this.parser = parser;
+        this.sourceViewer = sourceViewer;
+
+        this.autoActivationCharacters = new char[7 + 10 + 26 + 26];
+        this.autoActivationCharacters[0] = '(';
+        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;
+        }
+        for ( char c = 'A'; c <= 'Z'; c++, i++ )
+        {
+            this.autoActivationCharacters[i] = c;
+        }
+        for ( char c = '0'; c <= '9'; c++, i++ )
+        {
+            this.autoActivationCharacters[i] = c;
+        }
+    }
+
+
+    /**
+     * Sets the schema, used to retrieve attributeType and objectClass information.
+     * 
+     * @param schema the schema
+     */
+    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 );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getCompletionProposalAutoActivationCharacters()
+     */
+    public char[] getCompletionProposalAutoActivationCharacters()
+    {
+        return autoActivationCharacters;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
+     */
+    public ICompletionProposal[] computeCompletionProposals( ITextViewer viewer, int offset )
+    {
+        return computeCompletionProposals( offset );
+    }
+
+
+    /**
+     * @see org.eclipse.jface.fieldassist.IContentProposalProvider#getProposals(java.lang.String, int)
+     */
+    public IContentProposal[] getProposals( final String contents, final int position )
+    {
+        parser.parse( contents );
+
+        ICompletionProposal[] oldProposals = computeCompletionProposals( position );
+        IContentProposal[] proposals = new IContentProposal[oldProposals.length];
+        for ( int i = 0; i < oldProposals.length; i++ )
+        {
+            final ICompletionProposal oldProposal = oldProposals[i];
+            final Document document = new Document( contents );
+            oldProposal.apply( document );
+
+            proposals[i] = new IContentProposal()
+            {
+                public String getContent()
+                {
+                    return document.get();
+                }
+
+
+                public int getCursorPosition()
+                {
+                    return oldProposal.getSelection( document ).x;
+                }
+
+
+                public String getDescription()
+                {
+                    return oldProposal.getAdditionalProposalInfo();
+                }
+
+
+                public String getLabel()
+                {
+                    return oldProposal.getDisplayString();
+                }
+
+
+                public String toString()
+                {
+                    return getContent();
+                }
+            };
+        }
+
+        return proposals;
+    }
+
+
+    /**
+     * Computes completion proposals.
+     * 
+     * @param offset the offset
+     * 
+     * @return the matching completion proposals
+     */
+    private ICompletionProposal[] computeCompletionProposals( int offset )
+    {
+        String[] possibleObjectClasses = schema == null ? new String[0] : schema.getObjectClassDescriptionNames();
+        Arrays.sort( possibleObjectClasses );
+
+        List<ICompletionProposal> proposalList = new ArrayList<ICompletionProposal>();
+        LdapFilter filter = parser.getModel().getFilter( offset );
+        if ( filter != null )
+        {
+            // 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 );
+                    if ( templateProposals != null )
+                    {
+                        proposalList.addAll( Arrays.asList( templateProposals ) );
+                    }
+                }
+                addPossibleAttributeTypes( proposalList, "", offset );
+            }
+
+            // 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() )
+                {
+                    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 B: extensible filter
+            if ( filter.getFilterComponent() != null
+                && filter.getFilterComponent() instanceof LdapFilterExtensibleComponent )
+            {
+                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() )
+                {
+                    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 );
+                    }
+                    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 )
+                    {
+                        addDnAttr( proposalList, fc.getMatchingRuleToken().getValue(), fc.getMatchingRuleToken()
+                            .getOffset() );
+                    }
+
+                    String matchingRuleValue = fc.getMatchingRuleToken().getValue();
+                    addPossibleMatchingRules( proposalList, matchingRuleValue, fc.getMatchingRuleToken().getOffset(),
+                        fc.getEqualsColonToken(), fc.getEqualsToken() );
+                }
+            }
+        }
+
+        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() )
+            {
+                AttributeTypeDescription description = possibleAttributeTypes.get( possibleAttributeType );
+                if ( possibleAttributeType.toUpperCase().startsWith( attributeType.toUpperCase() ) )
+                {
+                    String replacementString = possibleAttributeType;
+                    String displayString = possibleAttributeType;
+                    if ( displayString.equals( description.getNumericOID() ) )
+                    {
+                        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( ">=" );
+            }
+
+            for ( String possibleFilterType : copy.keySet() )
+            {
+                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 );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 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() )
+            {
+                if ( possibleMatchingRule.toUpperCase().startsWith( matchingRule.toUpperCase() ) )
+                {
+                    MatchingRuleDescription description = schema.getMatchingRuleDescription( possibleMatchingRule );
+                    String replacementString = possibleMatchingRule;
+                    if ( equalsColonToken == null )
+                    {
+                        replacementString += ":";
+                    }
+                    if ( equalsToken == null )
+                    {
+                        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 );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 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 );
+        }
+    }
+
+
+    /**
+     * Gets the attribute type image.
+     * 
+     * @return the attribute type image
+     */
+    private Image getAttributeTypeImage()
+    {
+        return BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_ATD );
+    }
+
+
+    /**
+     * 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
+     */
+    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 );
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getTemplates(java.lang.String)
+     */
+    protected Template[] getTemplates( String contextTypeId )
+    {
+        Template[] templates = BrowserCommonActivator.getDefault().getFilterTemplateStore().getTemplates(
+            BrowserCommonConstants.FILTER_TEMPLATE_ID );
+        return templates;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getContextType(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
+     */
+    protected TemplateContextType getContextType( ITextViewer viewer, IRegion region )
+    {
+        TemplateContextType contextType = BrowserCommonActivator.getDefault().getFilterTemplateContextTypeRegistry()
+            .getContextType( BrowserCommonConstants.FILTER_TEMPLATE_ID );
+        return contextType;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getImage(org.eclipse.jface.text.templates.Template)
+     */
+    protected Image getImage( Template template )
+    {
+        return BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_TEMPLATE );
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
+     */
+    public IContextInformation[] computeContextInformation( ITextViewer viewer, int documentOffset )
+    {
+        return null;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+     */
+    public char[] getContextInformationAutoActivationCharacters()
+    {
+        return null;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
+     */
+    public String getErrorMessage()
+    {
+        return null;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
+     */
+    public IContextInformationValidator getContextInformationValidator()
+    {
+        return null;
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterDamagerRepairer.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterDamagerRepairer.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterDamagerRepairer.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterDamagerRepairer.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,169 @@
+/*
+ *  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.filtereditor;
+
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterParser;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterToken;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.RGB;
+
+
+/**
+ * The FilterDamagerRepairer is used for syntax highlighting.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class FilterDamagerRepairer implements IPresentationDamager, IPresentationRepairer
+{
+
+    private static final TextAttribute DEFAULT_TEXT_ATTRIBUTE = new TextAttribute( BrowserCommonActivator.getDefault()
+        .getColor( new RGB( 0, 0, 0 ) ) );
+
+    private static final TextAttribute AND_OR_NOT_TEXT_ATTRIBUTE = new TextAttribute( BrowserCommonActivator
+        .getDefault().getColor( new RGB( 0, 127, 0 ) ), null, SWT.BOLD );
+
+    private static final TextAttribute ATTRIBUTE_TEXT_ATTRIBUTE = new TextAttribute( BrowserCommonActivator
+        .getDefault().getColor( new RGB( 127, 0, 85 ) ) );
+
+    private static final TextAttribute FILTER_TYPE_TEXT_ATTRIBUTE = new TextAttribute( BrowserCommonActivator
+        .getDefault().getColor( new RGB( 255, 0, 0 ) ), null, SWT.BOLD );
+
+    private static final TextAttribute VALUE_TEXT_ATTRIBUTE = new TextAttribute( BrowserCommonActivator.getDefault()
+        .getColor( new RGB( 0, 0, 127 ) ) );
+
+    private static final TextAttribute PARENTHESIS_TEXT_ATTRIBUTE = new TextAttribute( BrowserCommonActivator
+        .getDefault().getColor( new RGB( 0, 0, 0 ) ), null, SWT.BOLD );
+
+    /** The filter parser. */
+    private LdapFilterParser parser;
+
+    /** The document. */
+    private IDocument document;
+
+
+    /**
+     * Creates a new instance of FilterDamagerRepairer.
+     * 
+     * @param parser the filter parser
+     */
+    public FilterDamagerRepairer( LdapFilterParser parser )
+    {
+        this.parser = parser;
+        this.document = null;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.presentation.IPresentationDamager#setDocument(org.eclipse.jface.text.IDocument)
+     */
+    public void setDocument( IDocument document )
+    {
+        this.document = document;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.presentation.IPresentationDamager#getDamageRegion(org.eclipse.jface.text.ITypedRegion, org.eclipse.jface.text.DocumentEvent, boolean)
+     */
+    public IRegion getDamageRegion( ITypedRegion partition, DocumentEvent event, boolean documentPartitioningChanged )
+    {
+        return partition;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.presentation.IPresentationRepairer#createPresentation(org.eclipse.jface.text.TextPresentation, org.eclipse.jface.text.ITypedRegion)
+     */
+    public void createPresentation( TextPresentation presentation, ITypedRegion damage )
+    {
+        // parse the filter
+        parser.parse( this.document.get() );
+
+        // get tokens
+        LdapFilterToken[] tokens = parser.getModel().getTokens();
+
+        // syntax highlighting
+        for ( int i = 0; i < tokens.length; i++ )
+        {
+            switch ( tokens[i].getType() )
+            {
+                case LdapFilterToken.LPAR:
+                case LdapFilterToken.RPAR:
+                    this.addStyleRange( presentation, tokens[i], PARENTHESIS_TEXT_ATTRIBUTE );
+                    break;
+                case LdapFilterToken.AND:
+                case LdapFilterToken.OR:
+                case LdapFilterToken.NOT:
+                    this.addStyleRange( presentation, tokens[i], AND_OR_NOT_TEXT_ATTRIBUTE );
+                    break;
+                case LdapFilterToken.EQUAL:
+                case LdapFilterToken.GREATER:
+                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:
+                    this.addStyleRange( presentation, tokens[i], VALUE_TEXT_ATTRIBUTE );
+                    break;
+                default:
+                    this.addStyleRange( presentation, tokens[i], DEFAULT_TEXT_ATTRIBUTE );
+            }
+        }
+    }
+
+
+    /**
+     * Adds the style range.
+     * 
+     * @param presentation the presentation
+     * @param textAttribute the text attribute
+     * @param token the token
+     */
+    private void addStyleRange( TextPresentation presentation, LdapFilterToken token, TextAttribute textAttribute )
+    {
+        StyleRange range = new StyleRange( token.getOffset(), token.getLength(), textAttribute.getForeground(),
+            textAttribute.getBackground(), textAttribute.getStyle() );
+        presentation.addStyleRange( range );
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterFormattingStrategy.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterFormattingStrategy.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterFormattingStrategy.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterFormattingStrategy.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,175 @@
+/*
+ *  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.filtereditor;
+
+
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapAndFilterComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilter;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterExtensibleComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterItemComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapNotFilterComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapOrFilterComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterParser;
+import org.eclipse.jface.text.formatter.IFormattingStrategy;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+
+/**
+ * The FilterFormattingStrategy is used to format the LDAP filter in the
+ * filter editor.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class FilterFormattingStrategy implements IFormattingStrategy
+{
+
+    /** The filter parser. */
+    private LdapFilterParser parser;
+
+    /** The source viewer. */
+    private ISourceViewer sourceViewer;
+
+
+    /**
+     * Creates a new instance of FilterFormattingStrategy.
+     * 
+     * @param sourceViewer the source viewer
+     * @param parser the filter parser
+     */
+    public FilterFormattingStrategy( ISourceViewer sourceViewer, LdapFilterParser parser )
+    {
+        this.parser = parser;
+        this.sourceViewer = sourceViewer;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.formatter.IFormattingStrategy#formatterStarts(java.lang.String)
+     */
+    public void formatterStarts( String initialIndentation )
+    {
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.formatter.IFormattingStrategy#format(java.lang.String, boolean, java.lang.String, int[])
+     */
+    public String format( String content, boolean isLineStart, String indentation, int[] positions )
+    {
+        // this.parser.parse(content);
+        LdapFilter model = parser.getModel();
+        if ( model != null && model.isValid() )
+        {
+            sourceViewer.getDocument().set( getFormattedFilter( model, 0 ) );
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Gets the formatted string respresentation of the filter.
+     * 
+     * @param filter the filter
+     * @param indent the indent
+     * 
+     * @return the formatted string respresentation of the filter
+     */
+    private String getFormattedFilter( LdapFilter filter, int indent )
+    {
+        StringBuffer sb = new StringBuffer();
+
+        for ( int i = 0; i < indent; i++ )
+        {
+            sb.append( FilterAutoEditStrategy.INDENT_STRING );
+        }
+
+        LdapFilterComponent fc = filter.getFilterComponent();
+        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 )
+        {
+            sb.append( "(!" );
+            LdapNotFilterComponent lnfc = ( LdapNotFilterComponent ) fc;
+            if ( lnfc.getFilters().length > 0
+                && lnfc.getFilters()[0].getFilterComponent() instanceof LdapFilterItemComponent )
+            {
+                sb.append( getFormattedFilter( ( lnfc ).getFilters()[0], 0 ) );
+            }
+            else
+            {
+                sb.append( '\n' );
+                sb.append( getFormattedFilter( ( lnfc ).getFilters()[0], indent + 1 ) );
+                sb.append( '\n' );
+                for ( int i = 0; i < indent; i++ )
+                    sb.append( FilterAutoEditStrategy.INDENT_STRING );
+            }
+            sb.append( ')' );
+        }
+        else if ( fc instanceof LdapAndFilterComponent )
+        {
+            sb.append( "(&" );
+            sb.append( '\n' );
+            LdapFilter[] filters = ( ( LdapAndFilterComponent ) fc ).getFilters();
+            for ( int i = 0; i < filters.length; i++ )
+            {
+                sb.append( getFormattedFilter( filters[i], indent + 1 ) );
+                sb.append( '\n' );
+            }
+            for ( int i = 0; i < indent; i++ )
+                sb.append( FilterAutoEditStrategy.INDENT_STRING );
+            sb.append( ')' );
+        }
+        else if ( fc instanceof LdapOrFilterComponent )
+        {
+            sb.append( "(|" );
+            sb.append( '\n' );
+            LdapFilter[] filters = ( ( LdapOrFilterComponent ) fc ).getFilters();
+            for ( int i = 0; i < filters.length; i++ )
+            {
+                sb.append( getFormattedFilter( filters[i], indent + 1 ) );
+                sb.append( '\n' );
+            }
+            for ( int i = 0; i < indent; i++ )
+                sb.append( FilterAutoEditStrategy.INDENT_STRING );
+            sb.append( ')' );
+        }
+
+        return sb.toString();
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.formatter.IFormattingStrategy#formatterStops()
+     */
+    public void formatterStops()
+    {
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterReconcilingStrategy.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterReconcilingStrategy.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterReconcilingStrategy.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterReconcilingStrategy.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,178 @@
+/*
+ *  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.filtereditor;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilter;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterParser;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterToken;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.PaintManager;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.AnnotationPainter;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelExtension;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.MatchingCharacterPainter;
+import org.eclipse.swt.graphics.RGB;
+
+
+/**
+ * The FilterReconcilingStrategy is used to maintain the error annotations 
+ * (red squirrels).
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class FilterReconcilingStrategy implements IReconcilingStrategy
+{
+
+    /** The source viewer. */
+    private ISourceViewer sourceViewer;
+
+    /** The filter parser. */
+    private LdapFilterParser parser;
+
+    /** The paint manager. */
+    private PaintManager paintManager;
+
+
+    /**
+     * Creates a new instance of FilterReconcilingStrategy.
+     * 
+     * @param sourceViewer the source viewer
+     * @param parser the filter parser
+     */
+    public FilterReconcilingStrategy( ISourceViewer sourceViewer, LdapFilterParser parser )
+    {
+        this.sourceViewer = sourceViewer;
+        this.parser = parser;
+        this.paintManager = null;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
+     */
+    public void setDocument( IDocument document )
+    {
+        if ( sourceViewer.getAnnotationModel() == null )
+        {
+            IAnnotationModel model = new AnnotationModel();
+            sourceViewer.setDocument( sourceViewer.getDocument(), model );
+        }
+
+        // add annotation painter
+        if ( paintManager == null && sourceViewer.getAnnotationModel() instanceof IAnnotationModelExtension )
+        {
+            AnnotationPainter ap = new AnnotationPainter( sourceViewer, null );
+            ap.addAnnotationType( "DEFAULT" );
+            ap.setAnnotationTypeColor( "DEFAULT", BrowserCommonActivator.getDefault().getColor( new RGB( 255, 0, 0 ) ) );
+            sourceViewer.getAnnotationModel().addAnnotationModelListener( ap );
+
+            FilterCharacterPairMatcher cpm = new FilterCharacterPairMatcher( sourceViewer, parser );
+            MatchingCharacterPainter mcp = new MatchingCharacterPainter( sourceViewer, cpm );
+            mcp.setColor( BrowserCommonActivator.getDefault().getColor( new RGB( 159, 159, 159 ) ) );
+
+            paintManager = new PaintManager( sourceViewer );
+            paintManager.addPainter( ap );
+            paintManager.addPainter( mcp );
+        }
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion, org.eclipse.jface.text.IRegion)
+     */
+    public void reconcile( DirtyRegion dirtyRegion, IRegion subRegion )
+    {
+        reconcile( dirtyRegion );
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
+     */
+    public void reconcile( IRegion partition )
+    {
+
+        LdapFilterToken[] tokens = parser.getModel().getTokens();
+
+        // annotations
+        if ( sourceViewer.getAnnotationModel() instanceof IAnnotationModelExtension )
+        {
+            ( ( IAnnotationModelExtension ) sourceViewer.getAnnotationModel() ).removeAllAnnotations();
+
+            List<Position> positionList = new ArrayList<Position>();
+
+            LdapFilter[] invalidFilters = parser.getModel().getInvalidFilters();
+            for ( int i = 0; i < invalidFilters.length; i++ )
+            {
+                if ( invalidFilters[i].getStartToken() != null )
+                {
+                    int start = invalidFilters[i].getStartToken().getOffset();
+                    int stop = invalidFilters[i].getStopToken() != null ? invalidFilters[i].getStopToken().getOffset()
+                        + invalidFilters[i].getStopToken().getLength() : start
+                        + invalidFilters[i].getStartToken().getLength();
+
+                    Annotation annotation = new Annotation( "DEFAULT", true, invalidFilters[i].toString() );
+                    Position position = new Position( start, stop - start );
+                    positionList.add( position );
+                    sourceViewer.getAnnotationModel().addAnnotation( annotation, position );
+                }
+            }
+
+            for ( int i = 0; i < tokens.length; i++ )
+            {
+                if ( tokens[i].getType() == LdapFilterToken.ERROR )
+                {
+
+                    boolean overlaps = false;
+                    for ( int k = 0; k < positionList.size(); k++ )
+                    {
+                        Position pos = positionList.get( k );
+                        if ( pos.overlapsWith( tokens[i].getOffset(), tokens[i].getLength() ) )
+                        {
+                            overlaps = true;
+                            break;
+                        }
+                    }
+                    if ( !overlaps )
+                    {
+                        Annotation annotation = new Annotation( "DEFAULT", true, tokens[i].getValue() );
+                        Position position = new Position( tokens[i].getOffset(), tokens[i].getLength() );
+                        sourceViewer.getAnnotationModel().addAnnotation( annotation, position );
+                    }
+                }
+            }
+        }
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterSourceViewerConfiguration.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterSourceViewerConfiguration.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterSourceViewerConfiguration.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterSourceViewerConfiguration.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,241 @@
+/*
+ *  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.filtereditor;
+
+
+import org.apache.directory.studio.ldapbrowser.common.widgets.DialogContentAssistant;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.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;
+import org.eclipse.jface.text.formatter.IContentFormatter;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+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;
+
+
+/**
+ * The FilterSourceViewerConfiguration implements the configuration of
+ * the source viewer.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class FilterSourceViewerConfiguration extends SourceViewerConfiguration
+{
+
+    /** The current connection, used to retrieve schema information. */
+    private IBrowserConnection connection;
+
+    /** The filter parser. */
+    private LdapFilterParser parser;
+
+    /** The presentation reconciler, used for syntax highlighting. */
+    private PresentationReconciler presentationReconciler;
+
+    /** The damager repairer, used for syntax highlighting. */
+    private FilterDamagerRepairer damagerRepairer;
+
+    /** The reconciler, used to maintain error annotations. */
+    private MonoReconciler reconciler;
+
+    /** The reconciling strategy, used to maintain error annotations. */
+    private FilterReconcilingStrategy reconcilingStrategy;
+
+    /** The text hover, used to display error message tooltips. */
+    private FilterTextHover textHover;
+
+    /** The auto edit strategy, used for smart parentesis handling. */
+    private FilterAutoEditStrategy[] autoEditStrategies;
+
+    /** The formatter, used to format the filter. */
+    private ContentFormatter formatter;
+
+    /** The formatting strategy, used to format the filter. */
+    private FilterFormattingStrategy formattingStrategy;
+
+    /** The content assistant, used for content proposals. */
+    private DialogContentAssistant contentAssistant;
+
+    /** The content assist processor, used for content proposals. */
+    private FilterContentAssistProcessor contentAssistProcessor;
+
+
+    /**
+     * Creates a new instance of FilterSourceViewerConfiguration.
+     * 
+     * @param parser the filer parser
+     * @param connection the connection
+     */
+    public FilterSourceViewerConfiguration( LdapFilterParser parser, IBrowserConnection connection )
+    {
+        this.parser = parser;
+        this.connection = connection;
+    }
+
+
+    /**
+     * Sets the connection.
+     * 
+     * @param connection the connection
+     */
+    public void setConnection( IBrowserConnection connection )
+    {
+        this.connection = connection;
+        contentAssistProcessor.setSchema( connection == null ? null : connection.getSchema() );
+        textHover.setSchema( connection == null ? null : connection.getSchema() );
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer)
+     */
+    public IPresentationReconciler getPresentationReconciler( ISourceViewer sourceViewer )
+    {
+        if ( damagerRepairer == null )
+        {
+            damagerRepairer = new FilterDamagerRepairer( parser );
+        }
+        if ( presentationReconciler == null )
+        {
+            presentationReconciler = new PresentationReconciler();
+            presentationReconciler.setDamager( damagerRepairer, IDocument.DEFAULT_CONTENT_TYPE );
+            presentationReconciler.setRepairer( damagerRepairer, IDocument.DEFAULT_CONTENT_TYPE );
+        }
+        return presentationReconciler;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+     */
+    public ITextHover getTextHover( ISourceViewer sourceViewer, String contentType )
+    {
+        if ( textHover == null )
+        {
+            textHover = new FilterTextHover( parser );
+            textHover.setSchema( connection == null ? null : connection.getSchema() );
+        }
+        return textHover;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer)
+     */
+    public IReconciler getReconciler( ISourceViewer sourceViewer )
+    {
+        if ( reconcilingStrategy == null )
+        {
+            reconcilingStrategy = new FilterReconcilingStrategy( sourceViewer, parser );
+        }
+        if ( reconciler == null )
+        {
+            reconciler = new MonoReconciler( reconcilingStrategy, false );
+        }
+        return reconciler;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+     */
+    public IAutoEditStrategy[] getAutoEditStrategies( ISourceViewer sourceViewer, String contentType )
+    {
+        if ( autoEditStrategies == null )
+        {
+            autoEditStrategies = new FilterAutoEditStrategy[]
+                { new FilterAutoEditStrategy( parser ) };
+        }
+        return autoEditStrategies;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentFormatter(org.eclipse.jface.text.source.ISourceViewer)
+     */
+    public IContentFormatter getContentFormatter( ISourceViewer sourceViewer )
+    {
+        if ( formattingStrategy == null )
+        {
+            formattingStrategy = new FilterFormattingStrategy( sourceViewer, parser );
+        }
+        if ( formatter == null )
+        {
+            formatter = new ContentFormatter();
+            formatter.enablePartitionAwareFormatting( false );
+            formatter.setFormattingStrategy( formattingStrategy, IDocument.DEFAULT_CONTENT_TYPE );
+        }
+        return formatter;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer)
+     */
+    public IContentAssistant getContentAssistant( ISourceViewer sourceViewer )
+    {
+        if ( contentAssistProcessor == null )
+        {
+            contentAssistProcessor = new FilterContentAssistProcessor( sourceViewer, parser );
+            contentAssistProcessor.setSchema( connection == null ? null : connection.getSchema() );
+        }
+        if ( contentAssistant == null )
+        {
+            contentAssistant = new DialogContentAssistant();
+            contentAssistant.enableAutoInsert( true );
+            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 );
+            }
+        };
+    }
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterTextHover.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterTextHover.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterTextHover.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/filtereditor/FilterTextHover.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,184 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.studio.ldapbrowser.common.filtereditor;
+
+
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilter;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterExtensibleComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterItemComponent;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterParser;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterToken;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.AttributeTypeDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.MatchingRuleDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.ObjectClassDescription;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+
+
+/**
+ * The FilterTextHover is used to display error messages in a tooltip.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class FilterTextHover implements ITextHover
+{
+
+    /** The filter parser. */
+    private LdapFilterParser parser;
+
+    /** The schema, used to retrieve attributeType and objectClass information. */
+    private Schema schema;
+
+
+    /**
+     * Creates a new instance of FilterTextHover.
+     *
+     * @param parser filter parser
+     */
+    public FilterTextHover( LdapFilterParser parser )
+    {
+        this.parser = parser;
+    }
+
+
+    /**
+     * 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++ )
+        {
+            if ( invalidFilters[i].getStartToken() != null )
+            {
+                int start = invalidFilters[i].getStartToken().getOffset();
+                int stop = invalidFilters[i].getStopToken() != null ? invalidFilters[i].getStopToken().getOffset()
+                    + invalidFilters[i].getStopToken().getLength() : start
+                    + invalidFilters[i].getStartToken().getLength();
+                if ( start <= hoverRegion.getOffset() && hoverRegion.getOffset() < stop )
+                {
+                    return invalidFilters[i].getInvalidCause();
+                }
+            }
+        }
+
+        // check error tokens
+        LdapFilterToken[] tokens = parser.getModel().getTokens();
+        for ( int i = 0; i < tokens.length; i++ )
+        {
+            if ( tokens[i].getType() == LdapFilterToken.ERROR )
+            {
+
+                int start = tokens[i].getOffset();
+                int stop = start + tokens[i].getLength();
+                if ( start <= hoverRegion.getOffset() && hoverRegion.getOffset() < stop )
+                {
+                    return "Invalid characters";
+                }
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
+     */
+    public IRegion getHoverRegion( ITextViewer textViewer, int offset )
+    {
+        return new Region( offset, 1 );
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/jobs/RunnableContextJobAdapter.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/jobs/RunnableContextJobAdapter.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/jobs/RunnableContextJobAdapter.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/jobs/RunnableContextJobAdapter.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,112 @@
+/*
+ *  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.jobs;
+
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Display;
+
+
+/**
+ * This class provides some convinience methods to execute a job within
+ * an {@link IRunnableContext}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class RunnableContextJobAdapter
+{
+
+    /**
+     * Executes the given job within a new {@link ProgressMonitorDialog}.
+     *
+     * @param job the job to execute
+     */
+    public static void execute( final AbstractEclipseJob job )
+    {
+        execute( job, null );
+    }
+
+
+    /**
+     * Executes the given job within the given runnable context and enabled error handling
+     * 
+     * @param runnableContext the runnable context
+     * @param job the job to execute
+     */
+    public static void execute( final AbstractEclipseJob job, IRunnableContext runnableContext )
+    {
+        execute( job, runnableContext, true );
+    }
+
+
+    /**
+     * Executes the given job within the given runnable context.
+     * 
+     * @param runnableContext the runnable context
+     * @param job the job to execute
+     * @param handleError true to handle errors
+     */
+    public static void execute( final AbstractEclipseJob job, IRunnableContext runnableContext, boolean handleError )
+    {
+
+        if ( runnableContext == null )
+        {
+            runnableContext = new ProgressMonitorDialog( Display.getDefault().getActiveShell() );
+        }
+
+        IRunnableWithProgress runnable = new IRunnableWithProgress()
+        {
+            public void run( IProgressMonitor ipm ) throws InterruptedException
+            {
+                job.setExternalProgressMonitor( ipm );
+                job.execute();
+                job.join();
+            }
+        };
+
+        try
+        {
+            runnableContext.run( true, true, runnable );
+        }
+        catch ( Exception ex )
+        {
+            BrowserCommonActivator.getDefault().getExceptionHandler().handleException(
+                new Status( IStatus.ERROR, BrowserCommonActivator.PLUGIN_ID, IStatus.ERROR,
+                    ex.getMessage() != null ? ex.getMessage() : "", ex ) );
+        }
+
+        if ( handleError && !job.getExternalResult().isOK() )
+        {
+            IStatus status = job.getExternalResult();
+            BrowserCommonActivator.getDefault().getExceptionHandler().handleException( status );
+        }
+
+    }
+
+}

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