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 2009/08/05 19:55:16 UTC

svn commit: r801340 [8/13] - in /directory/apacheds/trunk: core-entry/src/main/java/org/apache/directory/server/core/entry/ core-entry/src/test/java/org/apache/directory/server/core/entry/ core-integ/src/main/java/org/apache/directory/server/core/integ...

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLog.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLog.java?rev=801340&r1=801339&r2=801340&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLog.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLog.java Wed Aug  5 17:55:15 2009
@@ -1,409 +1,409 @@
-/*
- * 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.changelog;
-
-
-import java.util.List;
-
-import org.apache.directory.server.core.DirectoryService;
-import org.apache.directory.server.core.authn.LdapPrincipal;
-import org.apache.directory.server.core.partition.Partition;
-import org.apache.directory.shared.ldap.ldif.LdifEntry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * The default ChangeLog service implementation. It stores operations 
- * in memory.
- * 
- * Entries are stored into a dedicated partition, named ou=changelog, under which
- * we have two other sub-entries : ou=tags and ou= revisions :
- * 
- *  ou=changelog
- *    |
- *    +-- ou=revisions
- *    |
- *    +-- ou=tags
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class DefaultChangeLog implements ChangeLog
-{
-    /** The class logger */
-    private static final Logger LOG = LoggerFactory.getLogger( DefaultChangeLog.class );
-
-    /** Tells if the service is activated or not */ 
-    private boolean enabled;
-    
-    /** The latest tag set */
-    private Tag latest;
-    
-    /** 
-     * The default store is a InMemory store.
-     **/
-    private ChangeLogStore store;
-    
-    /** A volatile flag used to avoid store switching when in use */
-    private volatile boolean storeInitialized = false;
-
-    /** A flag used to tell if the changeLog system is vivible by the clients */
-    private boolean exposed;
-
-    // default values for ChangeLogStorePartition containers
-    private static final String DEFAULT_PARTITION_SUFFIX = "ou=changelog";
-    private static final String DEFAULT_REV_CONTAINER_NAME = "ou=revisions";
-    private static final String DEFAULT_TAG_CONTAINER_NAME = "ou=tags";
-
-    // default values for ChangeLogStorePartition containers
-    private String partitionSuffix = DEFAULT_PARTITION_SUFFIX;
-    private String revContainerName = DEFAULT_REV_CONTAINER_NAME;
-    private String tagContainerName = DEFAULT_TAG_CONTAINER_NAME;
-
-    
-    /**
-     * {@inheritDoc}
-     */
-    public ChangeLogStore getChangeLogStore()
-    {
-        return store;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     * 
-     * If there is an existing changeLog store, we don't switch it 
-     */
-    public void setChangeLogStore( ChangeLogStore store )
-    {
-        if ( storeInitialized )
-        {
-            LOG.error(  "Cannot set a changeLog store when one is already active" );
-        }
-        else
-        {
-            this.store = store;
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public long getCurrentRevision() throws Exception
-    {
-        synchronized( store )
-        {
-            return store.getCurrentRevision();
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, LdifEntry reverse ) throws Exception
-    {
-        if ( !enabled )
-        {
-            throw new IllegalStateException( "The ChangeLog has not been enabled." );
-        }
-
-        return store.log( principal, forward, reverse );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, List<LdifEntry> reverses ) throws Exception
-    {
-        if ( !enabled )
-        {
-            throw new IllegalStateException( "The ChangeLog has not been enabled." );
-        }
-
-        return store.log( principal, forward, reverses );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isLogSearchSupported()
-    {
-        return store instanceof SearchableChangeLogStore;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isTagSearchSupported()
-    {
-        return store instanceof TaggableSearchableChangeLogStore;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isTagStorageSupported()
-    {
-        return store instanceof TaggableChangeLogStore;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ChangeLogSearchEngine getChangeLogSearchEngine()
-    {
-        if ( isLogSearchSupported() )
-        {
-            return ( ( SearchableChangeLogStore ) store ).getChangeLogSearchEngine();
-        }
-
-        throw new UnsupportedOperationException(
-            "The underlying changelog store does not support searching through it's logs" );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public TagSearchEngine getTagSearchEngine()
-    {
-        if ( isTagSearchSupported() )
-        {
-            return ( ( TaggableSearchableChangeLogStore ) store ).getTagSearchEngine();
-        }
-
-        throw new UnsupportedOperationException(
-            "The underlying changelog store does not support searching through it's tags" );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Tag tag( long revision, String description ) throws Exception
-    {
-        if ( revision < 0 )
-        {
-            throw new IllegalArgumentException( "revision must be greater than or equal to 0" );
-        }
-
-        if ( revision > store.getCurrentRevision() )
-        {
-            throw new IllegalArgumentException( "revision must be less than or equal to the current revision" );
-        }
-
-        if ( store instanceof TaggableChangeLogStore )
-        {
-            return latest = ( ( TaggableChangeLogStore ) store ).tag( revision );
-        }
-
-        return latest = new Tag( revision, description );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Tag tag( long revision ) throws Exception
-    {
-        return tag( revision, null );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Tag tag( String description ) throws Exception
-    {
-        return tag( store.getCurrentRevision(), description );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Tag tag() throws Exception
-    {
-        return tag( store.getCurrentRevision(), null );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setEnabled( boolean enabled )
-    {
-        this.enabled = enabled;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isEnabled()
-    {
-        return enabled;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Tag getLatest() throws Exception
-    {
-        if ( latest != null )
-        {
-            return latest;
-        }
-
-        if ( store instanceof TaggableChangeLogStore )
-        {
-            return latest = ( ( TaggableChangeLogStore ) store ).getLatest();
-        }
-
-        return null;
-    }
-
-
-    /**
-     * Initialize the ChangeLog system. We will initialize the associated store.
-     */
-    public void init( DirectoryService service ) throws Exception
-    {
-        if ( enabled )
-        {
-            if ( store == null )
-            {
-                // If no store has been defined, create an In Memory store
-                store = new MemoryChangeLogStore();
-            }
-            
-            store.init( service );
-
-            if ( exposed && isTagSearchSupported() )
-            {
-                TaggableSearchableChangeLogStore tmp = ( TaggableSearchableChangeLogStore ) store;
-                
-                tmp.createPartition( partitionSuffix, revContainerName, tagContainerName );
-                
-                Partition partition = tmp.getPartition();
-                partition.init( service );
-
-                service.addPartition( partition );
-            }
-        }
-        
-        // Flip the protection flag
-        storeInitialized = true;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sync() throws Exception
-    {
-        if ( enabled )
-        {
-            store.sync();
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void destroy() throws Exception
-    {
-        if ( enabled )
-        {
-            store.destroy();
-        }
-        
-        storeInitialized = false;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isExposed()
-    {
-        return exposed;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setExposed( boolean exposed )
-    {
-        this.exposed = exposed;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setPartitionSuffix( String suffix )
-    {
-        this.partitionSuffix = suffix;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setRevisionsContainerName( String revContainerName )
-    {
-        this.revContainerName = revContainerName;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setTagsContainerName( String tagContainerName )
-    {
-        this.tagContainerName = tagContainerName;
-    }
-
-    
-    /**
-     * @see Object#toString()
-     */
-    public String toString()
-    {
-        StringBuilder sb = new StringBuilder();
-        
-        sb.append( "ChangeLog tag[" ).append( latest ).append( "]\n" );
-        sb.append( "    store : \n" ).append( store );
-        
-        return sb.toString();
-    }
-}
+/*
+ * 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.changelog;
+
+
+import java.util.List;
+
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.server.core.partition.Partition;
+import org.apache.directory.shared.ldap.ldif.LdifEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * The default ChangeLog service implementation. It stores operations 
+ * in memory.
+ * 
+ * Entries are stored into a dedicated partition, named ou=changelog, under which
+ * we have two other sub-entries : ou=tags and ou= revisions :
+ * 
+ *  ou=changelog
+ *    |
+ *    +-- ou=revisions
+ *    |
+ *    +-- ou=tags
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DefaultChangeLog implements ChangeLog
+{
+    /** The class logger */
+    private static final Logger LOG = LoggerFactory.getLogger( DefaultChangeLog.class );
+
+    /** Tells if the service is activated or not */ 
+    private boolean enabled;
+    
+    /** The latest tag set */
+    private Tag latest;
+    
+    /** 
+     * The default store is a InMemory store.
+     **/
+    private ChangeLogStore store;
+    
+    /** A volatile flag used to avoid store switching when in use */
+    private volatile boolean storeInitialized = false;
+
+    /** A flag used to tell if the changeLog system is vivible by the clients */
+    private boolean exposed;
+
+    // default values for ChangeLogStorePartition containers
+    private static final String DEFAULT_PARTITION_SUFFIX = "ou=changelog";
+    private static final String DEFAULT_REV_CONTAINER_NAME = "ou=revisions";
+    private static final String DEFAULT_TAG_CONTAINER_NAME = "ou=tags";
+
+    // default values for ChangeLogStorePartition containers
+    private String partitionSuffix = DEFAULT_PARTITION_SUFFIX;
+    private String revContainerName = DEFAULT_REV_CONTAINER_NAME;
+    private String tagContainerName = DEFAULT_TAG_CONTAINER_NAME;
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public ChangeLogStore getChangeLogStore()
+    {
+        return store;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * If there is an existing changeLog store, we don't switch it 
+     */
+    public void setChangeLogStore( ChangeLogStore store )
+    {
+        if ( storeInitialized )
+        {
+            LOG.error(  "Cannot set a changeLog store when one is already active" );
+        }
+        else
+        {
+            this.store = store;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getCurrentRevision() throws Exception
+    {
+        synchronized( store )
+        {
+            return store.getCurrentRevision();
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, LdifEntry reverse ) throws Exception
+    {
+        if ( !enabled )
+        {
+            throw new IllegalStateException( "The ChangeLog has not been enabled." );
+        }
+
+        return store.log( principal, forward, reverse );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, List<LdifEntry> reverses ) throws Exception
+    {
+        if ( !enabled )
+        {
+            throw new IllegalStateException( "The ChangeLog has not been enabled." );
+        }
+
+        return store.log( principal, forward, reverses );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isLogSearchSupported()
+    {
+        return store instanceof SearchableChangeLogStore;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isTagSearchSupported()
+    {
+        return store instanceof TaggableSearchableChangeLogStore;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isTagStorageSupported()
+    {
+        return store instanceof TaggableChangeLogStore;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ChangeLogSearchEngine getChangeLogSearchEngine()
+    {
+        if ( isLogSearchSupported() )
+        {
+            return ( ( SearchableChangeLogStore ) store ).getChangeLogSearchEngine();
+        }
+
+        throw new UnsupportedOperationException(
+            "The underlying changelog store does not support searching through it's logs" );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public TagSearchEngine getTagSearchEngine()
+    {
+        if ( isTagSearchSupported() )
+        {
+            return ( ( TaggableSearchableChangeLogStore ) store ).getTagSearchEngine();
+        }
+
+        throw new UnsupportedOperationException(
+            "The underlying changelog store does not support searching through it's tags" );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Tag tag( long revision, String description ) throws Exception
+    {
+        if ( revision < 0 )
+        {
+            throw new IllegalArgumentException( "revision must be greater than or equal to 0" );
+        }
+
+        if ( revision > store.getCurrentRevision() )
+        {
+            throw new IllegalArgumentException( "revision must be less than or equal to the current revision" );
+        }
+
+        if ( store instanceof TaggableChangeLogStore )
+        {
+            return latest = ( ( TaggableChangeLogStore ) store ).tag( revision );
+        }
+
+        return latest = new Tag( revision, description );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Tag tag( long revision ) throws Exception
+    {
+        return tag( revision, null );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Tag tag( String description ) throws Exception
+    {
+        return tag( store.getCurrentRevision(), description );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Tag tag() throws Exception
+    {
+        return tag( store.getCurrentRevision(), null );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setEnabled( boolean enabled )
+    {
+        this.enabled = enabled;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isEnabled()
+    {
+        return enabled;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Tag getLatest() throws Exception
+    {
+        if ( latest != null )
+        {
+            return latest;
+        }
+
+        if ( store instanceof TaggableChangeLogStore )
+        {
+            return latest = ( ( TaggableChangeLogStore ) store ).getLatest();
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Initialize the ChangeLog system. We will initialize the associated store.
+     */
+    public void init( DirectoryService service ) throws Exception
+    {
+        if ( enabled )
+        {
+            if ( store == null )
+            {
+                // If no store has been defined, create an In Memory store
+                store = new MemoryChangeLogStore();
+            }
+            
+            store.init( service );
+
+            if ( exposed && isTagSearchSupported() )
+            {
+                TaggableSearchableChangeLogStore tmp = ( TaggableSearchableChangeLogStore ) store;
+                
+                tmp.createPartition( partitionSuffix, revContainerName, tagContainerName );
+                
+                Partition partition = tmp.getPartition();
+                partition.init( service );
+
+                service.addPartition( partition );
+            }
+        }
+        
+        // Flip the protection flag
+        storeInitialized = true;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void sync() throws Exception
+    {
+        if ( enabled )
+        {
+            store.sync();
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void destroy() throws Exception
+    {
+        if ( enabled )
+        {
+            store.destroy();
+        }
+        
+        storeInitialized = false;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isExposed()
+    {
+        return exposed;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setExposed( boolean exposed )
+    {
+        this.exposed = exposed;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setPartitionSuffix( String suffix )
+    {
+        this.partitionSuffix = suffix;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setRevisionsContainerName( String revContainerName )
+    {
+        this.revContainerName = revContainerName;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setTagsContainerName( String tagContainerName )
+    {
+        this.tagContainerName = tagContainerName;
+    }
+
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append( "ChangeLog tag[" ).append( latest ).append( "]\n" );
+        sb.append( "    store : \n" ).append( store );
+        
+        return sb.toString();
+    }
+}

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java?rev=801340&r1=801339&r2=801340&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java Wed Aug  5 17:55:15 2009
@@ -1,569 +1,569 @@
-/*
- * 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.changelog;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.directory.server.core.DirectoryService;
-import org.apache.directory.server.core.authn.LdapPrincipal;
-import org.apache.directory.shared.ldap.cursor.Cursor;
-import org.apache.directory.shared.ldap.cursor.ListCursor;
-import org.apache.directory.shared.ldap.ldif.LdifEntry;
-import org.apache.directory.shared.ldap.util.DateUtils;
-
-
-/**
- * A change log store that keeps it's information in memory.
- *
- * @org.apache.xbean.XBean
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- * TODO remove the NamingException
- */
-public class MemoryChangeLogStore implements TaggableChangeLogStore
-{
-    
-    private static final String REV_FILE = "revision";
-    private static final String TAG_FILE = "tags";
-    private static final String CHANGELOG_FILE = "changelog.dat";
-
-    /** An incremental number giving the current revision */
-    private long currentRevision;
-    
-    /** The latest tag */
-    private Tag latest;
-    
-    /** A Map of tags and revisions */
-    private final Map<Long,Tag> tags = new HashMap<Long,Tag>( 100 );
-    
-    private final List<ChangeLogEvent> events = new ArrayList<ChangeLogEvent>();
-    private File workingDirectory;
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Tag tag( long revision ) throws Exception
-    {
-        if ( tags.containsKey( revision ) )
-        {
-            return tags.get( revision );
-        }
-
-        latest = new Tag( revision, null );
-        tags.put( revision, latest );
-        return latest;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Tag tag() throws Exception
-    {
-        if ( ( latest != null) && ( latest.getRevision() == currentRevision ) )
-        {
-            return latest;
-        }
-
-        latest = new Tag( currentRevision, null );
-        tags.put( currentRevision, latest );
-        return latest;
-    }
-
-
-    public Tag tag( String description ) throws Exception
-    {
-        if ( ( latest != null ) && ( latest.getRevision() == currentRevision ) )
-        {
-            return latest;
-        }
-
-        latest = new Tag( currentRevision, description );
-        tags.put( currentRevision, latest );
-        return latest;
-    }
-
-
-    public void init( DirectoryService service ) throws Exception
-    {
-        workingDirectory = service.getWorkingDirectory();
-        loadRevision();
-        loadTags();
-        loadChangeLog();
-    }
-
-
-    private void loadRevision() throws Exception
-    {
-        File revFile = new File( workingDirectory, REV_FILE );
-        
-        if ( revFile.exists() )
-        {
-            BufferedReader reader = null;
-            
-            try
-            {
-                reader = new BufferedReader( new FileReader( revFile ) );
-                String line = reader.readLine();
-                currentRevision = Long.valueOf( line );
-            }
-            catch ( IOException e )
-            {
-                throw e;
-            }
-            finally
-            {
-                if ( reader != null )
-                {
-                    //noinspection EmptyCatchBlock
-                    try
-                    {
-                        reader.close();
-                    }
-                    catch ( IOException e )
-                    {
-                    }
-                }
-            }
-        }
-    }
-
-
-    private void saveRevision() throws Exception
-    {
-        File revFile = new File( workingDirectory, REV_FILE );
-        
-        if ( revFile.exists() )
-        {
-            revFile.delete();
-        }
-
-        PrintWriter out = null;
-        
-        try
-        {
-            out = new PrintWriter( new FileWriter( revFile ) );
-            out.println( currentRevision );
-            out.flush();
-        }
-        catch ( IOException e )
-        {
-            throw e;
-        }
-        finally
-        {
-            if ( out != null )
-            {
-                out.close();
-            }
-        }
-    }
-
-
-    private void saveTags() throws Exception
-    {
-        File tagFile = new File( workingDirectory, TAG_FILE );
-        
-        if ( tagFile.exists() )
-        {
-            tagFile.delete();
-        }
-
-        FileOutputStream out = null;
-        
-        try
-        {
-            out = new FileOutputStream( tagFile );
-
-            Properties props = new Properties();
-            
-            for ( Tag tag : tags.values() )
-            {
-                String key = String.valueOf( tag.getRevision() );
-                
-                if ( tag.getDescription() == null )
-                {
-                    props.setProperty( key, "null" );
-                }
-                else
-                {
-                    props.setProperty( key, tag.getDescription() );
-                }
-            }
-
-            props.store( out, null );
-            out.flush();
-        }
-        catch ( IOException e )
-        {
-            throw e;
-        }
-        finally
-        {
-            if ( out != null )
-            {
-                //noinspection EmptyCatchBlock
-                try
-                {
-                    out.close();
-                }
-                catch ( IOException e )
-                {
-                }
-            }
-        }
-    }
-
-
-    private void loadTags() throws Exception
-    {
-        File revFile = new File( workingDirectory, REV_FILE );
-        
-        if ( revFile.exists() )
-        {
-            Properties props = new Properties();
-            FileInputStream in = null;
-            
-            try
-            {
-                in = new FileInputStream( revFile );
-                props.load( in );
-                ArrayList<Long> revList = new ArrayList<Long>();
-                
-                for ( Object key : props.keySet() )
-                {
-                    revList.add( Long.valueOf( ( String ) key ) );
-                }
-
-                Collections.sort( revList );
-                Tag tag = null;
-
-                // @todo need some serious syncrhoization here on tags
-                tags.clear();
-                
-                for ( Long lkey : revList )
-                {
-                    String rev = String.valueOf( lkey );
-                    String desc = props.getProperty( rev );
-
-                    if ( desc != null && desc.equals( "null" ) )
-                    {
-                        tag = new Tag( lkey, null );
-                    }
-                    else
-                    {
-                        tag = new Tag( lkey, desc );
-                    }
-
-                    tags.put( lkey, tag );
-                }
-
-                latest = tag;
-            }
-            catch ( IOException e )
-            {
-                throw e;
-            }
-            finally
-            {
-                if ( in != null )
-                {
-                    //noinspection EmptyCatchBlock
-                    try
-                    {
-                        in.close();
-                    }
-                    catch ( IOException e )
-                    {
-                    }
-                }
-            }
-        }
-    }
-
-
-    private void loadChangeLog() throws Exception
-    {
-        File file = new File( workingDirectory, CHANGELOG_FILE );
-        
-        if ( file.exists() )
-        {
-            ObjectInputStream in = null;
-
-            try
-            {
-                in = new ObjectInputStream( new FileInputStream( file ) );
-                int size = in.readInt();
-                
-                ArrayList<ChangeLogEvent> changeLogEvents = new ArrayList<ChangeLogEvent>( size );
-
-                for ( int i = 0; i < size; i++ )
-                {
-                    ChangeLogEvent event = ( ChangeLogEvent ) in.readObject();
-                    changeLogEvents.add( event );
-                }
-
-                // @todo man o man we need some synchronization later after getting this to work
-                this.events.clear();
-                this.events.addAll( changeLogEvents );
-            }
-            catch ( Exception e )
-            {
-                throw e;
-            }
-            finally
-            {
-                if ( in != null )
-                {
-                    //noinspection EmptyCatchBlock
-                    try
-                    {
-                        in.close();
-                    }
-                    catch ( IOException e )
-                    {
-                    }
-                }
-            }
-        }
-    }
-
-
-    private void saveChangeLog() throws Exception
-    {
-        File file = new File( workingDirectory, CHANGELOG_FILE );
-        
-        if ( file.exists() )
-        {
-            file.delete();
-        }
-
-        try
-        {
-            file.createNewFile();
-        }
-        catch ( IOException e )
-        {
-            throw e;
-        }
-
-        ObjectOutputStream out = null;
-
-        try
-        {
-            out = new ObjectOutputStream( new FileOutputStream( file ) );
-
-            out.writeInt( events.size() );
-            
-            for ( ChangeLogEvent event : events )
-            {
-                out.writeObject( event );
-            }
-
-            out.flush();
-        }
-        catch ( Exception e )
-        {
-            throw e;
-        }
-        finally
-        {
-            if ( out != null )
-            {
-                //noinspection EmptyCatchBlock
-                try
-                {
-                    out.close();
-                }
-                catch ( IOException e )
-                {
-                }
-            }
-        }
-    }
-
-
-    public void sync() throws Exception
-    {
-        saveRevision();
-        saveTags();
-        saveChangeLog();
-    }
-
-
-    /**
-     * Save logs, tags and revision on disk, and clean everything in memory
-     */
-    public void destroy() throws Exception
-    {
-        saveRevision();
-        saveTags();
-        saveChangeLog();
-    }
-
-
-    public long getCurrentRevision()
-    {
-        return currentRevision;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, LdifEntry reverse ) throws Exception
-    {
-        currentRevision++;
-        ChangeLogEvent event = new ChangeLogEvent( currentRevision, DateUtils.getGeneralizedTime(), 
-                principal, forward, reverse );
-        events.add( event );
-        return event;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, List<LdifEntry> reverses ) throws Exception
-    {
-        currentRevision++;
-        ChangeLogEvent event = new ChangeLogEvent( currentRevision, DateUtils.getGeneralizedTime(), 
-                principal, forward, reverses );
-        events.add( event );
-        return event;
-    }
-
-
-    public ChangeLogEvent lookup( long revision ) throws Exception
-    {
-        if ( revision < 0 )
-        {
-            throw new IllegalArgumentException( "revision must be greater than or equal to 0" );
-        }
-
-        if ( revision > getCurrentRevision() )
-        {
-            throw new IllegalArgumentException( "The revision must not be greater than the current revision" );
-        }
-
-        return events.get( ( int ) revision );
-    }
-
-
-    public Cursor<ChangeLogEvent> find() throws Exception
-    {
-        return new ListCursor<ChangeLogEvent>( events );
-    }
-
-
-    public Cursor<ChangeLogEvent> findBefore( long revision ) throws Exception
-    {
-        return new ListCursor<ChangeLogEvent>( events, ( int ) revision );
-    }
-
-
-    public Cursor<ChangeLogEvent> findAfter( long revision ) throws Exception
-    {
-        return new ListCursor<ChangeLogEvent>( ( int ) revision, events );
-    }
-
-
-    public Cursor<ChangeLogEvent> find( long startRevision, long endRevision ) throws Exception
-    {
-        return new ListCursor<ChangeLogEvent>( ( int ) startRevision, events, ( int ) ( endRevision + 1 ) );
-    }
-
-
-    public Tag getLatest() throws Exception
-    {
-        return latest;
-    }
-
-
-    /**
-     * @see TaggableChangeLogStore#removeTag(long)
-     */
-    public Tag removeTag( long revision ) throws Exception
-    {
-        return tags.remove( revision );
-    }
-
-
-    /**
-     * @see TaggableChangeLogStore#tag(long, String)
-     */
-    public Tag tag( long revision, String descrition ) throws Exception
-    {
-        if ( tags.containsKey( revision ) )
-        {
-            return tags.get( revision );
-        }
-
-        latest = new Tag( revision, descrition );
-        tags.put( revision, latest );
-        return latest;
-    }
-    
-    
-    /**
-     * @see Object#toString()
-     */
-    public String toString()
-    {
-        StringBuilder sb = new StringBuilder();
-        
-        sb.append( "MemoryChangeLog\n" );
-        sb.append( "latest tag : " ).append( latest ).append( '\n' );
-        
-        if ( events != null )
-        {
-            sb.append( "Nb of events : " ).append( events.size() ).append( '\n' );
-            
-            int i = 0;
-            
-            for ( ChangeLogEvent event:events )
-            {
-                sb.append( "event[" ).append( i++ ).append( "] : " );
-                sb.append( "\n---------------------------------------\n" );
-                sb.append( event );
-                sb.append( "\n---------------------------------------\n" );
-            }
-        }
-        
-        
-        return sb.toString();
-    }
-}
+/*
+ * 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.changelog;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.shared.ldap.cursor.Cursor;
+import org.apache.directory.shared.ldap.cursor.ListCursor;
+import org.apache.directory.shared.ldap.ldif.LdifEntry;
+import org.apache.directory.shared.ldap.util.DateUtils;
+
+
+/**
+ * A change log store that keeps it's information in memory.
+ *
+ * @org.apache.xbean.XBean
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ * TODO remove the NamingException
+ */
+public class MemoryChangeLogStore implements TaggableChangeLogStore
+{
+    
+    private static final String REV_FILE = "revision";
+    private static final String TAG_FILE = "tags";
+    private static final String CHANGELOG_FILE = "changelog.dat";
+
+    /** An incremental number giving the current revision */
+    private long currentRevision;
+    
+    /** The latest tag */
+    private Tag latest;
+    
+    /** A Map of tags and revisions */
+    private final Map<Long,Tag> tags = new HashMap<Long,Tag>( 100 );
+    
+    private final List<ChangeLogEvent> events = new ArrayList<ChangeLogEvent>();
+    private File workingDirectory;
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Tag tag( long revision ) throws Exception
+    {
+        if ( tags.containsKey( revision ) )
+        {
+            return tags.get( revision );
+        }
+
+        latest = new Tag( revision, null );
+        tags.put( revision, latest );
+        return latest;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Tag tag() throws Exception
+    {
+        if ( ( latest != null) && ( latest.getRevision() == currentRevision ) )
+        {
+            return latest;
+        }
+
+        latest = new Tag( currentRevision, null );
+        tags.put( currentRevision, latest );
+        return latest;
+    }
+
+
+    public Tag tag( String description ) throws Exception
+    {
+        if ( ( latest != null ) && ( latest.getRevision() == currentRevision ) )
+        {
+            return latest;
+        }
+
+        latest = new Tag( currentRevision, description );
+        tags.put( currentRevision, latest );
+        return latest;
+    }
+
+
+    public void init( DirectoryService service ) throws Exception
+    {
+        workingDirectory = service.getWorkingDirectory();
+        loadRevision();
+        loadTags();
+        loadChangeLog();
+    }
+
+
+    private void loadRevision() throws Exception
+    {
+        File revFile = new File( workingDirectory, REV_FILE );
+        
+        if ( revFile.exists() )
+        {
+            BufferedReader reader = null;
+            
+            try
+            {
+                reader = new BufferedReader( new FileReader( revFile ) );
+                String line = reader.readLine();
+                currentRevision = Long.valueOf( line );
+            }
+            catch ( IOException e )
+            {
+                throw e;
+            }
+            finally
+            {
+                if ( reader != null )
+                {
+                    //noinspection EmptyCatchBlock
+                    try
+                    {
+                        reader.close();
+                    }
+                    catch ( IOException e )
+                    {
+                    }
+                }
+            }
+        }
+    }
+
+
+    private void saveRevision() throws Exception
+    {
+        File revFile = new File( workingDirectory, REV_FILE );
+        
+        if ( revFile.exists() )
+        {
+            revFile.delete();
+        }
+
+        PrintWriter out = null;
+        
+        try
+        {
+            out = new PrintWriter( new FileWriter( revFile ) );
+            out.println( currentRevision );
+            out.flush();
+        }
+        catch ( IOException e )
+        {
+            throw e;
+        }
+        finally
+        {
+            if ( out != null )
+            {
+                out.close();
+            }
+        }
+    }
+
+
+    private void saveTags() throws Exception
+    {
+        File tagFile = new File( workingDirectory, TAG_FILE );
+        
+        if ( tagFile.exists() )
+        {
+            tagFile.delete();
+        }
+
+        FileOutputStream out = null;
+        
+        try
+        {
+            out = new FileOutputStream( tagFile );
+
+            Properties props = new Properties();
+            
+            for ( Tag tag : tags.values() )
+            {
+                String key = String.valueOf( tag.getRevision() );
+                
+                if ( tag.getDescription() == null )
+                {
+                    props.setProperty( key, "null" );
+                }
+                else
+                {
+                    props.setProperty( key, tag.getDescription() );
+                }
+            }
+
+            props.store( out, null );
+            out.flush();
+        }
+        catch ( IOException e )
+        {
+            throw e;
+        }
+        finally
+        {
+            if ( out != null )
+            {
+                //noinspection EmptyCatchBlock
+                try
+                {
+                    out.close();
+                }
+                catch ( IOException e )
+                {
+                }
+            }
+        }
+    }
+
+
+    private void loadTags() throws Exception
+    {
+        File revFile = new File( workingDirectory, REV_FILE );
+        
+        if ( revFile.exists() )
+        {
+            Properties props = new Properties();
+            FileInputStream in = null;
+            
+            try
+            {
+                in = new FileInputStream( revFile );
+                props.load( in );
+                ArrayList<Long> revList = new ArrayList<Long>();
+                
+                for ( Object key : props.keySet() )
+                {
+                    revList.add( Long.valueOf( ( String ) key ) );
+                }
+
+                Collections.sort( revList );
+                Tag tag = null;
+
+                // @todo need some serious syncrhoization here on tags
+                tags.clear();
+                
+                for ( Long lkey : revList )
+                {
+                    String rev = String.valueOf( lkey );
+                    String desc = props.getProperty( rev );
+
+                    if ( desc != null && desc.equals( "null" ) )
+                    {
+                        tag = new Tag( lkey, null );
+                    }
+                    else
+                    {
+                        tag = new Tag( lkey, desc );
+                    }
+
+                    tags.put( lkey, tag );
+                }
+
+                latest = tag;
+            }
+            catch ( IOException e )
+            {
+                throw e;
+            }
+            finally
+            {
+                if ( in != null )
+                {
+                    //noinspection EmptyCatchBlock
+                    try
+                    {
+                        in.close();
+                    }
+                    catch ( IOException e )
+                    {
+                    }
+                }
+            }
+        }
+    }
+
+
+    private void loadChangeLog() throws Exception
+    {
+        File file = new File( workingDirectory, CHANGELOG_FILE );
+        
+        if ( file.exists() )
+        {
+            ObjectInputStream in = null;
+
+            try
+            {
+                in = new ObjectInputStream( new FileInputStream( file ) );
+                int size = in.readInt();
+                
+                ArrayList<ChangeLogEvent> changeLogEvents = new ArrayList<ChangeLogEvent>( size );
+
+                for ( int i = 0; i < size; i++ )
+                {
+                    ChangeLogEvent event = ( ChangeLogEvent ) in.readObject();
+                    changeLogEvents.add( event );
+                }
+
+                // @todo man o man we need some synchronization later after getting this to work
+                this.events.clear();
+                this.events.addAll( changeLogEvents );
+            }
+            catch ( Exception e )
+            {
+                throw e;
+            }
+            finally
+            {
+                if ( in != null )
+                {
+                    //noinspection EmptyCatchBlock
+                    try
+                    {
+                        in.close();
+                    }
+                    catch ( IOException e )
+                    {
+                    }
+                }
+            }
+        }
+    }
+
+
+    private void saveChangeLog() throws Exception
+    {
+        File file = new File( workingDirectory, CHANGELOG_FILE );
+        
+        if ( file.exists() )
+        {
+            file.delete();
+        }
+
+        try
+        {
+            file.createNewFile();
+        }
+        catch ( IOException e )
+        {
+            throw e;
+        }
+
+        ObjectOutputStream out = null;
+
+        try
+        {
+            out = new ObjectOutputStream( new FileOutputStream( file ) );
+
+            out.writeInt( events.size() );
+            
+            for ( ChangeLogEvent event : events )
+            {
+                out.writeObject( event );
+            }
+
+            out.flush();
+        }
+        catch ( Exception e )
+        {
+            throw e;
+        }
+        finally
+        {
+            if ( out != null )
+            {
+                //noinspection EmptyCatchBlock
+                try
+                {
+                    out.close();
+                }
+                catch ( IOException e )
+                {
+                }
+            }
+        }
+    }
+
+
+    public void sync() throws Exception
+    {
+        saveRevision();
+        saveTags();
+        saveChangeLog();
+    }
+
+
+    /**
+     * Save logs, tags and revision on disk, and clean everything in memory
+     */
+    public void destroy() throws Exception
+    {
+        saveRevision();
+        saveTags();
+        saveChangeLog();
+    }
+
+
+    public long getCurrentRevision()
+    {
+        return currentRevision;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, LdifEntry reverse ) throws Exception
+    {
+        currentRevision++;
+        ChangeLogEvent event = new ChangeLogEvent( currentRevision, DateUtils.getGeneralizedTime(), 
+                principal, forward, reverse );
+        events.add( event );
+        return event;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ChangeLogEvent log( LdapPrincipal principal, LdifEntry forward, List<LdifEntry> reverses ) throws Exception
+    {
+        currentRevision++;
+        ChangeLogEvent event = new ChangeLogEvent( currentRevision, DateUtils.getGeneralizedTime(), 
+                principal, forward, reverses );
+        events.add( event );
+        return event;
+    }
+
+
+    public ChangeLogEvent lookup( long revision ) throws Exception
+    {
+        if ( revision < 0 )
+        {
+            throw new IllegalArgumentException( "revision must be greater than or equal to 0" );
+        }
+
+        if ( revision > getCurrentRevision() )
+        {
+            throw new IllegalArgumentException( "The revision must not be greater than the current revision" );
+        }
+
+        return events.get( ( int ) revision );
+    }
+
+
+    public Cursor<ChangeLogEvent> find() throws Exception
+    {
+        return new ListCursor<ChangeLogEvent>( events );
+    }
+
+
+    public Cursor<ChangeLogEvent> findBefore( long revision ) throws Exception
+    {
+        return new ListCursor<ChangeLogEvent>( events, ( int ) revision );
+    }
+
+
+    public Cursor<ChangeLogEvent> findAfter( long revision ) throws Exception
+    {
+        return new ListCursor<ChangeLogEvent>( ( int ) revision, events );
+    }
+
+
+    public Cursor<ChangeLogEvent> find( long startRevision, long endRevision ) throws Exception
+    {
+        return new ListCursor<ChangeLogEvent>( ( int ) startRevision, events, ( int ) ( endRevision + 1 ) );
+    }
+
+
+    public Tag getLatest() throws Exception
+    {
+        return latest;
+    }
+
+
+    /**
+     * @see TaggableChangeLogStore#removeTag(long)
+     */
+    public Tag removeTag( long revision ) throws Exception
+    {
+        return tags.remove( revision );
+    }
+
+
+    /**
+     * @see TaggableChangeLogStore#tag(long, String)
+     */
+    public Tag tag( long revision, String descrition ) throws Exception
+    {
+        if ( tags.containsKey( revision ) )
+        {
+            return tags.get( revision );
+        }
+
+        latest = new Tag( revision, descrition );
+        tags.put( revision, latest );
+        return latest;
+    }
+    
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append( "MemoryChangeLog\n" );
+        sb.append( "latest tag : " ).append( latest ).append( '\n' );
+        
+        if ( events != null )
+        {
+            sb.append( "Nb of events : " ).append( events.size() ).append( '\n' );
+            
+            int i = 0;
+            
+            for ( ChangeLogEvent event:events )
+            {
+                sb.append( "event[" ).append( i++ ).append( "] : " );
+                sb.append( "\n---------------------------------------\n" );
+                sb.append( event );
+                sb.append( "\n---------------------------------------\n" );
+            }
+        }
+        
+        
+        return sb.toString();
+    }
+}