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();
+ }
+}