directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fel...@apache.org
Subject svn commit: r592082 [9/20] - in /directory/sandbox/felixk/studio-ldapbrowser-core: ./ 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/ sr...
Date Mon, 05 Nov 2007 16:52:07 GMT
Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/Password.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/Password.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/Password.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/Password.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,449 @@
+/*
+ *  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.core.model;
+
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.utils.LdifUtils;
+import org.apache.directory.studio.ldapbrowser.core.utils.UnixCrypt;
+
+
+/**
+ * The Password class is used to represent a hashed or plain text password.
+ * It provides methods to retrieve information about the used hash method. 
+ * And it provides a verify method to check if the hashed password is equal to 
+ * a given plain text password.  
+ * 
+ * The following hash methods are supported:
+ * <ul>
+ *   <li>SHA</li>
+ *   <li>SSHA</li>
+ *   <li>MD5</li>
+ *   <li>SMD5</li>
+ *   <li>CRYPT</li>
+ * </ul>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class Password
+{
+    /** The constant used for the SHA hash, value <code>SHA</code> */
+    public static final String HASH_METHOD_SHA = "SHA"; //$NON-NLS-1$
+
+    /** The constant used for the salted SHA hash, value <code>SSHA</code> */
+    public static final String HASH_METHOD_SSHA = "SSHA"; //$NON-NLS-1$
+
+    /** The constant used for the MD5 hash, value <code>MD5</code> */
+    public static final String HASH_METHOD_MD5 = "MD5"; //$NON-NLS-1$
+
+    /** The constant used for the salted MD5 hash, value <code>SMD5</code> */
+    public static final String HASH_METHOD_SMD5 = "SMD5"; //$NON-NLS-1$
+
+    /** The constant used for the crypt hash, value <code>CRYPT</code> */
+    public static final String HASH_METHOD_CRYPT = "CRYPT"; //$NON-NLS-1$
+
+    /** The constant used for plain text passwords */
+    public static final String HASH_METHOD_NO = BrowserCoreMessages.model__no_hash;
+
+    /** The constant used for unsupported hash methods */
+    public static final String HASH_METHOD_UNSUPPORTED = BrowserCoreMessages.model__unsupported_hash;
+
+    /** The hash method. */
+    private String hashMethod;
+
+    /** The hashed password. */
+    private byte[] hashedPassword;
+
+    /** The salt. */
+    private byte[] salt;
+
+    /** The trash, used for unknown hash methods. */
+    private String trash;
+
+
+    /**
+     * Creates a new instance of Password.
+     *
+     * @param password the password, either hashed or plain text
+     */
+    public Password( byte[] password )
+    {
+        this( LdifUtils.utf8decode( password ) );
+    }
+
+
+    /**
+     * Creates a new instance of Password.
+     *
+     * @param password the password, either hashed or plain text
+     */
+    public Password( String password )
+    {
+        if ( password == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_password );
+        }
+        else if ( password.indexOf( '{' ) == 0 && password.indexOf( '}' ) > 0 )
+        {
+            hashMethod = password.substring( password.indexOf( '{' ) + 1, password.indexOf( '}' ) );
+            String rest = password.substring( hashMethod.length() + 2 );
+
+            if ( HASH_METHOD_SHA.equalsIgnoreCase( hashMethod ) || HASH_METHOD_MD5.equalsIgnoreCase( hashMethod ) )
+            {
+                hashedPassword = LdifUtils.base64decodeToByteArray( rest );
+                salt = null;
+            }
+            else if ( HASH_METHOD_SSHA.equalsIgnoreCase( hashMethod ) )
+            {
+                byte[] hashedPasswordWithSalt = LdifUtils.base64decodeToByteArray( rest );
+                hashedPassword = new byte[20];
+                salt = new byte[hashedPasswordWithSalt.length - hashedPassword.length];
+                split( hashedPasswordWithSalt, hashedPassword, salt );
+            }
+            else if ( HASH_METHOD_SMD5.equalsIgnoreCase( hashMethod ) )
+            {
+                byte[] hashedPasswordWithSalt = LdifUtils.base64decodeToByteArray( rest );
+                hashedPassword = new byte[16];
+                salt = new byte[hashedPasswordWithSalt.length - hashedPassword.length];
+                split( hashedPasswordWithSalt, hashedPassword, salt );
+            }
+            else if ( HASH_METHOD_CRYPT.equalsIgnoreCase( hashMethod ) )
+            {
+                byte[] saltWithPassword = LdifUtils.utf8encode( rest );
+                salt = new byte[2];
+                hashedPassword = new byte[saltWithPassword.length - salt.length];
+                split( saltWithPassword, salt, hashedPassword );
+            }
+            else
+            {
+                // throw new IllegalArgumentException("Unsupported hash method
+                // '"+hashMethod+"'");
+                // handle as plain text?
+                hashMethod = HASH_METHOD_UNSUPPORTED;
+                trash = password;
+                // salt = null;
+            }
+        }
+        else
+        {
+            // plain text
+            hashMethod = null;
+            hashedPassword = LdifUtils.utf8encode( password );
+            salt = null;
+        }
+    }
+
+
+    /**
+     * Creates a new instance of Password and calculates the hashed password.
+     *
+     * @param hashMethod the hash method to use
+     * @param passwordAsPlaintext the plain text password
+     * 
+     * @throws IllegalArgumentException if the given hash method is not
+     *         supported of if the given password is null
+     */
+    public Password( String hashMethod, String passwordAsPlaintext )
+    {
+        if ( !( hashMethod == null || HASH_METHOD_NO.equalsIgnoreCase( hashMethod ) || HASH_METHOD_SHA.equalsIgnoreCase( hashMethod )
+            || HASH_METHOD_SSHA.equalsIgnoreCase( hashMethod ) || HASH_METHOD_MD5.equalsIgnoreCase( hashMethod )
+            || HASH_METHOD_SMD5.equalsIgnoreCase( hashMethod ) || HASH_METHOD_CRYPT.equalsIgnoreCase( hashMethod ) ) )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__unsupported_hash );
+        }
+        if ( passwordAsPlaintext == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_password );
+        }
+
+        // set hash method
+        if ( HASH_METHOD_NO.equalsIgnoreCase( hashMethod ) )
+        {
+            hashMethod = null;
+        }
+        this.hashMethod = hashMethod;
+
+        // set salt
+        if ( HASH_METHOD_SSHA.equalsIgnoreCase( hashMethod ) || HASH_METHOD_SMD5.equalsIgnoreCase( hashMethod ) )
+        {
+            this.salt = new byte[8];
+            new SecureRandom().nextBytes( this.salt );
+        }
+        else if ( HASH_METHOD_CRYPT.equalsIgnoreCase( hashMethod ) )
+        {
+            this.salt = new byte[2];
+            SecureRandom sr = new SecureRandom();
+            int i1 = sr.nextInt( 64 );
+            int i2 = sr.nextInt( 64 );
+            this.salt[0] = ( byte ) ( i1 < 12 ? ( i1 + '.' ) : i1 < 38 ? ( i1 + 'A' - 12 ) : ( i1 + 'a' - 38 ) );
+            this.salt[1] = ( byte ) ( i2 < 12 ? ( i2 + '.' ) : i2 < 38 ? ( i2 + 'A' - 12 ) : ( i2 + 'a' - 38 ) );
+        }
+        else
+        {
+            this.salt = null;
+        }
+
+        // digest
+        if ( HASH_METHOD_SHA.equalsIgnoreCase( hashMethod ) || HASH_METHOD_SSHA.equalsIgnoreCase( hashMethod ) )
+        {
+            this.hashedPassword = digest( HASH_METHOD_SHA, passwordAsPlaintext, this.salt );
+        }
+        else if ( HASH_METHOD_MD5.equalsIgnoreCase( hashMethod ) || HASH_METHOD_SMD5.equalsIgnoreCase( hashMethod ) )
+        {
+            this.hashedPassword = digest( HASH_METHOD_MD5, passwordAsPlaintext, this.salt );
+        }
+        else if ( HASH_METHOD_CRYPT.equalsIgnoreCase( hashMethod ) )
+        {
+            this.hashedPassword = crypt( passwordAsPlaintext, this.salt );
+        }
+        else if ( hashMethod == null )
+        {
+            this.hashedPassword = LdifUtils.utf8encode( passwordAsPlaintext );
+        }
+    }
+
+
+    /**
+     * Verifies if this password is equal to the given test password.
+     * 
+     * @param testPasswordAsPlaintext the test password as plaintext
+     * 
+     * @return true, if equal
+     */
+    public boolean verify( String testPasswordAsPlaintext )
+    {
+        if ( testPasswordAsPlaintext == null )
+        {
+            return false;
+        }
+
+        boolean verified = false;
+        if ( hashMethod == null )
+        {
+            verified = testPasswordAsPlaintext.equals( LdifUtils.utf8decode( hashedPassword ) );
+        }
+        else if ( HASH_METHOD_SHA.equalsIgnoreCase( hashMethod ) || HASH_METHOD_SSHA.equalsIgnoreCase( hashMethod ) )
+        {
+            byte[] hash = digest( HASH_METHOD_SHA, testPasswordAsPlaintext, salt );
+            verified = equals( hash, hashedPassword );
+        }
+        else if ( HASH_METHOD_MD5.equalsIgnoreCase( hashMethod ) || HASH_METHOD_SMD5.equalsIgnoreCase( hashMethod ) )
+        {
+            byte[] hash = digest( HASH_METHOD_MD5, testPasswordAsPlaintext, salt );
+            verified = equals( hash, hashedPassword );
+        }
+        else if ( HASH_METHOD_CRYPT.equalsIgnoreCase( hashMethod ) )
+        {
+            byte[] crypted = crypt( testPasswordAsPlaintext, salt );
+            verified = equals( crypted, hashedPassword );
+        }
+
+        return verified;
+    }
+
+
+    /**
+     * Gets the hash method.
+     * 
+     * @return the hash method
+     */
+    public String getHashMethod()
+    {
+        return hashMethod;
+    }
+
+
+    /**
+     * Gets the hashed password.
+     * 
+     * @return the hashed password
+     */
+    public byte[] getHashedPassword()
+    {
+        return hashedPassword;
+    }
+
+
+    /**
+     * Gets the hashed password as hex string.
+     * 
+     * @return the hashed password as hex string
+     */
+    public String getHashedPasswordAsHexString()
+    {
+        return LdifUtils.hexEncode( hashedPassword );
+    }
+
+
+    /**
+     * Gets the salt.
+     * 
+     * @return the salt
+     */
+    public byte[] getSalt()
+    {
+        return salt;
+    }
+
+
+    /**
+     * Gets the salt as hex string.
+     * 
+     * @return the salt as hex string
+     */
+    public String getSaltAsHexString()
+    {
+        return LdifUtils.hexEncode( salt );
+    }
+
+
+    /**
+     * Gets the 
+     * 
+     * @return the byte[]
+     */
+    public byte[] toBytes()
+    {
+        return LdifUtils.utf8encode( toString() );
+    }
+
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+
+        if ( HASH_METHOD_UNSUPPORTED.equalsIgnoreCase( hashMethod ) )
+        {
+            sb.append( trash );
+        }
+        else if ( HASH_METHOD_CRYPT.equalsIgnoreCase( hashMethod ) )
+        {
+            sb.append( '{' ).append( hashMethod ).append( '}' );
+            sb.append( LdifUtils.utf8decode( salt ) );
+            sb.append( LdifUtils.utf8decode( hashedPassword ) );
+        }
+        else if ( hashMethod != null )
+        {
+            sb.append( '{' ).append( hashMethod ).append( '}' );
+            if ( salt != null )
+            {
+                byte[] hashedPasswordWithSaltBytes = new byte[hashedPassword.length + salt.length];
+                merge( hashedPasswordWithSaltBytes, hashedPassword, salt );
+                sb.append( LdifUtils.base64encode( hashedPasswordWithSaltBytes ) );
+            }
+            else
+            {
+                sb.append( LdifUtils.base64encode( hashedPassword ) );
+            }
+        }
+        else
+        {
+            sb.append( LdifUtils.utf8decode( hashedPassword ) );
+        }
+
+        return sb.toString();
+    }
+
+
+    private static void split( byte[] all, byte[] left, byte[] right )
+    {
+        System.arraycopy( all, 0, left, 0, left.length );
+        System.arraycopy( all, left.length, right, 0, right.length );
+    }
+
+
+    private static void merge( byte[] all, byte[] left, byte[] right )
+    {
+        System.arraycopy( left, 0, all, 0, left.length );
+        System.arraycopy( right, 0, all, left.length, right.length );
+    }
+
+
+    private static boolean equals( byte[] data1, byte[] data2 )
+    {
+        if ( data1 == data2 )
+        {
+            return true;
+        }
+        if ( data1 == null || data2 == null )
+        {
+            return false;
+        }
+        if ( data1.length != data2.length )
+        {
+            return false;
+        }
+        for ( int i = 0; i < data1.length; i++ )
+        {
+            if ( data1[i] != data2[i] )
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    private static byte[] digest( String hashMethod, String password, byte[] salt )
+    {
+
+        byte[] passwordBytes = LdifUtils.utf8encode( password );
+        MessageDigest digest;
+        try
+        {
+            digest = MessageDigest.getInstance( hashMethod );
+        }
+        catch ( NoSuchAlgorithmException e1 )
+        {
+            return null;
+        }
+
+        if ( salt != null )
+        {
+            digest.update( passwordBytes );
+            digest.update( salt );
+            byte[] hashedPasswordBytes = digest.digest();
+            return hashedPasswordBytes;
+        }
+        else
+        {
+            byte[] hashedPasswordBytes = digest.digest( passwordBytes );
+            return hashedPasswordBytes;
+        }
+    }
+
+
+    private static byte[] crypt( String password, byte[] salt )
+    {
+        String saltWithCrypted = UnixCrypt.crypt( password, LdifUtils.utf8decode( salt ) );
+        String crypted = saltWithCrypted.substring( 2 );
+        return LdifUtils.utf8encode( crypted );
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/Password.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDN.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDN.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDN.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDN.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,406 @@
+/*
+ *  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.core.model;
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+
+
+/**
+ * A RDN represents a LDAP relative distinguished name.
+ *
+ * @deprecated This class will be removed in the next version. The DN/RDN/RDNPart 
+ * classes are replaced with the shared-ldap LdapDN/Rdn/ATAV. This class just 
+ * remains to provide backward compatibility of the old browserconnections.xml
+ * file that stores searches and bookmarks.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class RDN implements Serializable
+{
+
+    /** The generated serialVersionUID. */
+    private static final long serialVersionUID = -4165959915339033047L;
+
+    /** The attribute type-value pairs */
+    private RDNPart[] parts;
+
+
+    /**
+     * Creates an empty RDN.
+     *
+     */
+    public RDN()
+    {
+        this.parts = new RDNPart[0];
+    }
+
+
+    /**
+     * Creates a new instance of RDN. The given string is parsed.
+     *
+     * @param rdn the rdn
+     * @throws NameException if parsing fails.
+     */
+    public RDN( String rdn ) throws NameException
+    {
+        if ( rdn == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_rdn );
+        }
+
+        // this.parseMultiRdn(rdn.trim());
+        this.parseMultiRdn( rdn );
+    }
+
+
+    /**
+     * Creates a clone of the given RDN.
+     *
+     * @param rdn the RDN
+     */
+    public RDN( RDN rdn )
+    {
+        if ( rdn == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_rdn );
+        }
+
+        this.parts = new RDNPart[rdn.getParts().length];
+        for ( int i = 0; i < this.parts.length; i++ )
+        {
+            this.parts[i] = new RDNPart( rdn.getParts()[i] );
+        }
+    }
+
+
+    /**
+     * Create a single-valued RDN with the given type and value.
+     * 
+     * @param type the attribute type
+     * @param value the value
+     * @param isValueEncoded true if the value is already encoded according RFC4514, Section 2.4
+     * @throws NameException if the type or value are invalid
+     */
+    public RDN( String type, String value, boolean isValueEncoded ) throws NameException
+    {
+        if ( type == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_attribute );
+        }
+        if ( value == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_value );
+        }
+
+        this.parts = new RDNPart[1];
+        this.parts[0] = new RDNPart( type, value, isValueEncoded );
+    }
+
+
+    /**
+     * Creates a multi-values RDN with the given types and values.
+     *
+     * @param types the attribute types
+     * @param values the attribute values
+     * @param areValuesEncoded true if the values is already encoded according RFC4514, Section 2.4
+     * @throws NameException if the types or values are invalid
+     */
+    public RDN( String[] types, String[] values, boolean areValuesEncoded ) throws NameException
+    {
+
+        if ( types == null || types.length < 1 )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_attribute );
+        }
+        if ( values == null || values.length < 1 )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_value );
+        }
+        if ( types.length != values.length )
+        {
+            throw new IllegalArgumentException( "Size of types and values is not equal" ); //$NON-NLS-1$
+        }
+
+        this.parts = new RDNPart[types.length];
+        for ( int i = 0; i < this.parts.length; i++ )
+        {
+            this.parts[i] = new RDNPart( types[i], values[i], areValuesEncoded );
+        }
+    }
+
+
+    /**
+     * Checks if the RDN is multi-valued.
+     * 
+     * @return true, if the RDN is multi-valued
+     */
+    public boolean isMultivalued()
+    {
+        return this.parts.length > 1;
+    }
+
+
+    /**
+     * Gets the first attribute type.
+     * 
+     * @return the first attribute type
+     */
+    public String getType()
+    {
+        return this.parts.length > 0 ? this.parts[0].getType() : ""; //$NON-NLS-1$
+    }
+
+
+    /**
+     * Gets the first attribute value.
+     * 
+     * @return the first attribute value
+     */
+    public String getValue()
+    {
+        return this.parts.length > 0 ? this.parts[0].getValue() : ""; //$NON-NLS-1$
+    }
+
+
+    /**
+     * Gets the parts.
+     * 
+     * @return the parts
+     */
+    public RDNPart[] getParts()
+    {
+        return this.parts;
+    }
+
+
+    /**
+     * Sets the parts.
+     * 
+     * @param parts the parts
+     */
+    public void setParts( RDNPart[] parts )
+    {
+        this.parts = parts;
+    }
+
+
+    /**
+     * Gets the attribute types.
+     * 
+     * @return the attribute types
+     */
+    public String[] getTypes()
+    {
+        if ( !isMultivalued() )
+        {
+            return new String[]
+                { getType() };
+        }
+        else
+        {
+            Set<String> typeSet = new LinkedHashSet<String>();
+            for ( int i = 0; i < this.parts.length; i++ )
+            {
+                RDNPart entry = this.parts[i];
+                typeSet.add( entry.getType() );
+            }
+            return typeSet.toArray( new String[typeSet.size()] );
+        }
+    }
+
+
+    /**
+     * Gets the values.
+     * 
+     * @return the values
+     */
+    public String[] getValues()
+    {
+        if ( !isMultivalued() )
+        {
+            return new String[]
+                { getValue() };
+        }
+        else
+        {
+            Set<String> valueSet = new LinkedHashSet<String>();
+            for ( int i = 0; i < this.parts.length; i++ )
+            {
+                RDNPart entry = this.parts[i];
+                valueSet.add( entry.getValue() );
+            }
+            return valueSet.toArray( new String[valueSet.size()] );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return this.toString().hashCode();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals( Object o )
+    {
+        if ( o instanceof RDN )
+        {
+            return this.toString().equals( ( ( RDN ) o ).toString() );
+        }
+        return false;
+    }
+
+
+    /**
+     * Returns the string representation of this RDN, 
+     * for example &lt;type&gt;=&lt;value&gt;
+     * 
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+
+        if ( isMultivalued() )
+        {
+            for ( int i = 0; i < this.parts.length; i++ )
+            {
+                RDNPart part = this.parts[i];
+                sb.append( part.toString() );
+
+                if ( i + 1 < this.parts.length )
+                {
+                    sb.append( "+" ); //$NON-NLS-1$
+                }
+            }
+        }
+        else if ( this.parts.length > 0 )
+        {
+            RDNPart part = this.parts[0];
+            sb.append( part.toString() );
+        }
+
+        return sb.toString();
+    }
+
+
+    /**
+     * Returns the string representation of this RDN, but 
+     * lowercased and with the numerid OIDs instead of the types.
+     *
+     * @param schema the schema
+     * @return the lowercased and OID-fizied string representation of this RDN
+     */
+    public String toOidString( Schema schema )
+    {
+        StringBuffer sb = new StringBuffer();
+
+        if ( isMultivalued() )
+        {
+            for ( int i = 0; i < this.parts.length; i++ )
+            {
+                RDNPart part = this.parts[i];
+                sb.append( part.toOidString( schema ) );
+
+                if ( i + 1 < this.parts.length )
+                {
+                    sb.append( "+" ); //$NON-NLS-1$
+                }
+            }
+        }
+        else if ( this.parts.length > 0 )
+        {
+            RDNPart part = this.parts[0];
+            sb.append( part.toOidString( schema ) );
+        }
+
+        return sb.toString();
+    }
+
+
+    /**
+     * Parses the RDN.
+     *
+     * @param multirdn the rdn
+     * @throws NameException if parsing fails
+     */
+    private void parseMultiRdn( String multirdn ) throws NameException
+    {
+        List<RDNPart> partList = new ArrayList<RDNPart>( 1 );
+
+        boolean backslash = false;
+        int start = 0;
+        for ( int i = 0; i < multirdn.length(); i++ )
+        {
+            if ( multirdn.charAt( i ) == '\\' && !backslash )
+            {
+                backslash = true;
+            }
+            else
+            {
+                String rdn = null;
+                if ( multirdn.charAt( i ) == '+' && !backslash )
+                {
+                    rdn = multirdn.substring( start, i );
+                }
+                else if ( i == multirdn.length() - 1 )
+                {
+                    rdn = multirdn.substring( start );
+                }
+                if ( rdn != null )
+                {
+                    int index = rdn.indexOf( '=' );
+                    if ( index < 1 )
+                    {
+                        throw new NameException( BrowserCoreMessages.model__invalid_rdn );
+                    }
+                    String type = rdn.substring( 0, index );
+                    String value = rdn.substring( index + 1, rdn.length() );
+                    partList.add( new RDNPart( type, value, true ) );
+                    start = i + 1;
+                }
+                backslash = false;
+            }
+        }
+
+        if ( partList.isEmpty() )
+        {
+
+        }
+
+        this.parts = partList.toArray( new RDNPart[partList.size()] );
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDN.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDNPart.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDNPart.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDNPart.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDNPart.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,276 @@
+/*
+ *  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.core.model;
+
+
+import java.io.Serializable;
+
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+
+
+/**
+ * A RDNPart represents a attribute type-value-pair, used in RDN. 
+ * 
+ * @deprecated This class will be removed in the next version. The DN/RDN/RDNPart 
+ * classes are replaced with the shared-ldap LdapDN/Rdn/ATAV. This class just 
+ * remains to provide backward compatibility of the old browserconnections.xml
+ * file that stores searches and bookmarks.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class RDNPart implements Serializable
+{
+    /** The generated serialVersionUID */
+    private static final long serialVersionUID = 3250931604639940667L;
+
+    /** The attribute type */
+    private String type;
+
+    /** The value */
+    private String value;
+
+
+    /**
+     * Creates a new instance of RDNPart with an empty type an value 
+     *
+     */
+    public RDNPart()
+    {
+        this.type = ""; //$NON-NLS-1$
+        this.value = ""; //$NON-NLS-1$
+    }
+
+
+    /**
+     * Creates a new instance of RDNPart with the given type and value.
+     *
+     * @param type the attribute type
+     * @param value the value
+     * @param isValueEncoded true if the value is already encoded according RFC4514, Section 2.4
+     * @throws NameException if the type or value are invalid
+     */
+    public RDNPart( String type, String value, boolean isValueEncoded ) throws NameException
+    {
+        if ( type == null || !type.matches( "([A-Za-z][A-Za-z0-9-]*)|([0-9]+(\\.[0-9]+)+)" ) ) { //$NON-NLS-1$
+            throw new NameException( BrowserCoreMessages.model__empty_attribute );
+        }
+        if ( value == null || value.length() < 1 )
+        {
+            throw new NameException( BrowserCoreMessages.model__empty_value );
+        }
+        // this.type = type.trim();
+        // this.value = value.trim();
+        this.setType( type );
+        if ( isValueEncoded )
+        {
+            this.setValue( value );
+        }
+        else
+        {
+            this.setUnencodedValue( value );
+        }
+    }
+
+
+    /**
+     * Creates a clone of the given RDNPart.
+     *
+     * @param rdnPart the RDNPart.
+     */
+    public RDNPart( RDNPart rdnPart )
+    {
+        this.type = rdnPart.type;
+        this.value = rdnPart.value;
+    }
+
+
+    /**
+     * Gets the type.
+     * 
+     * @return the type
+     */
+    public String getType()
+    {
+        return type;
+    }
+
+
+    /**
+     * Sets the type.
+     * 
+     * @param type the type
+     */
+    public void setType( String type )
+    {
+        this.type = type;
+    }
+
+
+    /**
+     * Gets the unencoded value. All escaped characters are unescaped
+     * before returning the vaue.
+     *
+     * @return the unencoded value.
+     */
+    public String getUnencodedValue()
+    {
+        StringBuffer unencodedValue = new StringBuffer( this.value );
+
+        for ( int i = 0; i < unencodedValue.length(); i++ )
+        {
+            if ( unencodedValue.charAt( i ) == '\\' )
+            {
+                if ( i == 0 && unencodedValue.length() > i + 1 && unencodedValue.charAt( i + 1 ) == ' ' )
+                {
+                    unencodedValue.deleteCharAt( i );
+                }
+                else if ( i == unencodedValue.length() - 2 && unencodedValue.length() > i + 1
+                    && unencodedValue.charAt( i + 1 ) == ' ' )
+                {
+                    unencodedValue.deleteCharAt( i );
+                }
+                else if ( i == 0 && unencodedValue.length() > i + 1 && unencodedValue.charAt( i + 1 ) == '#' )
+                {
+                    unencodedValue.deleteCharAt( i );
+                }
+                else if ( unencodedValue.length() > i + 1
+                    && ( unencodedValue.charAt( i + 1 ) == '+' || unencodedValue.charAt( i + 1 ) == ','
+                        || unencodedValue.charAt( i + 1 ) == ';' || unencodedValue.charAt( i + 1 ) == '<'
+                        || unencodedValue.charAt( i + 1 ) == '>' || unencodedValue.charAt( i + 1 ) == '"' || unencodedValue
+                        .charAt( i + 1 ) == '\\' ) )
+                {
+                    unencodedValue.deleteCharAt( i );
+                }
+            }
+        }
+
+        return unencodedValue.toString();
+    }
+
+
+    /**
+     * Sets the unencoded value. The unencoded value will be encoded 
+     * according RFC4514, Section 2.4.
+     * 
+     * @param unencodedValue the unencoded value
+     */
+    public void setUnencodedValue( String unencodedValue )
+    {
+        unencodedValue = unencodedValue.replaceAll( "\\\\", "\\\\\\\\" ); //$NON-NLS-1$ //$NON-NLS-2$
+        unencodedValue = unencodedValue.replaceAll( "\\+", "\\\\+" ); //$NON-NLS-1$ //$NON-NLS-2$
+        unencodedValue = unencodedValue.replaceAll( ",", "\\\\," ); //$NON-NLS-1$ //$NON-NLS-2$
+        unencodedValue = unencodedValue.replaceAll( "\"", "\\\\\"" ); //$NON-NLS-1$ //$NON-NLS-2$
+        unencodedValue = unencodedValue.replaceAll( "<", "\\\\<" ); //$NON-NLS-1$ //$NON-NLS-2$
+        unencodedValue = unencodedValue.replaceAll( ">", "\\\\>" ); //$NON-NLS-1$ //$NON-NLS-2$
+        unencodedValue = unencodedValue.replaceAll( ";", "\\\\;" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+        if ( unencodedValue.startsWith( " " ) ) //$NON-NLS-1$
+        {
+            unencodedValue = "\\" + unencodedValue; //$NON-NLS-1$
+        }
+        else if ( unencodedValue.startsWith( "#" ) ) //$NON-NLS-1$
+        {
+            unencodedValue = "\\" + unencodedValue; //$NON-NLS-1$
+        }
+
+        if ( unencodedValue.endsWith( " " ) ) //$NON-NLS-1$
+        {
+            unencodedValue = unencodedValue.substring( 0, unencodedValue.length() - 1 ) + "\\ "; //$NON-NLS-1$
+        }
+
+        this.value = unencodedValue;
+    }
+
+
+    /**
+     * Gets the value. Note that the value is encoded
+     * according RFC 4514, Section 2.4.
+     * 
+     * @return the value
+     */
+    public String getValue()
+    {
+        return value;
+    }
+
+
+    /**
+     * Sets the value. Note that the value must be encoded
+     * according RFC 4514, Section 2.4.
+     * 
+     * @param value the value
+     */
+    public void setValue( String value )
+    {
+        this.value = value;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return this.toString().hashCode();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals( Object o )
+    {
+        if ( o instanceof RDNPart )
+        {
+            return this.toString().equals( ( ( RDNPart ) o ).toString() );
+        }
+        return false;
+    }
+
+
+    /**
+     * Returns the string representation of this RDNPart, namely
+     * &lt;type&gt;=&lt;value&gt;
+     * 
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return getType() + "=" + getValue(); //$NON-NLS-1$
+    }
+
+
+    /**
+     * Returns the string representation of this RDNPart, but 
+     * lowercased and with the numerid OID instead of the type.
+     *
+     * @param schema the schema
+     * @return the lowercased and OID-fizied string representation of this RDNPart
+     */
+    public String toOidString( Schema schema )
+    {
+        String oid = schema != null ? schema.getAttributeTypeDescription( getType() ).getNumericOID() : getType();
+        return oid.toLowerCase() + "=" + getValue().toLowerCase(); //$NON-NLS-1$
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/RDNPart.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/ReferralException.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/ReferralException.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/ReferralException.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/ReferralException.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,110 @@
+/*
+ *  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.core.model;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Search;
+
+
+public class ReferralException extends ConnectionException
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private SearchParameter originalSearchParameter;
+
+    private String[] referrals;
+
+
+    public ReferralException( SearchParameter originalSearchParameter, String[] referrals, int ldapStatusCode,
+        String message, Throwable originalThrowable )
+    {
+        super( ldapStatusCode, message, originalThrowable );
+        this.originalSearchParameter = originalSearchParameter;
+        this.referrals = referrals;
+    }
+
+
+    public String[] getReferrals()
+    {
+        return referrals;
+    }
+
+
+    public ISearch[] getReferralSearches() throws ConnectionException
+    {
+
+        // get referral handler
+        IReferralHandler referralHandler = BrowserCorePlugin.getDefault().getReferralHandler();
+        if ( referralHandler == null )
+        {
+            throw new ConnectionException( BrowserCoreMessages.model__no_referral_handler );
+        }
+
+        List referralSearchList = new ArrayList( getReferrals().length );
+
+        for ( int i = 0; i < getReferrals().length; i++ )
+        {
+
+            // parse referral URL
+            String referral = getReferrals()[i];
+            URL referralUrl = new URL( referral );
+
+            // get referral connection
+            IBrowserConnection referralConnection = referralHandler.getReferralConnection( referralUrl );
+            if ( referralConnection == null )
+            {
+                // throw new
+                // ConnectionException(BrowserCoreMessages.model__no_referral_connection);
+                continue;
+            }
+
+            // create search
+            try
+            {
+                ISearch referralSearch = new Search(
+                    null, //
+                    referralConnection, //
+                    referralUrl.hasDn() ? referralUrl.getDn() : originalSearchParameter.getSearchBase(), referralUrl
+                        .hasFilter() ? referralUrl.getFilter() : originalSearchParameter.getFilter(),
+                    originalSearchParameter.getReturningAttributes(), referralUrl.hasScope() ? referralUrl.getScope()
+                        : originalSearchParameter.getScope(), originalSearchParameter.getCountLimit(),
+                    originalSearchParameter.getTimeLimit(), originalSearchParameter.getAliasesDereferencingMethod(),
+                    originalSearchParameter.getReferralsHandlingMethod(), originalSearchParameter.isInitHasChildrenFlag(),
+                    originalSearchParameter.isInitAliasAndReferralFlag(), originalSearchParameter.getControls() );
+                referralSearchList.add( referralSearch );
+            }
+            catch ( NoSuchFieldException nsfe )
+            {
+            }
+
+        }
+
+        ISearch[] referralSearches = ( ISearch[] ) referralSearchList.toArray( new ISearch[referralSearchList.size()] );
+        return referralSearches;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/ReferralException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/SearchParameter.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/SearchParameter.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/SearchParameter.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/SearchParameter.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,438 @@
+/*
+ *  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.core.model;
+
+
+import java.io.Serializable;
+
+import javax.naming.InvalidNameException;
+
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.AliasDereferencingMethod;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.ReferralHandlingMethod;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch.SearchScope;
+
+
+/**
+ * A Bean class to hold the search parameters.
+ * It is used to make searches persistent.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class SearchParameter implements Serializable
+{
+
+    /** The serialVersionUID. */
+    private static final long serialVersionUID = 2447490121520960805L;
+
+    /** The symbolic name. */
+    private String name;
+
+    /** The search base. */
+    private LdapDN searchBase;
+
+    /** The filter. */
+    private String filter;
+
+    /** The returning attributes. */
+    private String[] returningAttributes;
+
+    /** The search scope. */
+    private SearchScope scope;
+
+    /** The time limit in milliseconds, 0 means no limit. */
+    private int timeLimit;
+
+    /** The count limit, 0 means no limit. */
+    private int countLimit;
+
+    /** The alias dereferencing method. */
+    private AliasDereferencingMethod aliasesDereferencingMethod;
+
+    /** The referrals handling method. */
+    private ReferralHandlingMethod referralsHandlingMethod;
+
+    /** The controls */
+    private Control[] controls;
+
+    /** Flag indicating weather the hasChildren flag of IEntry should be initialized */
+    private boolean initHasChildrenFlag;
+
+    /** Flag indicating weather the isAlias and isReferral flag of IEntry should be initialized */
+    private boolean initAliasAndReferralFlag;
+
+
+    /**
+     * Creates a new instance of SearchParameter with default search parameters:
+     * <ul>
+     * <li>null search name
+     * <li>null search base
+     * <li>default filter (objectClass=*)
+     * <li>no returning attributes
+     * <li>search scope one level
+     * <li>no count limit
+     * <li>no time limit
+     * <li>never dereference aliases
+     * <li>ignore referrals
+     * <li>no initialization of hasChildren flag
+     * <li>no initialization of isAlias and isReferral flag
+     * <li>no controls 
+     * </ul>
+     */
+    public SearchParameter()
+    {
+        name = null;
+        searchBase = null;
+        filter = ISearch.FILTER_TRUE;
+        returningAttributes = ISearch.NO_ATTRIBUTES;
+        scope = SearchScope.ONELEVEL;
+        timeLimit = 0;
+        countLimit = 0;
+        aliasesDereferencingMethod = AliasDereferencingMethod.NEVER;
+        referralsHandlingMethod = ReferralHandlingMethod.IGNORE;
+        controls = null;
+        initHasChildrenFlag = false;
+        initAliasAndReferralFlag = false;
+    }
+
+
+    /**
+     * Gets the count limit, 0 means no limit.
+     * 
+     * @return the count limit
+     */
+    public int getCountLimit()
+    {
+        return countLimit;
+    }
+
+
+    /**
+     * Sets the count limit, 0 means no limit.
+     * 
+     * @param countLimit the count limit
+     */
+    public void setCountLimit( int countLimit )
+    {
+        this.countLimit = countLimit;
+    }
+
+
+    /**
+     * Gets the filter.
+     * 
+     * @return the filter
+     */
+    public String getFilter()
+    {
+        return filter;
+    }
+
+
+    /**
+     * Sets the filter, a null or empty filter will be
+     * transformed to (objectClass=*).
+     * 
+     * @param filter the filter
+     */
+    public void setFilter( String filter )
+    {
+        if ( filter == null || "".equals( filter ) ) //$NON-NLS-1$
+        {
+            filter = ISearch.FILTER_TRUE;
+        }
+        this.filter = filter;
+    }
+
+
+    /**
+     * Gets the symbolic name.
+     * 
+     * @return the name
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Sets the symbolic name.
+     * 
+     * @param name the name
+     */
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Gets the returning attributes.
+     * 
+     * @return the returning attributes
+     */
+    public String[] getReturningAttributes()
+    {
+        return returningAttributes;
+    }
+
+
+    /**
+     * Sets the returning attributes, an empty array indicates none,
+     * null will be transformed to '*' (all user attributes).
+     * 
+     * @param returningAttributes the returning attributes
+     */
+    public void setReturningAttributes( String[] returningAttributes )
+    {
+        if ( returningAttributes == null )
+        {
+            returningAttributes = new String[]
+                { ISearch.ALL_USER_ATTRIBUTES };
+        }
+        this.returningAttributes = returningAttributes;
+    }
+
+
+    /**
+     * Gets the scope.
+     * 
+     * @return the scope
+     */
+    public SearchScope getScope()
+    {
+        return scope;
+    }
+
+
+    /**
+     * Sets the scope.
+     * 
+     * @param scope the scope
+     */
+    public void setScope( SearchScope scope )
+    {
+        this.scope = scope;
+    }
+
+
+    /**
+     * Gets the aliases dereferencing method.
+     * 
+     * @return the aliases dereferencing method
+     */
+    public AliasDereferencingMethod getAliasesDereferencingMethod()
+    {
+        return aliasesDereferencingMethod;
+    }
+
+
+    /**
+     * Sets the aliases dereferencing method.
+     * 
+     * @param aliasesDereferencingMethod the aliases dereferencing method
+     */
+    public void setAliasesDereferencingMethod( AliasDereferencingMethod aliasesDereferencingMethod )
+    {
+        this.aliasesDereferencingMethod = aliasesDereferencingMethod;
+    }
+
+
+    /**
+     * Gets the referrals handling method.
+     * 
+     * @return the referrals handling method
+     */
+    public ReferralHandlingMethod getReferralsHandlingMethod()
+    {
+        return referralsHandlingMethod;
+    }
+
+
+    /**
+     * Sets the referrals handling method.
+     * 
+     * @param referralsHandlingMethod the referrals handling method
+     */
+    public void setReferralsHandlingMethod( ReferralHandlingMethod referralsHandlingMethod )
+    {
+        this.referralsHandlingMethod = referralsHandlingMethod;
+    }
+
+
+    /**
+     * Gets the search base.
+     * 
+     * @return the search base
+     */
+    public LdapDN getSearchBase()
+    {
+        return searchBase;
+    }
+
+
+    /**
+     * Sets the search base, a null search base is not allowed.
+     * 
+     * @param searchBase the search base
+     */
+    public void setSearchBase( LdapDN searchBase )
+    {
+        assert searchBase != null;
+        this.searchBase = searchBase;
+    }
+
+
+    /**
+     * Sets the search base, a null search base is not allowed.
+     * 
+     * @deprecated This method will be removed in the next version. The DN/RDN/RDNPart 
+     * classes are replaced with the shared-ldap LdapDN/Rdn/ATAV. This method just 
+     * remains to provide backward compatibility of the old browserconnections.xml
+     * file that stores searches and bookmarks.
+     * 
+     * @param searchBase the search base
+     */
+    public void setSearchBase( DN searchBase )
+    {
+        assert searchBase != null;
+        try
+        {
+            setSearchBase( new LdapDN( searchBase.toString() ) );
+        }
+        catch ( InvalidNameException e )
+        {
+        }
+    }
+    
+    
+    /**
+     * Gets the time limit in milliseconds, 0 means no limit.
+     * 
+     * @return the time limit
+     */
+    public int getTimeLimit()
+    {
+        return timeLimit;
+    }
+
+
+    /**
+     * Sets the time limit in milliseconds, 0 means no limit.
+     * 
+     * @param timeLimit the time limit
+     */
+    public void setTimeLimit( int timeLimit )
+    {
+        this.timeLimit = timeLimit;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object clone()
+    {
+        SearchParameter clone = new SearchParameter();
+        clone.setName( getName() );
+        clone.setSearchBase( getSearchBase() );
+        clone.setFilter( getFilter() );
+        clone.setReturningAttributes( getReturningAttributes() );
+        clone.setScope( getScope() );
+        clone.setTimeLimit( getTimeLimit() );
+        clone.setCountLimit( getCountLimit() );
+        clone.setAliasesDereferencingMethod( getAliasesDereferencingMethod() );
+        clone.setReferralsHandlingMethod( getReferralsHandlingMethod() );
+        clone.setInitHasChildrenFlag( isInitHasChildrenFlag() );
+        clone.setInitAliasAndReferralFlag( isInitAliasAndReferralFlag() );
+        clone.setControls( getControls() );
+        return clone;
+    }
+
+
+    /**
+     * Checks if the isAlias and isReferral flags of IEntry should be initialized.
+     * 
+     * @return true, if the isAlias and isReferral flags of IEntry should be initialized
+     */
+    public boolean isInitAliasAndReferralFlag()
+    {
+        return initAliasAndReferralFlag;
+    }
+
+
+    /**
+     * Sets if the hasChildren flag of IEntry should be initialized.
+     * 
+     * @param initAliasAndReferralFlag the init isAlias and isReferral flag
+     */
+    public void setInitAliasAndReferralFlag( boolean initAliasAndReferralFlag )
+    {
+        this.initAliasAndReferralFlag = initAliasAndReferralFlag;
+    }
+
+
+    /**
+     * Checks if the hasChildren flag of IEntry should be initialized.
+     * 
+     * @return true, if the hasChildren flag of IEntry should be initialized
+     */
+    public boolean isInitHasChildrenFlag()
+    {
+        return initHasChildrenFlag;
+    }
+
+
+    /**
+     * Sets if the hasChildren flag of IEntry should be initialized.
+     * 
+     * @param initHasChildrenFlag the init hasChildren flag
+     */
+    public void setInitHasChildrenFlag( boolean initHasChildrenFlag )
+    {
+        this.initHasChildrenFlag = initHasChildrenFlag;
+    }
+
+
+    /**
+     * Gets the controls.
+     * 
+     * @return the controls
+     */
+    public Control[] getControls()
+    {
+        return controls;
+    }
+
+
+    /**
+     * Sets the controls.
+     * 
+     * @param controls the controls
+     */
+    public void setControls( Control[] controls )
+    {
+        this.controls = controls;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/SearchParameter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/URL.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/URL.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/URL.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/URL.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,665 @@
+/*
+ *  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.core.model;
+
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import javax.naming.InvalidNameException;
+
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.studio.connection.core.ConnectionParameter.EncryptionMethod;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch.SearchScope;
+import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
+
+
+/**
+ * An URL represents a LDAP URL.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class URL
+{
+
+    // ldap://host:port/dn?attributes?scope?filter?extensions
+    // ldap://localhost:389/ou=Testdata100,dc=seelmann,dc=muc
+
+    // ldapurl = scheme "://" [hostport] ["/" [dn ["?" [attributes] ["?"
+    // [scope] ["?" [filter] ["?" extensions]]]]]]
+    // scheme = "ldap"
+    // attributes = attrdesc *("," attrdesc)
+    // scope = "base" / "one" / "sub"
+    // dn = distinguishedName from Section 3 of [1]
+    // hostport = hostport from Section 5 of RFC 1738 [5]
+    // attrdesc = AttributeDescription from Section 4.1.5 of [2]
+    // filter = filter from Section 4 of [4]
+    // extensions = extension *("," extension)
+    // extension = ["!"] extype ["=" exvalue]
+    // extype = token / xtoken
+    // exvalue = LDAPString from section 4.1.2 of [2]
+    // token = oid from section 4.1 of [3]
+    // xtoken = ("X-" / "x-") token
+
+    /** The protocoll, ldap or ldaps */
+    private String protocol = null;
+
+    /** The host */
+    private String host = null;
+
+    /** The port */
+    private String port = null;
+
+    /** The dn */
+    private String dn = null;
+
+    /** The attributes */
+    private String attributes = null;
+
+    /** The scope */
+    private String scope = null;
+
+    /** The filter */
+    private String filter = null;
+
+    /** The extensions */
+    private String extensions = null;
+
+
+    /**
+     * Creates a new instance of URL. The given string is 
+     * parsed to an URL.
+     *
+     * @param url the URL
+     */
+    public URL( String url )
+    {
+        if ( url == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_url );
+        }
+
+        this.parseUrl( url );
+    }
+
+
+    /**
+     * Creates a new instance of URL, based on the given connection and DN. 
+     * Only the fields protocol, host, port and dn exists when using this constructor.
+     *
+     * @param connection the connection
+     * @param dn the DN
+     */
+    public URL( IBrowserConnection connection, LdapDN dn )
+    {
+        this( connection );
+
+        if ( dn == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_url );
+        }
+
+        this.dn = dn.getUpName();
+    }
+
+
+    /**
+     * Creates a new instance of URL, based on the given connection. Only
+     * the fields protocol, host and port exists when using this constructor.
+     *
+     * @param browserConnection the browser connection
+     */
+    public URL( IBrowserConnection browserConnection )
+    {
+        if ( browserConnection == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_url );
+        }
+
+        if ( browserConnection.getConnection().getEncryptionMethod() == EncryptionMethod.LDAPS )
+        {
+            this.protocol = "ldaps";; //$NON-NLS-1$
+        }
+        else
+        {
+            this.protocol = "ldap"; //$NON-NLS-1$
+        }
+        this.host = browserConnection.getConnection().getHost();
+        this.port = Integer.toString( browserConnection.getConnection().getPort() );
+    }
+
+
+    /**
+     * Creates a new instance of URL, based on the given search. Initializes
+     * the fields protocol, host, port, dn, attributes, scope and filter.
+     *
+     * @param search the search
+     */
+    public URL( ISearch search )
+    {
+        this( search.getBrowserConnection(), search.getSearchBase() );
+
+        if ( search == null )
+        {
+            throw new IllegalArgumentException( BrowserCoreMessages.model__empty_url );
+        }
+
+        this.attributes = Utils.arrayToString( search.getReturningAttributes() );
+        this.scope = search.getScope() == SearchScope.SUBTREE ? "sub" : //$NON-NLS-1$
+            search.getScope() == SearchScope.ONELEVEL ? "one" : //$NON-NLS-1$
+                "base"; //$NON-NLS-1$
+        this.filter = search.getFilter();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals( Object o ) throws ClassCastException
+    {
+        if ( o instanceof URL )
+        {
+            return this.toString().equals( ( ( URL ) o ).toString() );
+        }
+        return false;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return this.toString().hashCode();
+    }
+
+
+    /**
+     * Returns the string representation of this LDAP URL.
+     * 
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+
+        if ( hasProtocol() )
+            sb.append( protocol );
+
+        sb.append( "://" ); //$NON-NLS-1$
+
+        if ( hasHost() )
+            sb.append( host );
+        if ( hasPort() )
+            sb.append( ":" ).append( port ); //$NON-NLS-1$
+
+        if ( hasDn() || hasAttributes() || hasScope() || hasFilter() || hasExtensions() )
+            sb.append( "/" ); //$NON-NLS-1$
+        if ( hasDn() )
+            sb.append( dn );
+
+        if ( hasAttributes() || hasScope() || hasFilter() || hasExtensions() )
+            sb.append( "?" ); //$NON-NLS-1$
+        if ( hasAttributes() )
+            sb.append( attributes );
+
+        if ( hasScope() || hasFilter() || hasExtensions() )
+            sb.append( "?" ); //$NON-NLS-1$
+        if ( hasScope() )
+            sb.append( scope );
+
+        if ( hasFilter() || hasExtensions() )
+            sb.append( "?" ); //$NON-NLS-1$
+        if ( hasFilter() )
+            sb.append( filter );
+
+        if ( hasExtensions() )
+            sb.append( "?" ); //$NON-NLS-1$
+        if ( hasExtensions() )
+            sb.append( extensions );
+
+        return sb.toString();
+    }
+
+
+    /**
+     * Parses the given string represntation of the URL.
+     *
+     * @param url the URL
+     */
+    private void parseUrl( String url )
+    {
+
+        try
+        {
+            url = URLDecoder.decode( url, "UTF-8" ); //$NON-NLS-1$
+
+            // protocol
+            String[] protocolAndRest = url.split( "://", 2 ); //$NON-NLS-1$
+            if ( protocolAndRest.length > 0 )
+            {
+                if ( "ldap".equals( protocolAndRest[0] ) || "ldaps".equals( protocolAndRest[0] ) ) { //$NON-NLS-1$ //$NON-NLS-2$
+                    this.protocol = protocolAndRest[0];
+                }
+            }
+            if ( protocolAndRest.length < 2 )
+            {
+                return;
+            }
+
+            // host and port
+            String[] hostportAndRest = protocolAndRest[1].split( "/", 2 ); //$NON-NLS-1$
+            if ( hostportAndRest.length > 0 )
+            {
+                String[] hostAndPort = hostportAndRest[0].split( ":", 2 ); //$NON-NLS-1$
+                if ( hostAndPort.length == 2 )
+                {
+                    this.host = hostAndPort[0];
+                    this.port = hostAndPort[1];
+                }
+                else if ( hostAndPort.length == 1 && hostAndPort[0].length() > 0 )
+                {
+                    this.host = hostAndPort[0];
+                    this.port = "389"; //$NON-NLS-1$
+                }
+            }
+            if ( hostportAndRest.length < 2 )
+            {
+                return;
+            }
+
+            // dn
+            String[] dnAndRest = hostportAndRest[1].split( "\\?", 2 ); //$NON-NLS-1$
+            if ( dnAndRest.length > 0 && dnAndRest[0].length() > 0 )
+            {
+                this.dn = dnAndRest[0];
+            }
+            if ( dnAndRest.length < 2 )
+            {
+                return;
+            }
+
+            // attributes
+            String[] attributesAndRest = dnAndRest[1].split( "\\?", 2 ); //$NON-NLS-1$
+            if ( attributesAndRest.length > 0 && attributesAndRest[0].length() > 0 )
+            {
+                this.attributes = attributesAndRest[0];
+            }
+            if ( attributesAndRest.length < 2 )
+            {
+                return;
+            }
+
+            // scope
+            String[] scopeAndRest = attributesAndRest[1].split( "\\?", 2 ); //$NON-NLS-1$
+            if ( scopeAndRest.length > 0 && scopeAndRest[0].length() > 0 )
+            {
+                this.scope = scopeAndRest[0];
+            }
+            if ( scopeAndRest.length < 2 )
+            {
+                return;
+            }
+
+            // filter
+            String[] filterAndRest = scopeAndRest[1].split( "\\?", 2 ); //$NON-NLS-1$
+            if ( filterAndRest.length > 0 && filterAndRest[0].length() > 0 )
+            {
+                this.filter = filterAndRest[0];
+            }
+            if ( filterAndRest.length < 2 )
+            {
+                return;
+            }
+
+            if ( filterAndRest[1].length() > 0 )
+            {
+                this.extensions = filterAndRest[0];
+            }
+
+        }
+        catch ( UnsupportedEncodingException e1 )
+        {
+        }
+
+    }
+
+
+    /**
+     * Checks for protocol.
+     * 
+     * @return true, if has protocol
+     */
+    public boolean hasProtocol()
+    {
+        try
+        {
+            getProtocol();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the protocol.
+     * 
+     * @return the protocol
+     * @throws NoSuchFieldException if not has protocol
+     */
+    public String getProtocol() throws NoSuchFieldException
+    {
+        if ( protocol == null )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_protocol );
+        }
+
+        return protocol;
+    }
+
+
+    /**
+     * Checks for host.
+     * 
+     * @return true, if has host
+     */
+    public boolean hasHost()
+    {
+        try
+        {
+            getHost();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the host.
+     * 
+     * @return the host
+     * @throws NoSuchFieldException if not has host
+     */
+    public String getHost() throws NoSuchFieldException
+    {
+        if ( host == null )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_host );
+        }
+
+        return host;
+    }
+
+
+    /**
+     * Checks for port.
+     * 
+     * @return true, if has port
+     */
+    public boolean hasPort()
+    {
+        try
+        {
+            getPort();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the port.
+     * 
+     * @return the port
+     * @throws NoSuchFieldException if not has port
+     */
+    public String getPort() throws NoSuchFieldException
+    {
+        try
+        {
+            int p = Integer.parseInt( port );
+            if ( p > 0 && p <= 65536 )
+            {
+                return port;
+            }
+            else
+            {
+                throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_port );
+            }
+        }
+        catch ( NumberFormatException e )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_port );
+        }
+    }
+
+
+    /**
+     * Checks for dn.
+     * 
+     * @return true, if has dn
+     */
+    public boolean hasDn()
+    {
+        try
+        {
+            getDn();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the dn.
+     * 
+     * @return the dn
+     * @throws NoSuchFieldException if not has dn
+     */
+    public LdapDN getDn() throws NoSuchFieldException
+    {
+        if ( dn == null )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_dn );
+        }
+
+        try
+        {
+            return new LdapDN( dn );
+        }
+        catch ( InvalidNameException e )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_dn );
+        }
+    }
+
+
+    /**
+     * Checks for attributes.
+     * 
+     * @return true, if has attributes
+     */
+    public boolean hasAttributes()
+    {
+        try
+        {
+            getAttributes();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the attributes.
+     * 
+     * @return the attributes
+     * @throws NoSuchFieldException if not has attributes
+     */
+    public String[] getAttributes() throws NoSuchFieldException
+    {
+        if ( attributes == null )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_attributes );
+        }
+
+        return Utils.stringToArray( attributes );
+        // return attributes.split(",");
+    }
+
+
+    /**
+     * Checks for scope.
+     * 
+     * @return true, if has scope
+     */
+    public boolean hasScope()
+    {
+        try
+        {
+            getScope();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the scope.
+     * 
+     * @return the scope
+     * @throws NoSuchFieldException if not has scope
+     */
+    public SearchScope getScope() throws NoSuchFieldException
+    {
+        if ( scope == null )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_scope );
+        }
+
+        if ( "base".equals( scope ) ) { //$NON-NLS-1$
+            return SearchScope.OBJECT;
+        }
+        else if ( "one".equals( scope ) ) { //$NON-NLS-1$
+            return SearchScope.ONELEVEL;
+        }
+        else if ( "sub".equals( scope ) ) { //$NON-NLS-1$
+            return SearchScope.SUBTREE;
+        }
+        else
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_scope );
+        }
+    }
+
+
+    /**
+     * Checks for filter.
+     * 
+     * @return true, if has filter
+     */
+    public boolean hasFilter()
+    {
+        try
+        {
+            getFilter();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the filter.
+     * 
+     * @return the filter
+     * @throws NoSuchFieldException if not has filter
+     */
+    public String getFilter() throws NoSuchFieldException
+    {
+        if ( filter == null )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_filter );
+        }
+
+        return filter;
+    }
+
+
+    /**
+     * Checks for extensions.
+     * 
+     * @return true, if has extensions
+     */
+    public boolean hasExtensions()
+    {
+        try
+        {
+            getExtensions();
+            return true;
+        }
+        catch ( NoSuchFieldException e )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Gets the extensions.
+     * 
+     * @return the extensions
+     * @throws NoSuchFieldException if not has extensions
+     */
+    public String getExtensions() throws NoSuchFieldException
+    {
+        if ( extensions == null )
+        {
+            throw new NoSuchFieldException( BrowserCoreMessages.model__url_no_extensions );
+        }
+
+        return extensions;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/URL.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapAndFilterComponent.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapAndFilterComponent.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapAndFilterComponent.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapAndFilterComponent.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,102 @@
+/*
+ *  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.core.model.filter;
+
+
+import java.util.Iterator;
+
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterToken;
+
+
+/**
+ * The LdapAndFilterComponent represents an AND filter branch.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdapAndFilterComponent extends LdapFilterComponent
+{
+
+    /**
+     * Creates a new instance of LdapAndFilterComponent.
+     * 
+     * @param parent the parent filter
+     */
+    public LdapAndFilterComponent( LdapFilter parent )
+    {
+        super( parent );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterComponent#setStartToken(org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterToken)
+     */
+    public boolean setStartToken( LdapFilterToken andToken )
+    {
+        if ( andToken != null && andToken.getType() == LdapFilterToken.AND )
+        {
+            return super.setStartToken( andToken );
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.model.filter.LdapFilterComponent#getInvalidCause()
+     */
+    public String getInvalidCause()
+    {
+        if ( startToken == null )
+        {
+            return "Missing AND character '&'";
+        }
+        else if ( filterList == null || filterList.isEmpty() )
+        {
+            return "Missing filters";
+        }
+        else
+        {
+            return "Invalid AND filter";
+        }
+    }
+
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        String s = startToken != null ? "&" : "";
+        for ( Iterator it = filterList.iterator(); it.hasNext(); )
+        {
+            LdapFilter filter = ( LdapFilter ) it.next();
+            if ( filter != null )
+            {
+                s += filter.toString();
+            }
+        }
+        return s;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapAndFilterComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapFilter.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapFilter.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapFilter.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapFilter.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,305 @@
+/*
+ *  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.core.model.filter;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.model.filter.parser.LdapFilterToken;
+
+
+/**
+ * The LdapFilter class represents an LDAP filter.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdapFilter
+{
+
+    private LdapFilterToken startToken;
+
+    private LdapFilterComponent filterComponent;
+
+    private LdapFilterToken stopToken;
+
+    private List<LdapFilterToken> otherTokens;
+
+
+    /**
+     * Creates a new instance of LdapFilter.
+     */
+    public LdapFilter()
+    {
+        this.startToken = null;
+        this.filterComponent = null;
+        this.stopToken = null;
+        this.otherTokens = new ArrayList<LdapFilterToken>( 2 );
+    }
+
+
+    /**
+     * Sets the start token.
+     * 
+     * @param startToken the start token
+     * 
+     * @return true, if setting the start token was successful, false otherwise
+     */
+    public boolean setStartToken( LdapFilterToken startToken )
+    {
+        if ( this.startToken == null && startToken != null && startToken.getType() == LdapFilterToken.LPAR )
+        {
+            this.startToken = startToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Sets the filter component.
+     * 
+     * @param filterComponent the filter component
+     * 
+     * @return true, if setting the filter component was successful, false otherwise
+     */
+    public boolean setFilterComponent( LdapFilterComponent filterComponent )
+    {
+        if ( this.startToken != null && this.filterComponent == null && filterComponent != null )
+        {
+            this.filterComponent = filterComponent;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Sets the stop token.
+     * 
+     * @param stopToken the stop token
+     * 
+     * @return true, if setting the stop token was successful, false otherwise
+     */
+    public boolean setStopToken( LdapFilterToken stopToken )
+    {
+        if ( this.startToken != null && this.stopToken == null && stopToken != null
+            && stopToken.getType() == LdapFilterToken.RPAR )
+        {
+            this.stopToken = stopToken;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Adds another token.
+     * 
+     * @param otherToken the other token
+     */
+    public void addOtherToken( LdapFilterToken otherToken )
+    {
+        otherTokens.add( otherToken );
+    }
+
+
+    /**
+     * Gets the start token.
+     * 
+     * @return the start token, or null if not set
+     */
+    public LdapFilterToken getStartToken()
+    {
+        return startToken;
+    }
+
+
+    /**
+     * Gets the filter component.
+     * 
+     * @return the filter component, or null if not set
+     */
+    public LdapFilterComponent getFilterComponent()
+    {
+        return filterComponent;
+    }
+
+
+    /**
+     * Gets the stop token.
+     * 
+     * @return the stop token or null if not set
+     */
+    public LdapFilterToken getStopToken()
+    {
+        return stopToken;
+    }
+
+
+    /**
+     * Gets all the tokens.
+     * 
+     * @return the tokens
+     */
+    public LdapFilterToken[] getTokens()
+    {
+        // collect tokens
+        List<LdapFilterToken> tokenList = new ArrayList<LdapFilterToken>();
+        if ( startToken != null )
+        {
+            tokenList.add( startToken );
+        }
+        if ( stopToken != null )
+        {
+            tokenList.add( stopToken );
+        }
+        if ( filterComponent != null )
+        {
+            tokenList.addAll( Arrays.asList( filterComponent.getTokens() ) );
+        }
+        tokenList.addAll( otherTokens );
+
+        // sort tokens
+        LdapFilterToken[] tokens = tokenList.toArray( new LdapFilterToken[tokenList.size()] );
+        Arrays.sort( tokens );
+
+        // return
+        return tokens;
+    }
+
+
+    /**
+     * Checks if this filter and all its subfilters are valid.
+     * 
+     * @return true, if this filter and all its subfilters is valid
+     */
+    public boolean isValid()
+    {
+        return startToken != null && filterComponent != null && filterComponent.isValid() && stopToken != null;
+    }
+
+
+    /**
+     * Gets the invalid filters. This may be this filter itself or any of the subfilters.
+     * 
+     * @return an array of invalid filters or an empty array if all subfilters
+     *         are valid.
+     */
+    public LdapFilter[] getInvalidFilters()
+    {
+        if ( startToken == null || filterComponent == null || stopToken == null )
+        {
+            return new LdapFilter[]
+                { this };
+        }
+        else
+        {
+            return filterComponent.getInvalidFilters();
+        }
+    }
+
+
+    /**
+     * Gets the filter at the given offset. This may be this filter
+     * or one of the subfilters.
+     * 
+     * @param offset the offset
+     * 
+     * @return the filter at the given offset or null is offset is out of
+     *         range.
+     */
+    public LdapFilter getFilter( int offset )
+    {
+        if ( startToken != null && startToken.getOffset() == offset )
+        {
+            return this;
+        }
+        else if ( stopToken != null && stopToken.getOffset() == offset )
+        {
+            return this;
+        }
+
+        if ( otherTokens != null && otherTokens.size() > 0 )
+        {
+            for ( int i = 0; i < otherTokens.size(); i++ )
+            {
+                LdapFilterToken otherToken = otherTokens.get( i );
+                if ( otherToken != null && otherToken.getOffset() <= offset
+                    && offset < otherToken.getOffset() + otherToken.getLength() )
+                {
+                    return this;
+                }
+            }
+        }
+
+        if ( filterComponent != null )
+        {
+            return filterComponent.getFilter( offset );
+        }
+
+        return this;
+    }
+
+
+    /**
+     * Gets the invalid cause.
+     * 
+     * @return the invalid cause, or null if this filter is valid.
+     */
+    public String getInvalidCause()
+    {
+        if ( stopToken == null )
+        {
+            return BrowserCoreMessages.model_filter_missing_closing_parenthesis;
+        }
+        else if ( filterComponent == null )
+        {
+            return BrowserCoreMessages.model_filter_missing_filter_expression;
+        }
+        else
+        {
+            return filterComponent.getInvalidCause();
+        }
+    }
+
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return ( startToken != null ? "(" : "" ) + ( filterComponent != null ? filterComponent.toString() : "" ) + ( stopToken != null ? ")" : "" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/filter/LdapFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message