You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2010/07/16 17:25:55 UTC

svn commit: r964834 - in /directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src: main/java/org/apache/directory/server/core/entry/FilteredEntry.java test/java/org/apache/directory/server/core/entry/FilteredEntryTest.java

Author: kayyagari
Date: Fri Jul 16 15:25:54 2010
New Revision: 964834

URL: http://svn.apache.org/viewvc?rev=964834&view=rev
Log:
o an implementation of a filterable entry and its test cases

Added:
    directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/main/java/org/apache/directory/server/core/entry/FilteredEntry.java
    directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/test/java/org/apache/directory/server/core/entry/FilteredEntryTest.java

Added: directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/main/java/org/apache/directory/server/core/entry/FilteredEntry.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/main/java/org/apache/directory/server/core/entry/FilteredEntry.java?rev=964834&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/main/java/org/apache/directory/server/core/entry/FilteredEntry.java (added)
+++ directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/main/java/org/apache/directory/server/core/entry/FilteredEntry.java Fri Jul 16 15:25:54 2010
@@ -0,0 +1,634 @@
+/*
+ *   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.server.core.entry;
+
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.UsageEnum;
+
+
+/**
+ * A special wrapper on the Entry object to be used for filtering the attributes according to the
+ * specified search filter.
+ * 
+ *  This class avoids cloning of the attributes until the actual get() method is called.
+ *  A special XXXRef() method is also provided to avoid cloning, but this gives the actual reference
+ *  of the object that is present in wrapped original entry. But if the 'typesOnly' flag is set to
+ *  'true' then the XXXRef() methods will return a cloned object instead of the actual reference.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class FilteredEntry implements Entry
+{
+    /** The original entry as returned by the backend */
+    private Entry originalEntry;
+
+    private static final UnsupportedOperationException UNSUPPORTED_OP_EX = new UnsupportedOperationException(
+        "this operation is not supported" );
+
+    private boolean typesOnly = false;
+
+    private Set<AttributeType> attributeTypes = Collections.unmodifiableSet( Collections.EMPTY_SET );
+
+
+    public FilteredEntry( Entry entry, Set<AttributeType> attributeTypes )
+    {
+        this.originalEntry = entry;
+        if ( attributeTypes != null )
+        {
+            this.attributeTypes = Collections.unmodifiableSet( attributeTypes );
+        }
+    }
+
+
+    public FilteredEntry( Entry entry, Set<AttributeType> attributeTypes, boolean typesOnly )
+    {
+        this( entry, attributeTypes );
+
+        this.typesOnly = typesOnly;
+    }
+
+
+    public static FilteredEntry createFilteredEntry( Entry entry, UsageEnum atUsage )
+    {
+        return new FilteredEntry( entry, getRequestedAttributeTypes( entry, atUsage ) );
+    }
+
+
+    public static FilteredEntry createFilteredEntry( Entry entry )
+    {
+        return new FilteredEntry( entry, entry.getAttributeTypes() );
+    }
+
+
+    public static FilteredEntry createFilteredEntry( Entry entry, UsageEnum atUsage, boolean typesOnly )
+    {
+        return new FilteredEntry( entry, getRequestedAttributeTypes( entry, atUsage ), typesOnly );
+    }
+
+
+    private static Set<AttributeType> getRequestedAttributeTypes( Entry entry, UsageEnum atUsage )
+    {
+        Set<AttributeType> atSet = new HashSet<AttributeType>();
+        for ( EntryAttribute entryAt : entry )
+        {
+            AttributeType at = entryAt.getAttributeType();
+            if ( at.getUsage() == atUsage )
+            {
+                atSet.add( at );
+            }
+        }
+
+        return atSet;
+    }
+
+
+    public DN getDn()
+    {
+        return ( DN ) originalEntry.getDn().clone();
+    }
+
+
+    public DN getDnRef()
+    {
+        return originalEntry.getDn();
+    }
+
+
+    public boolean hasObjectClass( String objectClass )
+    {
+        if ( typesOnly || attributeTypes.isEmpty() )
+        {
+            return false;
+        }
+
+        return originalEntry.hasObjectClass( objectClass );
+    }
+
+
+    public boolean hasObjectClass( EntryAttribute objectClass )
+    {
+        if ( typesOnly || attributeTypes.isEmpty() )
+        {
+            return false;
+        }
+
+        return originalEntry.hasObjectClass( objectClass );
+    }
+
+
+    public EntryAttribute get( String alias )
+    {
+        EntryAttribute at = getRef( alias );
+
+        if ( at != null )
+        {
+            if ( !typesOnly )
+            {
+                at = at.clone();
+            }
+
+            return at;
+        }
+
+        return null;
+    }
+
+
+    public EntryAttribute getRef( String alias )
+    {
+        EntryAttribute at = originalEntry.get( alias );
+
+        if ( at == null )
+        {
+            return null;
+        }
+
+        if ( attributeTypes.contains( at.getAttributeType() ) )
+        {
+            if ( typesOnly )
+            {
+                at = at.clone();
+                at.clear();
+            }
+
+            return at;
+        }
+
+        return null;
+    }
+
+
+    public EntryAttribute get( AttributeType attributeType )
+    {
+        EntryAttribute at = getRef( attributeType );
+
+        if ( at != null )
+        {
+            return at.clone();
+        }
+
+        return null;
+    }
+
+
+    public EntryAttribute getRef( AttributeType attributeType )
+    {
+        if ( attributeTypes.contains( attributeType ) )
+        {
+            EntryAttribute at = originalEntry.get( attributeType );
+
+            if ( typesOnly )
+            {
+                at = at.clone();
+                at.clear();
+            }
+
+            return at;
+        }
+
+        return null;
+    }
+
+
+    public Set<AttributeType> getAttributeTypes()
+    {
+        return attributeTypes;
+    }
+
+
+    public boolean isValid()
+    {
+        return originalEntry.isValid();
+    }
+
+
+    public boolean isValid( String objectClass )
+    {
+        return originalEntry.isValid( objectClass );
+    }
+
+
+    public boolean isValid( EntryAttribute objectClass )
+    {
+        return originalEntry.isValid( objectClass );
+    }
+
+
+    public Iterator<EntryAttribute> iterator()
+    {
+        Set<EntryAttribute> entryAtSet = new HashSet<EntryAttribute>();
+
+        for ( AttributeType at : attributeTypes )
+        {
+            EntryAttribute entryAt = originalEntry.get( at ).clone();
+
+            if ( typesOnly )
+            {
+                entryAt.clear();
+            }
+
+            entryAtSet.add( entryAt );
+        }
+
+        return entryAtSet.iterator();
+    }
+
+
+    public Iterator<EntryAttribute> iteratorRef()
+    {
+        Set<EntryAttribute> entryAtSet = new HashSet<EntryAttribute>();
+
+        for ( AttributeType at : attributeTypes )
+        {
+            EntryAttribute entryAt = originalEntry.get( at );
+            if ( typesOnly )
+            {
+                entryAt = entryAt.clone();
+                entryAt.clear();
+            }
+
+            entryAtSet.add( entryAt );
+        }
+
+        return entryAtSet.iterator();
+    }
+
+
+    public boolean contains( String upId ) throws LdapException
+    {
+        EntryAttribute at = getRef( upId );
+
+        if ( at != null )
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+
+    public boolean contains( AttributeType attributeType, byte[]... values )
+    {
+        if ( attributeTypes.contains( attributeType ) )
+        {
+            return originalEntry.contains( attributeType, values );
+        }
+
+        return false;
+    }
+
+
+    public boolean contains( AttributeType attributeType, String... values )
+    {
+        if ( attributeTypes.contains( attributeType ) )
+        {
+            return originalEntry.contains( attributeType, values );
+        }
+
+        return false;
+    }
+
+
+    public boolean contains( AttributeType attributeType, Value<?>... values )
+    {
+        if ( attributeTypes.contains( attributeType ) )
+        {
+            return originalEntry.contains( attributeType, values );
+        }
+
+        return false;
+    }
+
+
+    public boolean containsAttribute( AttributeType attributeType )
+    {
+        return attributeTypes.contains( attributeType );
+    }
+
+
+    public boolean contains( EntryAttribute... attributes ) throws LdapException
+    {
+        for ( EntryAttribute at : attributes )
+        {
+            if ( !attributeTypes.contains( at.getAttributeType() ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    public boolean contains( String upId, byte[]... values )
+    {
+        EntryAttribute at = getRef( upId );
+        if ( at != null )
+        {
+            return originalEntry.contains( at.getAttributeType(), values );
+        }
+
+        return false;
+    }
+
+
+    public boolean contains( String upId, String... values )
+    {
+        EntryAttribute at = getRef( upId );
+        if ( at != null )
+        {
+            return originalEntry.contains( at.getAttributeType(), values );
+        }
+
+        return false;
+    }
+
+
+    public boolean contains( String upId, Value<?>... values )
+    {
+        EntryAttribute at = getRef( upId );
+        if ( at != null )
+        {
+            return originalEntry.contains( at.getAttributeType(), values );
+        }
+
+        return false;
+    }
+
+
+    public boolean containsAttribute( String... attributes )
+    {
+        for ( String s : attributes )
+        {
+            if ( getRef( s ) == null )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    public int size()
+    {
+        return attributeTypes.size();
+    }
+
+
+    public boolean isTypesOnly()
+    {
+        return typesOnly;
+    }
+
+
+    // ----------------- unsupported operations ------------------------
+
+    public void writeExternal( ObjectOutput out ) throws IOException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void clear()
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public Entry clone()
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public List<EntryAttribute> set( String... upIds )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public List<EntryAttribute> set( AttributeType... attributeTypes )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void setDn( DN dn )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( EntryAttribute... attributes ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( AttributeType attributeType, byte[]... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( AttributeType attributeType, String... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( AttributeType attributeType, Value<?>... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( String upId, AttributeType attributeType, byte[]... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( String upId, AttributeType attributeType, String... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( String upId, AttributeType attributeType, Value<?>... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( String upId, String... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( String upId, byte[]... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public void add( String upId, Value<?>... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public List<EntryAttribute> put( EntryAttribute... attributes ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( AttributeType attributeType, byte[]... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( AttributeType attributeType, String... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( AttributeType attributeType, Value<?>... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( String upId, AttributeType attributeType, byte[]... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( String upId, AttributeType attributeType, String... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( String upId, AttributeType attributeType, Value<?>... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( String upId, byte[]... values )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( String upId, String... values )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public EntryAttribute put( String upId, Value<?>... values )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public boolean remove( AttributeType attributeType, byte[]... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public boolean remove( AttributeType attributeType, String... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public boolean remove( AttributeType attributeType, Value<?>... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public List<EntryAttribute> remove( EntryAttribute... attributes ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public List<EntryAttribute> removeAttributes( AttributeType... attributes )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public boolean remove( String upId, byte[]... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public boolean remove( String upId, String... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public boolean remove( String upId, Value<?>... values ) throws LdapException
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+
+
+    public List<EntryAttribute> removeAttributes( String... attributes )
+    {
+        throw UNSUPPORTED_OP_EX;
+    }
+}

Added: directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/test/java/org/apache/directory/server/core/entry/FilteredEntryTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/test/java/org/apache/directory/server/core/entry/FilteredEntryTest.java?rev=964834&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/test/java/org/apache/directory/server/core/entry/FilteredEntryTest.java (added)
+++ directory/apacheds/branches/apacheds-noentryclone-experiment/core-api/src/test/java/org/apache/directory/server/core/entry/FilteredEntryTest.java Fri Jul 16 15:25:54 2010
@@ -0,0 +1,249 @@
+/*
+ *   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.server.core.entry;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.SchemaManager;
+import org.apache.directory.shared.ldap.schema.UsageEnum;
+import org.apache.directory.shared.ldap.schema.ldif.extractor.SchemaLdifExtractor;
+import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.DefaultSchemaLdifExtractor;
+import org.apache.directory.shared.ldap.schema.loader.ldif.LdifSchemaLoader;
+import org.apache.directory.shared.ldap.schema.manager.impl.DefaultSchemaManager;
+import org.apache.directory.shared.ldap.util.DateUtils;
+import org.apache.directory.shared.ldap.util.LdapExceptionUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+/**
+ * Test cases for FilteredEntry class.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class FilteredEntryTest
+{
+
+    private static final byte[] BYTES1 = new byte[]
+        { 'a', 'b' };
+
+    private static LdifSchemaLoader loader;
+    private static SchemaManager schemaManager;
+
+    private static DN EXAMPLE_DN;
+
+
+    /**
+     * Initialize the registries once for the whole test suite
+     */
+    @BeforeClass
+    public static void setup() throws Exception
+    {
+        String workingDirectory = System.getProperty( "workingDirectory" );
+
+        if ( workingDirectory == null )
+        {
+            String path = SchemaAwareEntryTest.class.getResource( "" ).getPath();
+            int targetPos = path.indexOf( "target" );
+            workingDirectory = path.substring( 0, targetPos + 6 );
+        }
+
+        File schemaRepository = new File( workingDirectory, "schema" );
+        SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
+        extractor.extractOrCopy( true );
+        loader = new LdifSchemaLoader( schemaRepository );
+
+        schemaManager = new DefaultSchemaManager( loader );
+        schemaManager.loadAllEnabled();
+
+        List<Throwable> errors = schemaManager.getErrors();
+
+        if ( errors.size() != 0 )
+        {
+            fail( "Schema load failed : " + LdapExceptionUtils.printErrors( errors ) );
+        }
+
+        EXAMPLE_DN = new DN( "dc=example,dc=com" );
+    }
+
+
+    /**
+     * Helper method which creates an entry with 4 attributes.
+     */
+    private Entry createEntry()
+    {
+        try
+        {
+            Entry entry = new DefaultEntry( schemaManager, EXAMPLE_DN );
+
+            EntryAttribute attrOC = new DefaultEntryAttribute( SchemaConstants.OBJECT_CLASS_AT, "top", "person" );
+            EntryAttribute attrCN = new DefaultEntryAttribute( SchemaConstants.CN_AT, "test1", "test2" );
+            EntryAttribute attrSN = new DefaultEntryAttribute( SchemaConstants.SN_AT, "Test1", "Test2" );
+            EntryAttribute attrPWD = new DefaultEntryAttribute( SchemaConstants.USER_PASSWORD_AT, BYTES1 );
+
+            entry.put( attrOC, attrCN, attrSN, attrPWD );
+
+            entry.add( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN );
+            entry.add( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
+
+            return entry;
+        }
+        catch ( LdapException ne )
+        {
+            // Do nothing
+            return null;
+        }
+    }
+
+
+    @Test
+    public void testFilteredEntryWithUserAttributes() throws LdapException
+    {
+        Entry entry = createEntry();
+        FilteredEntry fe = FilteredEntry.createFilteredEntry( entry, UsageEnum.USER_APPLICATIONS );
+        assertEquals( 4, fe.size() );
+
+        assertTrue( fe.contains( SchemaConstants.OBJECT_CLASS_AT ) );
+        assertTrue( fe.contains( SchemaConstants.CN_AT ) );
+        assertTrue( fe.contains( SchemaConstants.SN_AT ) );
+        assertTrue( fe.contains( SchemaConstants.USER_PASSWORD_AT ) );
+
+        assertFalse( fe.contains( SchemaConstants.CREATE_TIMESTAMP_AT ) );
+        assertFalse( fe.contains( SchemaConstants.CREATORS_NAME_AT ) );
+
+        assertTrue( fe.getDnRef() == entry.getDn() );
+        assertFalse( fe.getDn() == entry.getDn() );
+
+        // check some AT which is does not exist in the original entry 
+        assertFalse( fe.contains( SchemaConstants.ACCESS_CONTROL_INNER_AREA_AT ) );
+
+        Iterator<EntryAttribute> itr = fe.iterator();
+        int count = 0;
+        while ( itr.hasNext() )
+        {
+            count++;
+            EntryAttribute entryAt = itr.next();
+            assertTrue( entry.contains( entryAt ) );
+
+            AttributeType at = entryAt.getAttributeType();
+            assertEquals( entry.get( at ).get(), fe.get( at ).get() );
+        }
+
+        assertEquals( 4, count );
+    }
+
+
+    @Test
+    public void testFilteredEntryWithAllAttributes() throws LdapException
+    {
+        Entry entry = createEntry();
+        FilteredEntry fe = FilteredEntry.createFilteredEntry( entry );
+        assertEquals( 6, fe.size() );
+
+        assertTrue( fe.contains( SchemaConstants.OBJECT_CLASS_AT ) );
+        assertTrue( fe.contains( SchemaConstants.CN_AT ) );
+        assertTrue( fe.contains( SchemaConstants.SN_AT ) );
+        assertTrue( fe.contains( SchemaConstants.USER_PASSWORD_AT ) );
+
+        assertTrue( fe.contains( SchemaConstants.CREATE_TIMESTAMP_AT ) );
+        assertTrue( fe.contains( SchemaConstants.CREATORS_NAME_AT ) );
+
+        Iterator<EntryAttribute> itr = fe.iterator();
+        int count = 0;
+        while ( itr.hasNext() )
+        {
+            count++;
+            EntryAttribute entryAt = itr.next();
+            assertTrue( entry.contains( entryAt ) );
+
+            AttributeType at = entryAt.getAttributeType();
+            assertEquals( entry.get( at ).get(), fe.get( at ).get() );
+        }
+
+        assertEquals( 6, count );
+    }
+
+
+    @Test
+    public void testFilteredEntryWithOperationalAttributes() throws LdapException
+    {
+        Entry entry = createEntry();
+        FilteredEntry fe = FilteredEntry.createFilteredEntry( entry, UsageEnum.DIRECTORY_OPERATION );
+
+        assertEquals( 2, fe.size() );
+
+        assertTrue( fe.contains( SchemaConstants.CREATE_TIMESTAMP_AT ) );
+        assertTrue( fe.contains( SchemaConstants.CREATORS_NAME_AT ) );
+
+        assertFalse( fe.contains( SchemaConstants.OBJECT_CLASS_AT ) );
+        assertFalse( fe.contains( SchemaConstants.CN_AT ) );
+        assertFalse( fe.contains( SchemaConstants.SN_AT ) );
+        assertFalse( fe.contains( SchemaConstants.USER_PASSWORD_AT ) );
+
+        // check some AT which is does not exist in the original entry 
+        assertFalse( fe.contains( SchemaConstants.ACCESS_CONTROL_INNER_AREA_AT ) );
+    }
+
+
+    @Test
+    public void testTypesOnly() throws LdapException
+    {
+        Entry entry = createEntry();
+        FilteredEntry fe = FilteredEntry.createFilteredEntry( entry, UsageEnum.DIRECTORY_OPERATION, true );
+
+        assertEquals( 2, fe.size() );
+
+        assertTrue( fe.contains( SchemaConstants.CREATE_TIMESTAMP_AT ) );
+        assertTrue( fe.contains( SchemaConstants.CREATORS_NAME_AT ) );
+
+        assertEquals( 0, fe.get( SchemaConstants.CREATE_TIMESTAMP_AT ).size() );
+        assertEquals( 0, fe.get( SchemaConstants.CREATORS_NAME_AT ).size() );
+    }
+
+
+    @Test
+    public void testNoAttributes() throws LdapException
+    {
+        Entry entry = createEntry();
+        FilteredEntry fe = new FilteredEntry( entry, null );
+
+        assertEquals( 0, fe.size() );
+        assertNotNull( fe.getDn() );
+    }
+
+}