You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2011/10/20 21:42:13 UTC

svn commit: r1187013 [3/12] - in /directory/apacheds/branches/apacheds-txns: ./ all/ apache-felix/ apache-felix/bundle/ apache-felix/src/ apache-felix/src/main/ apache-felix/src/main/resources/ core-annotations/ core-annotations/src/main/java/org/apach...

Added: directory/apacheds/branches/apacheds-txns/core-shared/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/pom.xml?rev=1187013&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/pom.xml (added)
+++ directory/apacheds/branches/apacheds-txns/core-shared/pom.xml Thu Oct 20 19:41:49 2011
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.directory.server</groupId>
+    <artifactId>apacheds-parent</artifactId>
+    <version>2.0.0-M4-SNAPSHOT</version>
+  </parent>
+  
+  <artifactId>apacheds-core-shared</artifactId>
+  <name>ApacheDS Core Shared</name>
+  <packaging>bundle</packaging>
+
+  <description>
+    Contains helper classes that are part of the ApacheDS Core.
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.directory.junit</groupId>
+      <artifactId>junit-addons</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>apacheds-i18n</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>apacheds-core-api</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>apacheds-core-constants</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>commons-collections</groupId>
+      <artifactId>commons-collections</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-ldap-client-api</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-asn1-api</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-i18n</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-ldap-codec-standalone</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-ldap-codec-core</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-ldap-model</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-ldap-schema-data</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-util</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-ldap-extras-util</artifactId>
+    </dependency>
+    
+    <dependency>
+       <groupId>net.sf.ehcache</groupId>
+       <artifactId>ehcache-core</artifactId>
+   </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-tests</id>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestFile>META-INF/MANIFEST.MF</manifestFile>
+            <addMavenDescriptor>false</addMavenDescriptor>
+          </archive>
+        </configuration>
+      </plugin>
+      
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <inherited>true</inherited>
+        <extensions>true</extensions>
+        <configuration>
+          <manifestLocation>META-INF</manifestLocation>
+          <instructions>
+            <Bundle-SymbolicName>${project.groupId}.core.shared</Bundle-SymbolicName>
+            <Export-Package>
+                {local-packages};version=${project.version};-noimport:=true
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
+

Added: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java?rev=1187013&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java (added)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java Thu Oct 20 19:41:49 2011
@@ -0,0 +1,1084 @@
+/*
+ *   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.shared;
+
+
+import java.net.SocketAddress;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.api.CoreSession;
+import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.LdapPrincipal;
+import org.apache.directory.server.core.api.OperationManager;
+import org.apache.directory.server.core.api.changelog.LogChange;
+import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.api.interceptor.context.AbstractOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.CompareOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.EntryOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.ListOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.OperationContext;
+import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.UnbindOperationContext;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.shared.ldap.model.constants.AuthenticationLevel;
+import org.apache.directory.shared.ldap.model.entry.BinaryValue;
+import org.apache.directory.shared.ldap.model.entry.DefaultModification;
+import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.apache.directory.shared.ldap.model.entry.Modification;
+import org.apache.directory.shared.ldap.model.entry.StringValue;
+import org.apache.directory.shared.ldap.model.entry.Value;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+import org.apache.directory.shared.ldap.model.exception.LdapInvalidSearchFilterException;
+import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.apache.directory.shared.ldap.model.filter.FilterParser;
+import org.apache.directory.shared.ldap.model.message.AddRequest;
+import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.model.message.CompareRequest;
+import org.apache.directory.shared.ldap.model.message.Control;
+import org.apache.directory.shared.ldap.model.message.DeleteRequest;
+import org.apache.directory.shared.ldap.model.message.ModifyDnRequest;
+import org.apache.directory.shared.ldap.model.message.ModifyRequest;
+import org.apache.directory.shared.ldap.model.message.SearchRequest;
+import org.apache.directory.shared.ldap.model.message.SearchScope;
+import org.apache.directory.shared.ldap.model.message.UnbindRequest;
+import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.name.Rdn;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.apache.directory.shared.ldap.model.schema.AttributeTypeOptions;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * The default CoreSession implementation.
+ * 
+ * TODO - has not been completed yet
+ * TODO - need to supply controls and other parameters to setup opContexts
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class DefaultCoreSession implements CoreSession
+{
+    private final DirectoryService directoryService;
+    private final LdapPrincipal authenticatedPrincipal;
+    private final LdapPrincipal anonymousPrincipal;
+    private LdapPrincipal authorizedPrincipal;
+
+
+    public DefaultCoreSession( LdapPrincipal principal, DirectoryService directoryService )
+    {
+        this.directoryService = directoryService;
+        this.authenticatedPrincipal = principal;
+        this.anonymousPrincipal = new LdapPrincipal( directoryService.getSchemaManager() );
+    }
+
+
+    /**
+     * Set the ignoreRefferal flag for the current operationContext.
+     *
+     * @param opContext The current operationContext
+     * @param ignoreReferral The flag 
+     */
+    private void setReferralHandling( AbstractOperationContext opContext, boolean ignoreReferral )
+    {
+        if ( ignoreReferral )
+        {
+            opContext.ignoreReferral();
+        }
+        else
+        {
+            opContext.throwReferral();
+        }
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void add( Entry entry ) throws LdapException
+    {
+        add( entry, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void add( Entry entry, boolean ignoreReferral ) throws LdapException
+    {
+        add( entry, ignoreReferral, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void add( Entry entry, LogChange log ) throws LdapException
+    {
+        AddOperationContext addContext = new AddOperationContext( this, entry );
+
+        addContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.add( addContext );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void add( Entry entry, boolean ignoreReferral, LogChange log ) throws LdapException
+    {
+        AddOperationContext addContext = new AddOperationContext( this, entry );
+
+        addContext.setLogChange( log );
+        setReferralHandling( addContext, ignoreReferral );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.add( addContext );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void add( AddRequest addRequest ) throws LdapException
+    {
+        add( addRequest, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void add( AddRequest addRequest, LogChange log ) throws LdapException
+    {
+        AddOperationContext addContext = new AddOperationContext( this, addRequest );
+
+        addContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        try
+        {
+            operationManager.add( addContext );
+        }
+        catch ( LdapException e )
+        {
+            addRequest.getResultResponse().addAllControls( addContext.getResponseControls() );
+            throw e;
+        }
+        addRequest.getResultResponse().addAllControls( addContext.getResponseControls() );
+    }
+
+
+    private Value<?> convertToValue( String oid, Object value ) throws LdapException
+    {
+        Value<?> val = null;
+
+        AttributeType attributeType = directoryService.getSchemaManager().lookupAttributeTypeRegistry( oid );
+
+        // make sure we add the request controls to operation
+        if ( attributeType.getSyntax().isHumanReadable() )
+        {
+            if ( value instanceof String )
+            {
+                val = new StringValue( attributeType, ( String ) value );
+            }
+            else if ( value instanceof byte[] )
+            {
+                val = new StringValue( attributeType, Strings.utf8ToString((byte[]) value) );
+            }
+            else
+            {
+                throw new LdapException( I18n.err( I18n.ERR_309, oid ) );
+            }
+        }
+        else
+        {
+            if ( value instanceof String )
+            {
+                val = new BinaryValue( attributeType, Strings.getBytesUtf8((String) value) );
+            }
+            else if ( value instanceof byte[] )
+            {
+                val = new BinaryValue( attributeType, ( byte[] ) value );
+            }
+            else
+            {
+                throw new LdapException( I18n.err( I18n.ERR_309, oid ) );
+            }
+        }
+
+        return val;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean compare( Dn dn, String oid, Object value ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        return operationManager.compare( new CompareOperationContext( this, dn, oid, convertToValue( oid, value ) ) );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean compare( Dn dn, String oid, Object value, boolean ignoreReferral ) throws LdapException
+    {
+        CompareOperationContext compareContext = new CompareOperationContext( this, dn, oid,
+            convertToValue( oid, value ) );
+
+        setReferralHandling( compareContext, ignoreReferral );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        return operationManager.compare( compareContext );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void delete( Dn dn ) throws LdapException
+    {
+        delete( dn, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void delete( Dn dn, LogChange log ) throws LdapException
+    {
+        DeleteOperationContext deleteContext = new DeleteOperationContext( this, dn );
+
+        deleteContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.delete( deleteContext );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void delete( Dn dn, boolean ignoreReferral ) throws LdapException
+    {
+        delete( dn, ignoreReferral, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void delete( Dn dn, boolean ignoreReferral, LogChange log ) throws LdapException
+    {
+        DeleteOperationContext deleteContext = new DeleteOperationContext( this, dn );
+
+        deleteContext.setLogChange( log );
+        setReferralHandling( deleteContext, ignoreReferral );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.delete( deleteContext );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getAuthenticatedPrincipal()
+     */
+    public LdapPrincipal getAnonymousPrincipal()
+    {
+        return anonymousPrincipal;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getAuthenticatedPrincipal()
+     */
+    public LdapPrincipal getAuthenticatedPrincipal()
+    {
+        return authenticatedPrincipal;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getAuthenticationLevel()
+     */
+    public AuthenticationLevel getAuthenticationLevel()
+    {
+        return getEffectivePrincipal().getAuthenticationLevel();
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getClientAddress()
+     */
+    public SocketAddress getClientAddress()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getControls()
+     */
+    public Set<Control> getControls()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getDirectoryService()
+     */
+    public DirectoryService getDirectoryService()
+    {
+        return directoryService;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getEffectivePrincipal()
+     */
+    public LdapPrincipal getEffectivePrincipal()
+    {
+        if ( authorizedPrincipal == null )
+        {
+            return authenticatedPrincipal;
+        }
+
+        return authorizedPrincipal;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getOutstandingOperations()
+     */
+    public Set<OperationContext> getOutstandingOperations()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#getServiceAddress()
+     */
+    public SocketAddress getServiceAddress()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#isConfidential()
+     */
+    public boolean isConfidential()
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#isVirtual()
+     */
+    public boolean isVirtual()
+    {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+
+    /**
+     * TODO - perhaps we should just use a flag that is calculated on creation
+     * of this session
+     *  
+     * @see org.apache.directory.server.core.api.CoreSession#isAdministrator()
+     */
+    public boolean isAdministrator()
+    {
+        String normName = getEffectivePrincipal().getName();
+        
+        return normName.equals( ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
+    }
+
+
+    /**
+     * TODO - this method impl does not check to see if the principal is in 
+     * the administrators group - it only returns true of the principal is
+     * the actual admin user.  need to make it check groups.
+     * 
+     * TODO - perhaps we should just use a flag that is calculated on creation
+     * of this session
+     *  
+     * @see org.apache.directory.server.core.api.CoreSession#isAnAdministrator()
+     */
+    public boolean isAnAdministrator()
+    {
+        if ( isAdministrator() )
+        {
+            return true;
+        }
+
+        // TODO fix this so it checks groups
+        return false;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#list(org.apache.directory.shared.ldap.model.name.Dn, org.apache.directory.shared.ldap.model.message.AliasDerefMode, java.util.Set)
+     */
+    public EntryFilteringCursor list( Dn dn, AliasDerefMode aliasDerefMode,
+        Set<AttributeTypeOptions> returningAttributes ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        ListOperationContext listContext = new ListOperationContext( this, dn, returningAttributes );
+        listContext.setAliasDerefMode( aliasDerefMode );
+
+        return operationManager.list( listContext );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#list(org.apache.directory.shared.ldap.model.name.Dn, org.apache.directory.shared.ldap.message.AliasDerefMode, java.util.Set, int, int)
+     */
+    public EntryFilteringCursor list( Dn dn, AliasDerefMode aliasDerefMode,
+        Set<AttributeTypeOptions> returningAttributes, long sizeLimit, int timeLimit ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        ListOperationContext listContext = new ListOperationContext( this, dn, returningAttributes );
+        listContext.setSizeLimit( sizeLimit );
+        listContext.setTimeLimit( timeLimit );
+        listContext.setAliasDerefMode( aliasDerefMode );
+
+        return operationManager.list( listContext );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public Entry lookup( Dn dn ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        return operationManager.lookup( new LookupOperationContext( this, dn ) );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Entry lookup( Dn dn, String... attrIds ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        LookupOperationContext lookupContext = new LookupOperationContext( this, dn, attrIds );
+
+        Entry entry = operationManager.lookup( lookupContext );
+
+        return entry;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Entry lookup( Dn dn, Control[] controls, String... attrIds ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        LookupOperationContext lookupContext = new LookupOperationContext( this, dn, attrIds );
+        
+        if ( controls != null )
+        {
+            lookupContext.addRequestControls( controls );
+        }
+
+        Entry entry = operationManager.lookup( lookupContext );
+
+        return entry;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modify( Dn dn, Modification... mods ) throws LdapException
+    {
+        modify( dn, Arrays.asList( mods ), LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modify( Dn dn, List<Modification> mods ) throws LdapException
+    {
+        modify( dn, mods, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modify( Dn dn, List<Modification> mods, LogChange log ) throws LdapException
+    {
+        if ( mods == null )
+        {
+            return;
+        }
+
+        List<Modification> serverModifications = new ArrayList<Modification>( mods.size() );
+
+        for ( Modification mod : mods )
+        {
+            serverModifications.add( new DefaultModification( directoryService.getSchemaManager(), mod ) );
+        }
+
+        ModifyOperationContext modifyContext = new ModifyOperationContext( this, dn, serverModifications );
+
+        modifyContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.modify( modifyContext );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modify( Dn dn, List<Modification> mods, boolean ignoreReferral ) throws LdapException
+    {
+        modify( dn, mods, ignoreReferral, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modify( Dn dn, List<Modification> mods, boolean ignoreReferral, LogChange log ) throws LdapException
+    {
+        if ( mods == null )
+        {
+            return;
+        }
+
+        List<Modification> serverModifications = new ArrayList<Modification>( mods.size() );
+
+        for ( Modification mod : mods )
+        {
+            serverModifications.add( new DefaultModification( directoryService.getSchemaManager(), mod ) );
+        }
+
+        ModifyOperationContext modifyContext = new ModifyOperationContext( this, dn, serverModifications );
+
+        setReferralHandling( modifyContext, ignoreReferral );
+        modifyContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.modify( modifyContext );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void move( Dn dn, Dn newParent ) throws LdapException
+    {
+        move( dn, newParent, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void move( Dn dn, Dn newParent, LogChange log ) throws LdapException
+    {
+        MoveOperationContext moveContext = new MoveOperationContext( this, dn, newParent );
+        moveContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.move( moveContext );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void move( Dn dn, Dn newParent, boolean ignoreReferral ) throws Exception
+    {
+        move( dn, newParent, ignoreReferral, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void move( Dn dn, Dn newParent, boolean ignoreReferral, LogChange log ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        MoveOperationContext moveContext = new MoveOperationContext( this, dn, newParent );
+
+        setReferralHandling( moveContext, ignoreReferral );
+        moveContext.setLogChange( log );
+
+        operationManager.move( moveContext );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void moveAndRename( Dn dn, Dn newParent, Rdn newRdn, boolean deleteOldRdn ) throws LdapException
+    {
+        moveAndRename( dn, newParent, newRdn, deleteOldRdn, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void moveAndRename( Dn dn, Dn newSuperiorDn, Rdn newRdn, boolean deleteOldRdn, LogChange log )
+        throws LdapException
+    {
+        MoveAndRenameOperationContext moveAndRenameContext = new MoveAndRenameOperationContext( this, dn,
+            newSuperiorDn, newRdn, deleteOldRdn );
+
+        moveAndRenameContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.moveAndRename( moveAndRenameContext );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void moveAndRename( Dn dn, Dn newParent, Rdn newRdn, boolean deleteOldRdn, boolean ignoreReferral )
+        throws LdapException
+    {
+        moveAndRename( dn, newParent, newRdn, deleteOldRdn, ignoreReferral, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void moveAndRename( Dn dn, Dn newParent, Rdn newRdn, boolean deleteOldRdn, boolean ignoreReferral,
+        LogChange log ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        MoveAndRenameOperationContext moveAndRenameContext = new MoveAndRenameOperationContext( this, dn, newParent,
+            newRdn, deleteOldRdn );
+
+        moveAndRenameContext.setLogChange( log );
+        setReferralHandling( moveAndRenameContext, ignoreReferral );
+
+        operationManager.moveAndRename( moveAndRenameContext );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rename( Dn dn, Rdn newRdn, boolean deleteOldRdn ) throws LdapException
+    {
+        rename( dn, newRdn, deleteOldRdn, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rename( Dn dn, Rdn newRdn, boolean deleteOldRdn, LogChange log ) throws LdapException
+    {
+        RenameOperationContext renameContext = new RenameOperationContext( this, dn, newRdn, deleteOldRdn );
+
+        renameContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        operationManager.rename( renameContext );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rename( Dn dn, Rdn newRdn, boolean deleteOldRdn, boolean ignoreReferral ) throws LdapException
+    {
+        rename( dn, newRdn, deleteOldRdn, ignoreReferral, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rename( Dn dn, Rdn newRdn, boolean deleteOldRdn, boolean ignoreReferral, LogChange log )
+        throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        RenameOperationContext renameContext = new RenameOperationContext( this, dn, newRdn, deleteOldRdn );
+
+        renameContext.setLogChange( log );
+        setReferralHandling( renameContext, ignoreReferral );
+
+        operationManager.rename( renameContext );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public EntryFilteringCursor search( Dn dn, String filter ) throws LdapException
+    {
+        return search( dn, filter, true );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public EntryFilteringCursor search( Dn dn, String filter, boolean ignoreReferrals ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        ExprNode filterNode = null;
+
+        try
+        {
+            filterNode = ( ExprNode ) FilterParser.parse( directoryService.getSchemaManager(), filter );
+        }
+        catch ( ParseException pe )
+        {
+            throw new LdapInvalidSearchFilterException( pe.getMessage() );
+        }
+
+        SearchOperationContext searchContext = new SearchOperationContext( this, dn, SearchScope.OBJECT, filterNode,
+            null );
+        searchContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
+        setReferralHandling( searchContext, ignoreReferrals );
+
+        return operationManager.search( searchContext );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#search(org.apache.directory.shared.ldap.model.name.Dn, org.apache.directory.shared.ldap.model.filter.SearchScope, org.apache.directory.shared.ldap.model.filter.ExprNode, org.apache.directory.shared.ldap.message.AliasDerefMode, java.util.Set)
+     */
+    public EntryFilteringCursor search( Dn dn, SearchScope scope, ExprNode filter, AliasDerefMode aliasDerefMode,
+        Set<AttributeTypeOptions> returningAttributes ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        SearchOperationContext searchContext = new SearchOperationContext( this, dn, scope, filter, returningAttributes );
+        searchContext.setAliasDerefMode( aliasDerefMode );
+
+        return operationManager.search( searchContext );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.CoreSession#search(org.apache.directory.shared.ldap.model.name.Dn, org.apache.directory.shared.ldap.model.filter.SearchScope, org.apache.directory.shared.ldap.model.filter.ExprNode, org.apache.directory.shared.ldap.model.message.AliasDerefMode, java.util.Set, int, int)
+     */
+    public EntryFilteringCursor search( Dn dn, SearchScope scope, ExprNode filter, AliasDerefMode aliasDerefMode,
+        Set<AttributeTypeOptions> returningAttributes, long sizeLimit, int timeLimit ) throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        SearchOperationContext searchContext = new SearchOperationContext( this, dn, scope, filter, returningAttributes );
+        searchContext.setAliasDerefMode( aliasDerefMode );
+        searchContext.setSizeLimit( sizeLimit );
+        searchContext.setTimeLimit( timeLimit );
+
+        return operationManager.search( searchContext );
+    }
+
+
+    public boolean isAnonymous()
+    {
+        return getEffectivePrincipal().getDn().isEmpty();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean compare( CompareRequest compareRequest ) throws LdapException
+    {
+        CompareOperationContext compareContext = new CompareOperationContext( this, compareRequest );
+        OperationManager operationManager = directoryService.getOperationManager();
+        boolean result = false;
+        try
+        {
+            result = operationManager.compare( compareContext );
+        }
+        catch ( LdapException e )
+        {
+            compareRequest.getResultResponse().addAllControls( compareContext.getResponseControls() );
+            throw e;
+        }
+
+        compareRequest.getResultResponse().addAllControls( compareContext.getResponseControls() );
+        return result;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void delete( DeleteRequest deleteRequest ) throws LdapException
+    {
+        delete( deleteRequest, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void delete( DeleteRequest deleteRequest, LogChange log ) throws LdapException
+    {
+        DeleteOperationContext deleteContext = new DeleteOperationContext( this, deleteRequest );
+
+        deleteContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+        try
+        {
+            operationManager.delete( deleteContext );
+        }
+        catch ( LdapException e )
+        {
+            deleteRequest.getResultResponse().addAllControls( deleteContext.getResponseControls() );
+            throw e;
+        }
+
+        deleteRequest.getResultResponse().addAllControls( deleteContext.getResponseControls() );
+    }
+    
+    
+    /**
+     * {@inheritDoc} 
+     */
+    public boolean exists( String dn ) throws LdapException
+    {
+        return exists( new Dn( dn ) );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public boolean exists( Dn dn ) throws LdapException
+    {
+        EntryOperationContext hasEntryContext = new EntryOperationContext( this, dn );
+        OperationManager operationManager = directoryService.getOperationManager();
+        return operationManager.hasEntry( hasEntryContext );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modify( ModifyRequest modifyRequest ) throws LdapException
+    {
+        modify( modifyRequest, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modify( ModifyRequest modifyRequest, LogChange log ) throws LdapException
+    {
+        ModifyOperationContext modifyContext = new ModifyOperationContext( this, modifyRequest );
+
+        modifyContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        try
+        {
+            operationManager.modify( modifyContext );
+        }
+        catch ( LdapException e )
+        {
+            modifyRequest.getResultResponse().addAllControls( modifyContext.getResponseControls() );
+            throw e;
+        }
+
+        modifyRequest.getResultResponse().addAllControls( modifyContext.getResponseControls() );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void move( ModifyDnRequest modifyDnRequest ) throws LdapException
+    {
+        move( modifyDnRequest, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void move( ModifyDnRequest modifyDnRequest, LogChange log ) throws LdapException
+    {
+        MoveOperationContext moveContext = new MoveOperationContext( this, modifyDnRequest );
+
+        moveContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        try
+        {
+            operationManager.move( moveContext );
+        }
+        catch ( LdapException e )
+        {
+            modifyDnRequest.getResultResponse().addAllControls( moveContext.getResponseControls() );
+            throw e;
+        }
+
+        modifyDnRequest.getResultResponse().addAllControls( moveContext.getResponseControls() );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void moveAndRename( ModifyDnRequest modifyDnRequest ) throws LdapException
+    {
+        moveAndRename( modifyDnRequest, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc} 
+     */
+    public void moveAndRename( ModifyDnRequest modifyDnRequest, LogChange log ) throws LdapException
+    {
+        MoveAndRenameOperationContext moveAndRenameContext = new MoveAndRenameOperationContext( this, modifyDnRequest );
+
+        moveAndRenameContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        try
+        {
+            operationManager.moveAndRename( moveAndRenameContext );
+        }
+        catch ( LdapException e )
+        {
+            modifyDnRequest.getResultResponse().addAllControls( moveAndRenameContext.getResponseControls() );
+            throw e;
+        }
+
+        modifyDnRequest.getResultResponse().addAllControls( moveAndRenameContext.getResponseControls() );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rename( ModifyDnRequest modifyDnRequest ) throws LdapException
+    {
+        rename( modifyDnRequest, LogChange.TRUE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rename( ModifyDnRequest modifyDnRequest, LogChange log ) throws LdapException
+    {
+        RenameOperationContext renameContext = new RenameOperationContext( this, modifyDnRequest );
+
+        renameContext.setLogChange( log );
+
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        try
+        {
+            operationManager.rename( renameContext );
+        }
+        catch ( LdapException e )
+        {
+            modifyDnRequest.getResultResponse().addAllControls( renameContext.getResponseControls() );
+            throw e;
+        }
+
+        modifyDnRequest.getResultResponse().addAllControls( renameContext.getResponseControls() );
+    }
+
+
+    public EntryFilteringCursor search( SearchRequest searchRequest ) throws LdapException
+    {
+        SearchOperationContext searchContext = new SearchOperationContext( this, searchRequest );
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        EntryFilteringCursor cursor = null;
+
+        try
+        {
+            cursor = operationManager.search( searchContext );
+        }
+        catch ( LdapException e )
+        {
+            searchRequest.getResultResponse().addAllControls( searchContext.getResponseControls() );
+            throw e;
+        }
+
+        searchRequest.getResultResponse().addAllControls( searchContext.getResponseControls() );
+
+        return cursor;
+    }
+
+
+    public void unbind() throws LdapException
+    {
+        OperationManager operationManager = directoryService.getOperationManager();
+        operationManager.unbind( new UnbindOperationContext( this ) );
+    }
+
+
+    public void unbind( UnbindRequest unbindRequest )
+    {
+        // TODO Auto-generated method stub
+    }
+}

Added: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultDnFactory.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultDnFactory.java?rev=1187013&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultDnFactory.java (added)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultDnFactory.java Thu Oct 20 19:41:49 2011
@@ -0,0 +1,156 @@
+/*
+ *   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.shared;
+
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import org.apache.directory.server.core.api.DnFactory;
+import org.apache.directory.shared.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * The default Dn factory implementation.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class DefaultDnFactory implements DnFactory
+{
+    private static final Logger LOG = LoggerFactory.getLogger( DefaultDnFactory.class );
+
+    /** The cache for DNs */
+    private Cache dnCache;
+
+    /** The schema manager */
+    private SchemaManager schemaManager;
+
+    /** Flag to enable stats */
+    private boolean enableStats = false;
+
+    // stat counters
+    private int hitCount = 0;
+    private int missCount = 0;
+
+
+    /**
+     * Instantiates a new default Dn factory.
+     *
+     * @param directoryService the directory service
+     */
+    public DefaultDnFactory( SchemaManager schemaManager, Cache dnCache )
+    {
+        this.schemaManager = schemaManager;
+        this.dnCache = dnCache;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Dn create( String dn ) throws LdapInvalidDnException
+    {
+        if ( dn == null )
+        {
+            return null;
+        }
+
+        if ( dn.trim().length() == 0 )
+        {
+            return Dn.ROOT_DSE;
+        }
+
+        Dn cachedDn = null;
+
+        // read the explanation at the above DN_CACHE variable declaration
+        // for the reason for performing this check
+        if ( dnCache != null )
+        {
+            Element dnCacheEntry = dnCache.get( dn );
+
+            if ( dnCacheEntry != null )
+            {
+                cachedDn = (Dn) dnCacheEntry.getObjectValue();
+            }
+        }
+
+        if ( cachedDn == null )
+        {
+            LOG.debug( "Dn {} not found in the cache, creating", dn );
+
+            cachedDn = new Dn( schemaManager, dn );
+
+            if ( dnCache != null )
+            {
+                dnCache.put( new Element( dn, cachedDn) );
+            }
+
+            if ( enableStats )
+            {
+                missCount++;
+            }
+        }
+        else
+        {
+            if ( !cachedDn.isSchemaAware() && ( schemaManager != null ) )
+            {
+                cachedDn.apply( schemaManager );
+            }
+
+            if ( enableStats )
+            {
+                hitCount++;
+            }
+        }
+
+        LOG.debug( "Dn {} found in the cache", dn );
+
+        if ( enableStats )
+        {
+            System.out.println( "Dn cache hit - " + hitCount + ", miss - " + missCount + " and is normalized = "
+                + cachedDn.isSchemaAware() );
+        }
+
+        return cachedDn;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Dn create( String... upRdns ) throws LdapInvalidDnException
+    {
+        StringBuilder sb = new StringBuilder();
+        for ( String s : upRdns )
+        {
+            sb.append( s ).append( ',' );
+        }
+
+        String dn = sb.toString();
+        dn = dn.substring( 0, dn.length() - 1 );
+        return create( dn );
+    }
+
+}

Added: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java?rev=1187013&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java (added)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java Thu Oct 20 19:41:49 2011
@@ -0,0 +1,287 @@
+/*
+ *  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.shared;
+
+
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import javax.naming.directory.SearchControls;
+
+import org.apache.directory.server.core.api.CoreSession;
+import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.ReferralManager;
+import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.api.partition.PartitionNexus;
+import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.apache.directory.shared.ldap.model.entry.StringValue;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+import org.apache.directory.shared.ldap.model.exception.LdapOperationException;
+import org.apache.directory.shared.ldap.model.filter.EqualityNode;
+import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.tree.DnNode;
+
+
+/**
+ * Implement a referral Manager, handling the requests from the LDAP protocol.
+ * <br>
+ * Referrals are stored in a tree, where leaves are the referrals. We are using
+ * the very same structure than for the partition manager.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ReferralManagerImpl implements ReferralManager
+{
+    /** The referrals tree */
+    private DnNode<Entry> referrals;
+
+    /** A lock to guarantee the manager consistency */
+    private ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();
+
+    /** A storage for the ObjectClass attributeType */
+    private AttributeType OBJECT_CLASS_AT;
+
+
+    /**
+     *
+     * Creates a new instance of ReferralManagerImpl.
+     *
+     * @param directoryService The directory service
+     * @throws Exception If we can't initialize the manager
+     */
+    public ReferralManagerImpl( DirectoryService directoryService ) throws LdapException
+    {
+        lockWrite();
+
+        referrals = new DnNode<Entry>();
+        PartitionNexus nexus = directoryService.getPartitionNexus();
+
+        Set<String> suffixes = nexus.listSuffixes();
+        OBJECT_CLASS_AT = directoryService.getSchemaManager().getAttributeType( SchemaConstants.OBJECT_CLASS_AT );
+
+        init( directoryService, suffixes.toArray( new String[]{} ) );
+
+        unlock();
+    }
+
+
+    /**
+     * Get a read-lock on the referralManager.
+     * No read operation can be done on the referralManager if this
+     * method is not called before.
+     */
+    public void lockRead()
+    {
+        mutex.readLock().lock();
+    }
+
+
+    /**
+     * Get a write-lock on the referralManager.
+     * No write operation can be done on the referralManager if this
+     * method is not called before.
+     */
+    public void lockWrite()
+    {
+        mutex.writeLock().lock();
+    }
+
+
+    /**
+     * Release the read-write lock on the referralManager.
+     * This method must be called after having read or modified the
+     * ReferralManager
+     */
+    public void unlock()
+    {
+        if ( mutex.isWriteLockedByCurrentThread() )
+        {
+            mutex.writeLock().unlock();
+        }
+        else
+        {
+            mutex.readLock().unlock();
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    // This will suppress PMD.EmptyCatchBlock warnings in this method
+    @SuppressWarnings("PMD.EmptyCatchBlock")
+    public void addReferral( Entry entry )
+    {
+        try
+        {
+            referrals.add( entry.getDn(), entry );
+        }
+        catch ( LdapException ne )
+        {
+            // Do nothing
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void init( DirectoryService directoryService, String... suffixes ) throws LdapException
+    {
+        ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
+            new StringValue( SchemaConstants.REFERRAL_OC ) );
+
+        // Lookup for each entry with the ObjectClass = Referral value
+        SearchControls searchControl = new SearchControls();
+        searchControl.setReturningObjFlag( false );
+        searchControl.setSearchScope( SearchControls.SUBTREE_SCOPE );
+
+        CoreSession adminSession = directoryService.getAdminSession();
+        PartitionNexus nexus = directoryService.getPartitionNexus();
+
+        for ( String suffix:suffixes )
+        {
+            // We will store each entry's Dn into the Referral tree
+            Dn suffixDn = directoryService.getDnFactory().create( suffix );
+
+            SearchOperationContext searchOperationContext = new SearchOperationContext( adminSession, suffixDn, referralFilter, searchControl );
+            searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
+            EntryFilteringCursor cursor = nexus.search( searchOperationContext );
+
+            try
+            {
+                // Move to the first entry in the cursor
+                cursor.beforeFirst();
+
+                while ( cursor.next() )
+                {
+                    Entry entry = cursor.get();
+
+                    // Lock the referralManager
+                    lockWrite();
+
+                    // Add it at the right place
+                    addReferral( entry );
+
+                    // Unlock the referralManager
+                    unlock();
+                }
+
+                cursor.close();
+            }
+            catch ( Exception e )
+            {
+                throw new LdapOperationException( e.getMessage(), e );
+            }
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void remove( DirectoryService directoryService, Dn suffix ) throws Exception
+    {
+        ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
+            new StringValue( SchemaConstants.REFERRAL_OC ) );
+
+        // Lookup for each entry with the ObjectClass = Referral value
+        SearchControls searchControl = new SearchControls();
+        searchControl.setReturningObjFlag( false );
+        searchControl.setSearchScope( SearchControls.SUBTREE_SCOPE );
+
+        CoreSession adminSession = directoryService.getAdminSession();
+        PartitionNexus nexus = directoryService.getPartitionNexus();
+
+        // We will store each entry's Dn into the Referral tree
+        SearchOperationContext searchOperationContext = new SearchOperationContext( adminSession, suffix,
+            referralFilter, searchControl );
+        searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
+        EntryFilteringCursor cursor = nexus.search( searchOperationContext );
+
+        // Move to the first entry in the cursor
+        cursor.beforeFirst();
+
+        while ( cursor.next() )
+        {
+            Entry entry = cursor.get();
+
+            // Add it at the right place
+            removeReferral( entry );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasParentReferral( Dn dn )
+    {
+        DnNode<Entry> referral = referrals.getNode( dn );
+
+        return ( referral != null ) && referral.isLeaf();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Entry getParentReferral( Dn dn )
+    {
+        if ( !hasParentReferral( dn ) )
+        {
+            return null;
+        }
+
+        return referrals.getElement( dn );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isReferral( Dn dn )
+    {
+        Entry parent = referrals.getElement( dn );
+
+        if ( parent != null )
+        {
+            return dn.equals( parent.getDn() );
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeReferral( Entry entry ) throws LdapException
+    {
+        referrals.remove( entry.getDn() );
+    }
+}

Added: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/SchemaService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/SchemaService.java?rev=1187013&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/SchemaService.java (added)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/SchemaService.java Thu Oct 20 19:41:49 2011
@@ -0,0 +1,543 @@
+/*
+ * 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.shared;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directory.server.constants.ApacheSchemaConstants;
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
+import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.entry.Attribute;
+import org.apache.directory.shared.ldap.model.entry.DefaultAttribute;
+import org.apache.directory.shared.ldap.model.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.apache.directory.shared.ldap.model.schema.DITContentRule;
+import org.apache.directory.shared.ldap.model.schema.DITStructureRule;
+import org.apache.directory.shared.ldap.model.schema.LdapComparator;
+import org.apache.directory.shared.ldap.model.schema.LdapSyntax;
+import org.apache.directory.shared.ldap.model.schema.MatchingRule;
+import org.apache.directory.shared.ldap.model.schema.MatchingRuleUse;
+import org.apache.directory.shared.ldap.model.schema.NameForm;
+import org.apache.directory.shared.ldap.model.schema.Normalizer;
+import org.apache.directory.shared.ldap.model.schema.ObjectClass;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.apache.directory.shared.ldap.model.schema.SchemaUtils;
+import org.apache.directory.shared.ldap.model.schema.SyntaxChecker;
+import org.apache.directory.shared.ldap.model.schema.registries.NormalizerRegistry;
+import org.apache.directory.shared.util.StringConstants;
+
+
+/**
+ * This class manage the Schema's operations. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SchemaService
+{
+    /** cached version of the schema subentry with all attributes in it */
+    private static Entry schemaSubentry;
+    
+    /** A lock to avid concurrent generation of the SubschemaSubentry */
+    private static Object schemaSubentrLock = new Object();
+
+
+    /**
+     * Generate the comparators attribute from the registry
+     */
+    private static Attribute generateComparators( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.lookupAttributeTypeRegistry( SchemaConstants.COMPARATORS_AT ) );
+
+        for ( LdapComparator<?> comparator : schemaManager.getComparatorRegistry() )
+        {
+            attr.add( SchemaUtils.render( comparator ) );
+        }
+
+        return attr;
+    }
+
+
+    private static Attribute generateNormalizers( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.NORMALIZERS_AT ) );
+
+        NormalizerRegistry nr = schemaManager.getNormalizerRegistry();
+        
+        for ( Normalizer normalizer : nr )
+        {
+            attr.add( SchemaUtils.render( normalizer ) );
+        }
+
+        return attr;
+    }
+
+
+    private static Attribute generateSyntaxCheckers( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.SYNTAX_CHECKERS_AT ) );
+
+        for ( SyntaxChecker syntaxChecker : schemaManager.getSyntaxCheckerRegistry() )
+        {
+            attr.add( SchemaUtils.render( syntaxChecker ) );
+        }
+        
+        return attr;
+    }
+
+
+    private static Attribute generateObjectClasses( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute(
+            schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASSES_AT ) );
+
+        for ( ObjectClass objectClass : schemaManager.getObjectClassRegistry() )
+        {
+            attr.add( SchemaUtils.render( objectClass ).toString() );
+        }
+
+        return attr;
+    }
+
+
+    private static Attribute generateAttributeTypes( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.ATTRIBUTE_TYPES_AT ) );
+
+        for ( AttributeType attributeType : schemaManager.getAttributeTypeRegistry() )
+        {
+            attr.add( SchemaUtils.render( attributeType ).toString() );
+        }
+
+        return attr;
+    }
+
+
+    private static Attribute generateMatchingRules( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.MATCHING_RULES_AT ) );
+
+        for ( MatchingRule matchingRule : schemaManager.getMatchingRuleRegistry() )
+        {
+            attr.add( SchemaUtils.render( matchingRule ).toString() );
+        }
+
+        return attr;
+    }
+
+
+    private static Attribute generateMatchingRuleUses( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute(
+            schemaManager.getAttributeType( SchemaConstants.MATCHING_RULE_USE_AT ) );
+
+        for ( MatchingRuleUse matchingRuleUse : schemaManager.getMatchingRuleUseRegistry() )
+        {
+            attr.add( SchemaUtils.render( matchingRuleUse ).toString() );
+        }
+
+        return attr;
+    }
+
+
+    private static Attribute generateSyntaxes( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.LDAP_SYNTAXES_AT ) );
+
+        for ( LdapSyntax syntax : schemaManager.getLdapSyntaxRegistry() )
+        {
+            attr.add( SchemaUtils.render( syntax ).toString() );
+        }
+
+        return attr;
+    }
+
+
+    private static Attribute generateDitContextRules( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.DIT_CONTENT_RULES_AT ) );
+
+        for ( DITContentRule ditContentRule : schemaManager.getDITContentRuleRegistry() )
+        {
+            attr.add( SchemaUtils.render( ditContentRule ).toString() );
+        }
+        
+        return attr;
+    }
+
+
+    private static Attribute generateDitStructureRules( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.DIT_STRUCTURE_RULES_AT ) );
+
+        for ( DITStructureRule ditStructureRule : schemaManager.getDITStructureRuleRegistry() )
+        {
+            attr.add( SchemaUtils.render( ditStructureRule ).toString() );
+        }
+        
+        return attr;
+    }
+
+
+    private static Attribute generateNameForms( SchemaManager schemaManager ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( 
+            schemaManager.getAttributeType( SchemaConstants.NAME_FORMS_AT ) );
+
+        for ( NameForm nameForm : schemaManager.getNameFormRegistry() )
+        {
+            attr.add( SchemaUtils.render( nameForm ).toString() );
+        }
+        
+        return attr;
+    }
+
+
+    /**
+     * Creates the SSSE by extracting all the SchemaObjects from the registries.
+     */
+    private static void generateSchemaSubentry( SchemaManager schemaManager, Entry mods ) throws LdapException
+    {
+        Entry attrs = new DefaultEntry( schemaManager, mods.getDn() );
+
+        // add the objectClass attribute : 'top', 'subschema', 'subentry' and 'apacheSubschema' 
+        attrs.put( SchemaConstants.OBJECT_CLASS_AT, 
+            SchemaConstants.TOP_OC,
+            SchemaConstants.SUBSCHEMA_OC,
+            SchemaConstants.SUBENTRY_OC,
+            ApacheSchemaConstants.APACHE_SUBSCHEMA_OC
+            );
+
+        // add the cn attribute as required for the Rdn
+        attrs.put( SchemaConstants.CN_AT, "schema" );
+
+        // generate all the other operational attributes
+        attrs.put( generateComparators( schemaManager ) );
+        attrs.put( generateNormalizers( schemaManager ) );
+        attrs.put( generateSyntaxCheckers( schemaManager ) );
+        attrs.put( generateObjectClasses( schemaManager ) );
+        attrs.put( generateAttributeTypes( schemaManager ) );
+        attrs.put( generateMatchingRules( schemaManager ) );
+        attrs.put( generateMatchingRuleUses( schemaManager ) );
+        attrs.put( generateSyntaxes( schemaManager ) );
+        attrs.put( generateDitContextRules( schemaManager ) );
+        attrs.put( generateDitStructureRules( schemaManager ) );
+        attrs.put( generateNameForms( schemaManager ) );
+        attrs.put( SchemaConstants.SUBTREE_SPECIFICATION_AT, "{}" );
+
+        // -------------------------------------------------------------------
+        // set standard operational attributes for the subentry
+        // -------------------------------------------------------------------
+
+        // Add the createTimestamp
+        Attribute createTimestamp = mods.get( SchemaConstants.CREATE_TIMESTAMP_AT );
+        attrs.put( SchemaConstants.CREATE_TIMESTAMP_AT, createTimestamp.get() );
+
+        // Add the creatorsName
+        attrs.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN );
+
+        // Add the modifyTimestamp
+        Attribute schemaModifyTimestamp = mods.get( ApacheSchemaConstants.SCHEMA_MODIFY_TIMESTAMP_AT );
+        attrs.put( SchemaConstants.MODIFY_TIMESTAMP_AT, schemaModifyTimestamp.get() );
+
+        // Add the modifiersName
+        Attribute schemaModifiersName = mods.get( ApacheSchemaConstants.SCHEMA_MODIFIERS_NAME_AT );
+        attrs.put( SchemaConstants.MODIFIERS_NAME_AT, schemaModifiersName.get() );
+
+        // don't swap out if a request for the subentry is in progress or we
+        // can give back an inconsistent schema back to the client so we block
+        synchronized ( schemaSubentrLock )
+        {
+            schemaSubentry = attrs;
+        }
+    }
+
+
+    private static void addAttribute( Entry attrs, String id ) throws LdapException
+    {
+        Attribute attr = schemaSubentry.get( id );
+
+        if ( attr != null )
+        {
+            attrs.put( attr );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public static Entry getSubschemaEntryImmutable( DirectoryService directoryService ) throws LdapException
+    {
+        synchronized ( schemaSubentrLock )
+        {
+            if ( schemaSubentry == null )
+            {
+                Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(), 
+                    SchemaConstants.SCHEMA_MODIFICATIONS_DN );
+
+                generateSchemaSubentry( 
+                    directoryService.getSchemaManager(), 
+                    directoryService.getSchemaPartition().lookup(
+                        new LookupOperationContext( null, schemaModificationAttributesDn) ) );
+            }
+    
+            return ( Entry ) schemaSubentry.clone();
+        }
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.directory.server.core.schema.SchemaService#getSubschemaEntryCloned()
+     */
+    public static Entry getSubschemaEntryCloned( DirectoryService directoryService ) throws LdapException
+    {
+        if ( schemaSubentry == null )
+        {
+            Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(), 
+                SchemaConstants.SCHEMA_MODIFICATIONS_DN );
+
+            generateSchemaSubentry( 
+                directoryService.getSchemaManager(), 
+                directoryService.getSchemaPartition().lookup(
+                    new LookupOperationContext( null, schemaModificationAttributesDn) ) );
+        }
+
+        return ( Entry ) schemaSubentry.clone();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public static Entry getSubschemaEntry( DirectoryService directoryService, String[] ids ) throws LdapException
+    {
+        if ( ids == null )
+        {
+            ids = StringConstants.EMPTY_STRINGS;
+        }
+        
+        SchemaManager schemaManager = directoryService.getSchemaManager();
+
+        Set<String> setOids = new HashSet<String>();
+        Entry attrs = new DefaultEntry( schemaManager, Dn.ROOT_DSE );
+        boolean returnAllOperationalAttributes = false;
+
+        synchronized( schemaSubentrLock )
+        {
+            // ---------------------------------------------------------------
+            // Check if we need an update by looking at timestamps on disk
+            // ---------------------------------------------------------------
+            Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(), 
+                SchemaConstants.SCHEMA_MODIFICATIONS_DN );
+
+            Entry mods = 
+                directoryService.getSchemaPartition().lookup( 
+                    new LookupOperationContext( null, schemaModificationAttributesDn, SchemaConstants.ALL_ATTRIBUTES_ARRAY ) );
+            
+// @todo enable this optimization at some point but for now it
+// is causing some problems so I will just turn it off
+//          Attribute modifyTimeDisk = mods.get( SchemaConstants.MODIFY_TIMESTAMP_AT );
+//
+//          Attribute modifyTimeMemory = null;
+//
+//            if ( schemaSubentry != null )
+//            {
+//                modifyTimeMemory = schemaSubentry.get( SchemaConstants.MODIFY_TIMESTAMP_AT );
+//                if ( modifyTimeDisk == null && modifyTimeMemory == null )
+//                {
+//                    // do nothing!
+//                }
+//                else if ( modifyTimeDisk != null && modifyTimeMemory != null )
+//                {
+//                    Date disk = DateUtils.getDate( ( String ) modifyTimeDisk.get() );
+//                    Date mem = DateUtils.getDate( ( String ) modifyTimeMemory.get() );
+//                    if ( disk.after( mem ) )
+//                    {
+//                        generateSchemaSubentry( mods );
+//                    }
+//                }
+//                else
+//                {
+//                    generateSchemaSubentry( mods );
+//                }
+//            }
+//            else
+//            {
+                generateSchemaSubentry( schemaManager, mods );
+//            }
+
+            // ---------------------------------------------------------------
+            // Prep Work: Transform the attributes to their OID counterpart
+            // ---------------------------------------------------------------
+
+            for ( String id:ids )
+            {
+                // Check whether the set contains a plus, and use it below to include all
+                // operational attributes.  Due to RFC 3673, and issue DIREVE-228 in JIRA
+                if ( SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES.equals( id ) )
+                {
+                    returnAllOperationalAttributes = true;
+                }
+                else if ( SchemaConstants.ALL_USER_ATTRIBUTES.equals(  id ) )
+                {
+                    setOids.add( id );
+                }
+                else
+                {
+                    setOids.add( schemaManager.getAttributeTypeRegistry().getOidByName( id ) );
+                }
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.COMPARATORS_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.COMPARATORS_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.NORMALIZERS_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.NORMALIZERS_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.SYNTAX_CHECKERS_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.SYNTAX_CHECKERS_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.OBJECT_CLASSES_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.OBJECT_CLASSES_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.ATTRIBUTE_TYPES_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.ATTRIBUTE_TYPES_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.MATCHING_RULES_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.MATCHING_RULES_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.MATCHING_RULE_USE_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.MATCHING_RULE_USE_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.LDAP_SYNTAXES_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.LDAP_SYNTAXES_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.DIT_CONTENT_RULES_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.DIT_CONTENT_RULES_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.DIT_STRUCTURE_RULES_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.DIT_STRUCTURE_RULES_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.NAME_FORMS_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.NAME_FORMS_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.SUBTREE_SPECIFICATION_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.SUBTREE_SPECIFICATION_AT );
+            }
+
+            int minSetSize = 0;
+            
+            if ( setOids.contains( SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES ) )
+            {
+                minSetSize++;
+            }
+
+            if ( setOids.contains( SchemaConstants.ALL_USER_ATTRIBUTES ) )
+            {
+                minSetSize++;
+            }
+
+            if ( setOids.contains( SchemaConstants.REF_AT_OID ) )
+            {
+                minSetSize++;
+            }
+
+            // add the objectClass attribute
+            if ( setOids.contains( SchemaConstants.ALL_USER_ATTRIBUTES ) ||
+                 setOids.contains( SchemaConstants.OBJECT_CLASS_AT_OID ) ||
+                 setOids.size() == minSetSize )
+            {
+                addAttribute( attrs, SchemaConstants.OBJECT_CLASS_AT );
+            }
+
+            // add the cn attribute as required for the Rdn
+            if ( setOids.contains( SchemaConstants.ALL_USER_ATTRIBUTES ) ||
+                 setOids.contains( SchemaConstants.CN_AT_OID ) ||
+                 setOids.size() == minSetSize )
+            {
+                addAttribute( attrs, SchemaConstants.CN_AT );
+            }
+
+            // -------------------------------------------------------------------
+            // set standard operational attributes for the subentry
+            // -------------------------------------------------------------------
+
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.CREATE_TIMESTAMP_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.CREATE_TIMESTAMP_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.CREATORS_NAME_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.CREATORS_NAME_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.MODIFY_TIMESTAMP_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.MODIFY_TIMESTAMP_AT );
+            }
+
+            if ( returnAllOperationalAttributes || setOids.contains( SchemaConstants.MODIFIERS_NAME_AT_OID ) )
+            {
+                addAttribute( attrs, SchemaConstants.MODIFIERS_NAME_AT );
+            }
+        }
+
+        return attrs;
+    }
+}