You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2020/07/05 11:41:42 UTC

svn commit: r1879521 [14/37] - in /river/jtsk/modules/modularize/apache-river: ./ browser/ browser/src/main/java/org/apache/river/example/browser/ extra/ groovy-config/ river-activation/ river-collections/ river-collections/src/main/java/org/apache/riv...

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java Sun Jul  5 11:41:39 2020
@@ -1,56 +1,56 @@
-/*
- * 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.river.mahalo;
-
-import org.apache.river.start.LifeCycle;
-
-/**
- * Convenience class intended for use with the
- * {@link org.apache.river.start.ServiceStarter} framework to start
- * an implementation of Mahalo that is not activatable, but which
- * will log its state information to persistent storage.
- *
- * @author Sun Microsystems, Inc.
- * @since 2.0
- */
-class NonActivatableMahaloImpl extends TxnManagerImpl {
-
-    /**
-     * Constructs a new instance of <code>TxnManagerImpl</code> that is not
-     * activatable, but which will persist its state.
-     *
-     * @param configArgs <code>String</code> array whose elements are
-     *                   the arguments to use when creating the server.
-     * @param lifeCycle  instance of <code>LifeCycle</code> that, if 
-     *                   non-<code>null</code>, will cause this object's
-     *                   <code>unregister</code> method to be invoked during
-     *                   shutdown to notify the service starter framework that
-     *                   the reference to this service's implementation can be
-     *                   'released' for garbage collection. A value of 
-     *                   <code>null</code> for this argument is allowed.
-     *
-     * @throws Exception If there was a problem initializing the service.
-     */
-    NonActivatableMahaloImpl(String[] configArgs, LifeCycle lifeCycle)
-        throws Exception
-    {
-        super(configArgs, lifeCycle, true);//true ==> persistent
-    }//end constructor
-
-}//end class NonActivatableMahaloImpl
-
+/*
+ * 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.river.mahalo;
+
+import org.apache.river.start.lifecycle.LifeCycle;
+
+/**
+ * Convenience class intended for use with the
+ * {@link org.apache.river.start.ServiceStarter} framework to start
+ * an implementation of Mahalo that is not activatable, but which
+ * will log its state information to persistent storage.
+ *
+ * @author Sun Microsystems, Inc.
+ * @since 2.0
+ */
+class NonActivatableMahaloImpl extends TxnManagerImpl {
+
+    /**
+     * Constructs a new instance of <code>TxnManagerImpl</code> that is not
+     * activatable, but which will persist its state.
+     *
+     * @param configArgs <code>String</code> array whose elements are
+     *                   the arguments to use when creating the server.
+     * @param lifeCycle  instance of <code>LifeCycle</code> that, if 
+     *                   non-<code>null</code>, will cause this object's
+     *                   <code>unregister</code> method to be invoked during
+     *                   shutdown to notify the service starter framework that
+     *                   the reference to this service's implementation can be
+     *                   'released' for garbage collection. A value of 
+     *                   <code>null</code> for this argument is allowed.
+     *
+     * @throws Exception If there was a problem initializing the service.
+     */
+    NonActivatableMahaloImpl(String[] configArgs, LifeCycle lifeCycle)
+        throws Exception
+    {
+        super(configArgs, lifeCycle, true);//true ==> persistent
+    }//end constructor
+
+}//end class NonActivatableMahaloImpl
+

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java Sun Jul  5 11:41:39 2020
@@ -17,8 +17,8 @@
  */
 package org.apache.river.mahalo;
 
-import org.apache.river.thread.RetryTask;
-import org.apache.river.thread.WakeupManager;
+import org.apache.river.thread.wakeup.RetryTask;
+import org.apache.river.thread.wakeup.WakeupManager;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.logging.Level;

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java Sun Jul  5 11:41:39 2020
@@ -20,7 +20,7 @@ package org.apache.river.mahalo;
 import org.apache.river.logging.Levels;
 import org.apache.river.mahalo.log.ClientLog;
 import org.apache.river.thread.TaskManager;
-import org.apache.river.thread.WakeupManager;
+import org.apache.river.thread.wakeup.WakeupManager;
 import java.rmi.RemoteException;
 import java.util.concurrent.ExecutorService;
 import java.util.logging.Level;

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java Sun Jul  5 11:41:39 2020
@@ -19,7 +19,7 @@
 package org.apache.river.mahalo;
 
 import org.apache.river.mahalo.log.ClientLog;
-import org.apache.river.thread.WakeupManager;
+import org.apache.river.thread.wakeup.WakeupManager;
 import java.rmi.RemoteException;
 import java.util.Iterator;
 import java.util.concurrent.ExecutorService;

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java Sun Jul  5 11:41:39 2020
@@ -18,8 +18,8 @@
 package org.apache.river.mahalo;
 
 import org.apache.river.logging.Levels;
-import org.apache.river.thread.RetryTask;
-import org.apache.river.thread.WakeupManager;
+import org.apache.river.thread.wakeup.RetryTask;
+import org.apache.river.thread.wakeup.WakeupManager;
 import java.rmi.NoSuchObjectException;
 import java.rmi.RemoteException;
 import java.util.concurrent.ExecutorService;

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java Sun Jul  5 11:41:39 2020
@@ -1,56 +1,56 @@
-/*
- * 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.river.mahalo;
-
-import org.apache.river.start.LifeCycle;
-
-/**
- * Convenience class intended for use with the
- * {@link org.apache.river.start.ServiceStarter} framework to start
- * a <i>transient</i> (non-activatable, non-persistent) implementation
- * of Mahalo.
- *
- * @author Sun Microsystems, Inc.
- * @since 2.0
- */
-class TransientMahaloImpl extends TxnManagerImpl {
-
-    /**
-     * Constructs a new instance of <code>TxnManagerImpl</code> that is not
-     * activatable, and which will not persist its state.
-     *
-     * @param configArgs <code>String</code> array whose elements are
-     *                   the arguments to use when creating the server.
-     * @param lifeCycle  instance of <code>LifeCycle</code> that, if 
-     *                   non-<code>null</code>, will cause this object's
-     *                   <code>unregister</code> method to be invoked during
-     *                   shutdown to notify the service starter framework that
-     *                   the reference to this service's implementation can be
-     *                   'released' for garbage collection. A value of 
-     *                   <code>null</code> for this argument is allowed.
-     *
-     * @throws Exception If there was a problem initializing the service.
-     */
-    TransientMahaloImpl(String[] configArgs, LifeCycle lifeCycle)
-        throws Exception
-    {
-        super(configArgs, lifeCycle, false);//false ==> not persistent
-    }//end constructor
-
-}//end class TransientMahaloImpl
-
+/*
+ * 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.river.mahalo;
+
+import org.apache.river.start.lifecycle.LifeCycle;
+
+/**
+ * Convenience class intended for use with the
+ * {@link org.apache.river.start.ServiceStarter} framework to start
+ * a <i>transient</i> (non-activatable, non-persistent) implementation
+ * of Mahalo.
+ *
+ * @author Sun Microsystems, Inc.
+ * @since 2.0
+ */
+class TransientMahaloImpl extends TxnManagerImpl {
+
+    /**
+     * Constructs a new instance of <code>TxnManagerImpl</code> that is not
+     * activatable, and which will not persist its state.
+     *
+     * @param configArgs <code>String</code> array whose elements are
+     *                   the arguments to use when creating the server.
+     * @param lifeCycle  instance of <code>LifeCycle</code> that, if 
+     *                   non-<code>null</code>, will cause this object's
+     *                   <code>unregister</code> method to be invoked during
+     *                   shutdown to notify the service starter framework that
+     *                   the reference to this service's implementation can be
+     *                   'released' for garbage collection. A value of 
+     *                   <code>null</code> for this argument is allowed.
+     *
+     * @throws Exception If there was a problem initializing the service.
+     */
+    TransientMahaloImpl(String[] configArgs, LifeCycle lifeCycle)
+        throws Exception
+    {
+        super(configArgs, lifeCycle, false);//false ==> not persistent
+    }//end constructor
+
+}//end class TransientMahaloImpl
+

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java Sun Jul  5 11:41:39 2020
@@ -31,11 +31,11 @@ import org.apache.river.mahalo.log.LogRe
 import org.apache.river.mahalo.log.LogRecovery;
 import org.apache.river.mahalo.log.MultiLogManager;
 import org.apache.river.mahalo.log.MultiLogManagerAdmin;
-import org.apache.river.start.LifeCycle;
+import org.apache.river.start.lifecycle.LifeCycle;
 import org.apache.river.api.util.Startable;
 import org.apache.river.thread.InterruptedStatusThread;
 import org.apache.river.thread.ReadyState;
-import org.apache.river.thread.WakeupManager;
+import org.apache.river.thread.wakeup.WakeupManager;
 
 import java.io.File;
 import java.io.IOException;
@@ -100,6 +100,11 @@ import net.jini.security.TrustVerifier;
 import org.apache.river.thread.ExtensibleExecutorService;
 import org.apache.river.thread.ExtensibleExecutorService.RunnableFutureFactory;
 
+import org.apache.river.mahalo.proxy.TxnManager;
+import org.apache.river.mahalo.proxy.TxnMgrProxy;
+import org.apache.river.mahalo.proxy.TxnMgrAdminProxy;
+import org.apache.river.mahalo.proxy.ProxyVerifier;
+
 /**
  * An implementation of the Jini Transaction Specification.
  *

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java Sun Jul  5 11:41:39 2020
@@ -22,7 +22,7 @@ import org.apache.river.constants.TimeCo
 import org.apache.river.landlord.FixedLeasePeriodPolicy;
 import org.apache.river.landlord.LeasePeriodPolicy;
 import org.apache.river.thread.InterruptedStatusThread;
-import org.apache.river.thread.WakeupManager;
+import org.apache.river.thread.wakeup.WakeupManager;
 import java.io.IOException;
 import java.rmi.RemoteException;
 import java.rmi.activation.ActivationException;
@@ -52,6 +52,8 @@ import net.jini.jeri.tcp.TcpServerEndpoi
 import net.jini.security.BasicProxyPreparer;
 import net.jini.security.ProxyPreparer;
 import org.apache.river.thread.NamedThreadFactory;
+import org.apache.river.mahalo.proxy.TxnManager;
+
 
 /**
  *

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java Sun Jul  5 11:41:39 2020
@@ -25,7 +25,7 @@ import org.apache.river.logging.Levels;
 import org.apache.river.mahalo.log.ClientLog;
 import org.apache.river.mahalo.log.LogException;
 import org.apache.river.mahalo.log.LogManager;
-import org.apache.river.thread.WakeupManager;
+import org.apache.river.thread.wakeup.WakeupManager;
 import java.rmi.RemoteException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -50,6 +50,7 @@ import net.jini.core.transaction.server.
 import net.jini.core.transaction.server.TransactionParticipant;
 import net.jini.id.Uuid;
 import net.jini.security.ProxyPreparer;
+import org.apache.river.mahalo.proxy.InternalManagerException;
 
 /**
  * TxnManagerTransaction is a class which

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java Sun Jul  5 11:41:39 2020
@@ -1,386 +1,386 @@
-/*
- * 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.river.mahalo.log;
-
-import org.apache.river.logging.Levels;
-import org.apache.river.mahalo.TxnManager;
-import org.apache.river.system.FileSystem;
-import java.io.File;
-import java.io.FilenameFilter;
-
-import net.jini.admin.Administrable;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author Sun Microsystems, Inc.
- *
- */
-public class MultiLogManager
-        implements LogManager, FileModes, Administrable, MultiLogManagerAdmin {
-    private static final String LOG_FILE = "Log.";
-
-    /** Logger for persistence related messages */
-    private static final Logger persistenceLogger = 
-        Logger.getLogger(TxnManager.MAHALO + ".persistence");
-
-    /** Logger for operations related messages */
-    private static final Logger operationsLogger = 
-        Logger.getLogger(TxnManager.MAHALO + ".operations");
-
-    /** Logger for initialization related messages */
-    private static final Logger initLogger = 
-        Logger.getLogger(TxnManager.MAHALO + ".init");
-
-    /** Client called during log recovery to process log objects */
-    private final LogRecovery client;
-
-    /** Map of log files keyed by their associated cookie */
-    private final Map logByID = new HashMap();
-    
-    /** Lock object used for coordinating access to logByID */
-    private final Object logByIDLock = new Object();
-    
-    /** Flag that is set to true upon destruction */
-    private boolean destroyed = false;
-    
-    /** Persistence directory */
-    private String directory = null;
-    
-    private final static FilenameFilter filter =
-        new FilenameFilter() {
-            public boolean accept(File dir, String name) {
-                if (operationsLogger.isLoggable(Level.FINER)) {
-                    operationsLogger.entering(FilenameFilter.class.getName(), 
-		        "accept", new Object[] {dir, name});
-		}
-                final boolean isLog = name.startsWith(LOG_FILE);
-                if (operationsLogger.isLoggable(Level.FINER)) {
-                    operationsLogger.exiting(FilenameFilter.class.getName(), 
-		        "accept", Boolean.valueOf(isLog));
-		}
-                return isLog;
-            };
-        };
-
-    /**
-     * Callback interface for log files to remove themselves from 
-     * this manager 
-     */ 
-    public static interface LogRemovalManager {
-        public void release(long cookie);
-    }
-    
-    /**
-     * Capability object passed to log files, which is called back upon
-     * log removal. 
-     */ 
-    final LogRemovalManager logMgrRef = new LogRemovalManager() {
-        public void release(long cookie) {
-	    MultiLogManager.this.release(cookie);
-	}
-    };
-    
-    /**
-     * Create a non-persistent <code>MultiLogManager</code>.
-     */
-    public MultiLogManager() {
-        directory = null; // just for insurance
-        client = null; 
-    }
-	    
-    /**
-     * Create a <code>MultiLogManager</code>.
-     *
-     * @param client who to inform during recovery.
-     *
-     * @param path where to store logging information.
-     */
-    public MultiLogManager(LogRecovery client, String path) {
-	if (path == null)
-	    throw new IllegalArgumentException("MultiLogManager: must use " +
-						"non-null path");
-	if (client == null)
-	    throw new IllegalArgumentException("MultiLogManager: must use " +
-						"non-null recovery client");
-        this.client = client;
-	directory = path; 
-
-	if (!directory.endsWith(File.separator))
-	    directory = directory.concat(File.separator);
-
-	if (persistenceLogger.isLoggable(Level.FINEST)) {
-            persistenceLogger.log(Level.FINEST,
-	    "directory = {0}", directory);
-	}
-
-        File tmpfile = new File(directory);
- 
-        //If you attempt to access the Version file and
-        //it does not exist, start with zero.
-         try {
-            if (!tmpfile.exists())
-                if (!tmpfile.mkdirs())
- 	            if (persistenceLogger.isLoggable(Level.SEVERE)) {
-                        persistenceLogger.log(Level.SEVERE,
-		            "Could not create {0}", tmpfile);
-		    }
-//TODO - ignore???		    
-        } catch (SecurityException se) {
-            if (persistenceLogger.isLoggable(Level.SEVERE)) {
-                persistenceLogger.log(Level.SEVERE,
-	        "Error accessing Version File", se);
-	    }
-//TODO ignore? throw (SecurityException)se.fillInStackTrace();
-        }
-     }
-
-    // javadoc inherited from supertype
-    public ClientLog logFor(long cookie) throws LogException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(MultiLogManager.class.getName(), 
-	        "logFor", Long.valueOf(cookie));
-	}
-	ClientLog cl = null;
-	Long key = Long.valueOf(cookie);
-        Object prev = null;
-	
-        synchronized(logByIDLock) {
-	    if (destroyed)
-	        throw new LogException("Manger has been destroyed");
-		
-	    cl = (ClientLog)logByID.get(key); 
-	    if (cl == null) {
-	        cl = (directory==null)?
-		    (ClientLog)new TransientLogFile(cookie, logMgrRef):
-		    (ClientLog)new SimpleLogFile(
-		        directory + LOG_FILE + cookie, 
-		        cookie, logMgrRef);
-	        if (persistenceLogger.isLoggable(Level.FINEST)) {
-                    persistenceLogger.log(Level.FINEST,
-		    "Created ClientLog: {0}", 
-		    directory + LOG_FILE + cookie);
-		}
- 	        prev = logByID.put(key, cl);
-	    }
-            if (persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST,
-                "Currently managing {0} logs.", 
-                Integer.valueOf(logByID.size()));
-            }
-
-	} 
-        if (prev != null)
-	    throw new LogException("Previous mapping for cookie(" 
-	        + cookie + ") -- internal table corrupt?");
-	     
-	if (persistenceLogger.isLoggable(Level.FINEST)) {
-            persistenceLogger.log(Level.FINEST,
-            "Using ClientLog {0} for cookie {1}",
-	    new Object[] {cl, Long.valueOf(cookie)});
-	}
-	
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(MultiLogManager.class.getName(), 
-	        "logFor", cl);
-	}
-	return cl;
-    }
-
-    // javadoc inherited from supertype
-    private void release(long cookie) {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(MultiLogManager.class.getName(), 
-	        "release", Long.valueOf(cookie));
-	}
-	Object prev = null;
-        synchronized(logByIDLock) {
-	    if (destroyed)
-	        return;
-            if (persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST,
-                "Releasing ClientLog for cookie {0}",
-                Long.valueOf(cookie));
-            }
-	    prev = logByID.remove(Long.valueOf(cookie));
-            if (persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST,
-                "Currently managing {0} logs.", 
-                Integer.valueOf(logByID.size()));
-            }
-	}
-        
-	if (persistenceLogger.isLoggable(Level.FINEST)) {
-	    if (prev == null) {
-    	        persistenceLogger.log(Level.FINEST,
-		"Note: ClientLog already removed");
-            }
-        }
-
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(MultiLogManager.class.getName(), 
-	        "release");
-	}
-    }
-        
-    /**
-     *  Consumes the log file and re-constructs a system's
-     *  state.
-     */
-    public void recover() throws LogException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(MultiLogManager.class.getName(), 
-	        "recover");
-	}
-        // Short-circuit for non-persistent mode
-	if (directory == null) return;
-	
-	Log log = null;
-	File tmpfile = null;
-	String [] filenames = null;
-
-	/* Called by initialization thread only, 
-	 * so don't need to check for destroyed.
-	 */
-
-	try {
-	    tmpfile = new File(directory);
-	    filenames = tmpfile.list(filter);
-
-	    if (filenames == null || filenames.length == 0)
-	      return;
-
-            String logName;
-	    for (int i = 0; i < filenames.length; i++ ) {
-	        logName = directory +  filenames[i];
-	        log = new SimpleLogFile(logName, logMgrRef);
-		if (persistenceLogger.isLoggable(Level.FINEST)) {
-                    persistenceLogger.log(Level.FINEST,
-		    "Recovering log: {0}", logName);
-		}
-		try {
-		    log.recover(client);
-                
-		    /* Called by initialization thread only, 
-		     * so doesn't need to be synchronized here.
-		     */
-		    logByID.put(Long.valueOf(log.cookie()),log);
-	        } catch (LogException le) {
-	            if(persistenceLogger.isLoggable(Level.WARNING)) {
-		        persistenceLogger.log(Level.WARNING,
-			"Unable to recover log state", le);
-		    }
-		}
-	    }
-	} catch (SecurityException se) { // TODO - shouldn't this percolate back up?
-	    if(persistenceLogger.isLoggable(Level.WARNING)) {
-		persistenceLogger.log(Level.WARNING,
-		"Unable to recover log state", se);
-	    }
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(MultiLogManager.class.getName(), 
-	        "recover");
-	}
-    }
-
-
-    /**
-     * Retrieves the administration interface for the
-     * <code>MultiLogManager</code>
-     *
-     */
-    public Object getAdmin() {
-        // TBD - pass capability object instead?
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(MultiLogManager.class.getName(), 
-	        "getAdmin");
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(MultiLogManager.class.getName(), 
-	        "getAdmin", this);
-	}
-	return (MultiLogManagerAdmin)this;
-    }
-
-
-    /**
-     * Clean up all <code>LogFile</code> objects on behalf of caller.
-     *
-     * @see org.apache.river.admin.DestroyAdmin
-     * @see org.apache.river.system.FileSystem
-     */
-    public void destroy() {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(MultiLogManager.class.getName(), 
-	        "destroy");
-	}
-
-	// TBD - Set destroy flag? used by logFor()/release()
-	// TBD - Loop over values enum?
-	/**
-	 * Loop over know logs and invalidate them.
-	 */
-        synchronized(logByIDLock) {
-  	    if (destroyed) // return silently to avoids retries
-	        return;
- 	    if (logByID.size() > 0) {
-	        /* Can't use iterator because slf.invalidate() calls back into
-		 * this.release() in order to remove itself from logByID,
-		 * which would cause a concurrent modification exception.
-		 */
-	        Object [] vals = logByID.values().toArray();
-		Log slf = null;
-	        for (int i=0; i<vals.length; i++) {
-		    try {
-		        slf = (Log)vals[i];
-			if (slf != null) 
-			    slf.invalidate();
-			else {
-  		            if (persistenceLogger.isLoggable(Level.FINEST)) {
-                                persistenceLogger.log(Level.FINEST,
-				"Observed a null log file entry at: {0}", i);
-			    }
-			}
-                    } catch (LogException le) {
-                        if(persistenceLogger.isLoggable(Levels.HANDLED)) {
-		            persistenceLogger.log(Levels.HANDLED,
-			        "Unable to recover log state", le);
-			}
-                    } catch (java.util.NoSuchElementException nsee) {
-                        if(persistenceLogger.isLoggable(Levels.HANDLED)) {
-		            persistenceLogger.log(Levels.HANDLED,
-			        "Problem enumerating internal log state", nsee);
-			}
-     	            }
-	        }
-	        logByID.clear();
-		destroyed = true;
-	    }
-	} 
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(MultiLogManager.class.getName(), 
-	        "destroy");
-	}
-    }
-}
+/*
+ * 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.river.mahalo.log;
+
+import org.apache.river.logging.Levels;
+import org.apache.river.mahalo.proxy.TxnManager;
+import org.apache.river.system.FileSystem;
+import java.io.File;
+import java.io.FilenameFilter;
+
+import net.jini.admin.Administrable;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+public class MultiLogManager
+        implements LogManager, FileModes, Administrable, MultiLogManagerAdmin {
+    private static final String LOG_FILE = "Log.";
+
+    /** Logger for persistence related messages */
+    private static final Logger persistenceLogger = 
+        Logger.getLogger(TxnManager.MAHALO + ".persistence");
+
+    /** Logger for operations related messages */
+    private static final Logger operationsLogger = 
+        Logger.getLogger(TxnManager.MAHALO + ".operations");
+
+    /** Logger for initialization related messages */
+    private static final Logger initLogger = 
+        Logger.getLogger(TxnManager.MAHALO + ".init");
+
+    /** Client called during log recovery to process log objects */
+    private final LogRecovery client;
+
+    /** Map of log files keyed by their associated cookie */
+    private final Map logByID = new HashMap();
+    
+    /** Lock object used for coordinating access to logByID */
+    private final Object logByIDLock = new Object();
+    
+    /** Flag that is set to true upon destruction */
+    private boolean destroyed = false;
+    
+    /** Persistence directory */
+    private String directory = null;
+    
+    private final static FilenameFilter filter =
+        new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                if (operationsLogger.isLoggable(Level.FINER)) {
+                    operationsLogger.entering(FilenameFilter.class.getName(), 
+		        "accept", new Object[] {dir, name});
+		}
+                final boolean isLog = name.startsWith(LOG_FILE);
+                if (operationsLogger.isLoggable(Level.FINER)) {
+                    operationsLogger.exiting(FilenameFilter.class.getName(), 
+		        "accept", Boolean.valueOf(isLog));
+		}
+                return isLog;
+            };
+        };
+
+    /**
+     * Callback interface for log files to remove themselves from 
+     * this manager 
+     */ 
+    public static interface LogRemovalManager {
+        public void release(long cookie);
+    }
+    
+    /**
+     * Capability object passed to log files, which is called back upon
+     * log removal. 
+     */ 
+    final LogRemovalManager logMgrRef = new LogRemovalManager() {
+        public void release(long cookie) {
+	    MultiLogManager.this.release(cookie);
+	}
+    };
+    
+    /**
+     * Create a non-persistent <code>MultiLogManager</code>.
+     */
+    public MultiLogManager() {
+        directory = null; // just for insurance
+        client = null; 
+    }
+	    
+    /**
+     * Create a <code>MultiLogManager</code>.
+     *
+     * @param client who to inform during recovery.
+     *
+     * @param path where to store logging information.
+     */
+    public MultiLogManager(LogRecovery client, String path) {
+	if (path == null)
+	    throw new IllegalArgumentException("MultiLogManager: must use " +
+						"non-null path");
+	if (client == null)
+	    throw new IllegalArgumentException("MultiLogManager: must use " +
+						"non-null recovery client");
+        this.client = client;
+	directory = path; 
+
+	if (!directory.endsWith(File.separator))
+	    directory = directory.concat(File.separator);
+
+	if (persistenceLogger.isLoggable(Level.FINEST)) {
+            persistenceLogger.log(Level.FINEST,
+	    "directory = {0}", directory);
+	}
+
+        File tmpfile = new File(directory);
+ 
+        //If you attempt to access the Version file and
+        //it does not exist, start with zero.
+         try {
+            if (!tmpfile.exists())
+                if (!tmpfile.mkdirs())
+ 	            if (persistenceLogger.isLoggable(Level.SEVERE)) {
+                        persistenceLogger.log(Level.SEVERE,
+		            "Could not create {0}", tmpfile);
+		    }
+//TODO - ignore???		    
+        } catch (SecurityException se) {
+            if (persistenceLogger.isLoggable(Level.SEVERE)) {
+                persistenceLogger.log(Level.SEVERE,
+	        "Error accessing Version File", se);
+	    }
+//TODO ignore? throw (SecurityException)se.fillInStackTrace();
+        }
+     }
+
+    // javadoc inherited from supertype
+    public ClientLog logFor(long cookie) throws LogException {
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(MultiLogManager.class.getName(), 
+	        "logFor", Long.valueOf(cookie));
+	}
+	ClientLog cl = null;
+	Long key = Long.valueOf(cookie);
+        Object prev = null;
+	
+        synchronized(logByIDLock) {
+	    if (destroyed)
+	        throw new LogException("Manger has been destroyed");
+		
+	    cl = (ClientLog)logByID.get(key); 
+	    if (cl == null) {
+	        cl = (directory==null)?
+		    (ClientLog)new TransientLogFile(cookie, logMgrRef):
+		    (ClientLog)new SimpleLogFile(
+		        directory + LOG_FILE + cookie, 
+		        cookie, logMgrRef);
+	        if (persistenceLogger.isLoggable(Level.FINEST)) {
+                    persistenceLogger.log(Level.FINEST,
+		    "Created ClientLog: {0}", 
+		    directory + LOG_FILE + cookie);
+		}
+ 	        prev = logByID.put(key, cl);
+	    }
+            if (persistenceLogger.isLoggable(Level.FINEST)) {
+                persistenceLogger.log(Level.FINEST,
+                "Currently managing {0} logs.", 
+                Integer.valueOf(logByID.size()));
+            }
+
+	} 
+        if (prev != null)
+	    throw new LogException("Previous mapping for cookie(" 
+	        + cookie + ") -- internal table corrupt?");
+	     
+	if (persistenceLogger.isLoggable(Level.FINEST)) {
+            persistenceLogger.log(Level.FINEST,
+            "Using ClientLog {0} for cookie {1}",
+	    new Object[] {cl, Long.valueOf(cookie)});
+	}
+	
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(MultiLogManager.class.getName(), 
+	        "logFor", cl);
+	}
+	return cl;
+    }
+
+    // javadoc inherited from supertype
+    private void release(long cookie) {
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(MultiLogManager.class.getName(), 
+	        "release", Long.valueOf(cookie));
+	}
+	Object prev = null;
+        synchronized(logByIDLock) {
+	    if (destroyed)
+	        return;
+            if (persistenceLogger.isLoggable(Level.FINEST)) {
+                persistenceLogger.log(Level.FINEST,
+                "Releasing ClientLog for cookie {0}",
+                Long.valueOf(cookie));
+            }
+	    prev = logByID.remove(Long.valueOf(cookie));
+            if (persistenceLogger.isLoggable(Level.FINEST)) {
+                persistenceLogger.log(Level.FINEST,
+                "Currently managing {0} logs.", 
+                Integer.valueOf(logByID.size()));
+            }
+	}
+        
+	if (persistenceLogger.isLoggable(Level.FINEST)) {
+	    if (prev == null) {
+    	        persistenceLogger.log(Level.FINEST,
+		"Note: ClientLog already removed");
+            }
+        }
+
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(MultiLogManager.class.getName(), 
+	        "release");
+	}
+    }
+        
+    /**
+     *  Consumes the log file and re-constructs a system's
+     *  state.
+     */
+    public void recover() throws LogException {
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(MultiLogManager.class.getName(), 
+	        "recover");
+	}
+        // Short-circuit for non-persistent mode
+	if (directory == null) return;
+	
+	Log log = null;
+	File tmpfile = null;
+	String [] filenames = null;
+
+	/* Called by initialization thread only, 
+	 * so don't need to check for destroyed.
+	 */
+
+	try {
+	    tmpfile = new File(directory);
+	    filenames = tmpfile.list(filter);
+
+	    if (filenames == null || filenames.length == 0)
+	      return;
+
+            String logName;
+	    for (int i = 0; i < filenames.length; i++ ) {
+	        logName = directory +  filenames[i];
+	        log = new SimpleLogFile(logName, logMgrRef);
+		if (persistenceLogger.isLoggable(Level.FINEST)) {
+                    persistenceLogger.log(Level.FINEST,
+		    "Recovering log: {0}", logName);
+		}
+		try {
+		    log.recover(client);
+                
+		    /* Called by initialization thread only, 
+		     * so doesn't need to be synchronized here.
+		     */
+		    logByID.put(Long.valueOf(log.cookie()),log);
+	        } catch (LogException le) {
+	            if(persistenceLogger.isLoggable(Level.WARNING)) {
+		        persistenceLogger.log(Level.WARNING,
+			"Unable to recover log state", le);
+		    }
+		}
+	    }
+	} catch (SecurityException se) { // TODO - shouldn't this percolate back up?
+	    if(persistenceLogger.isLoggable(Level.WARNING)) {
+		persistenceLogger.log(Level.WARNING,
+		"Unable to recover log state", se);
+	    }
+	}
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(MultiLogManager.class.getName(), 
+	        "recover");
+	}
+    }
+
+
+    /**
+     * Retrieves the administration interface for the
+     * <code>MultiLogManager</code>
+     *
+     */
+    public Object getAdmin() {
+        // TBD - pass capability object instead?
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(MultiLogManager.class.getName(), 
+	        "getAdmin");
+	}
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(MultiLogManager.class.getName(), 
+	        "getAdmin", this);
+	}
+	return (MultiLogManagerAdmin)this;
+    }
+
+
+    /**
+     * Clean up all <code>LogFile</code> objects on behalf of caller.
+     *
+     * @see org.apache.river.admin.DestroyAdmin
+     * @see org.apache.river.system.FileSystem
+     */
+    public void destroy() {
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(MultiLogManager.class.getName(), 
+	        "destroy");
+	}
+
+	// TBD - Set destroy flag? used by logFor()/release()
+	// TBD - Loop over values enum?
+	/**
+	 * Loop over know logs and invalidate them.
+	 */
+        synchronized(logByIDLock) {
+  	    if (destroyed) // return silently to avoids retries
+	        return;
+ 	    if (logByID.size() > 0) {
+	        /* Can't use iterator because slf.invalidate() calls back into
+		 * this.release() in order to remove itself from logByID,
+		 * which would cause a concurrent modification exception.
+		 */
+	        Object [] vals = logByID.values().toArray();
+		Log slf = null;
+	        for (int i=0; i<vals.length; i++) {
+		    try {
+		        slf = (Log)vals[i];
+			if (slf != null) 
+			    slf.invalidate();
+			else {
+  		            if (persistenceLogger.isLoggable(Level.FINEST)) {
+                                persistenceLogger.log(Level.FINEST,
+				"Observed a null log file entry at: {0}", i);
+			    }
+			}
+                    } catch (LogException le) {
+                        if(persistenceLogger.isLoggable(Levels.HANDLED)) {
+		            persistenceLogger.log(Levels.HANDLED,
+			        "Unable to recover log state", le);
+			}
+                    } catch (java.util.NoSuchElementException nsee) {
+                        if(persistenceLogger.isLoggable(Levels.HANDLED)) {
+		            persistenceLogger.log(Levels.HANDLED,
+			        "Problem enumerating internal log state", nsee);
+			}
+     	            }
+	        }
+	        logByID.clear();
+		destroyed = true;
+	    }
+	} 
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(MultiLogManager.class.getName(), 
+	        "destroy");
+	}
+    }
+}

Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java Sun Jul  5 11:41:39 2020
@@ -1,464 +1,464 @@
-/*
- * 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.river.mahalo.log;
-
-import org.apache.river.logging.Levels;
-import org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager;
-import org.apache.river.mahalo.TxnManager;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidClassException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * An implementation of a re-usable <code>Log</code>.
- *
- * @author Sun Microsystems, Inc.
- *
- * @see org.apache.river.mahalo.log.Log
- */
-public class SimpleLogFile implements Log {
-    /** Unique ID associated with this log */
-    private /*final*/ long cookie;
-    /** Output stream for writing log objects */
-    private /*final*/ ObjectOutputStream out;
-    /** 
-     * File output stream associated with <code>out</code>. 
-     * Used to get a handle to underlying file descriptor object.
-     */
-    private /*final*/ FileOutputStream outfile;
-    /** (Relative) File name of the log file */
-    private final String name;
-    /** 
-     * Reference to <code>LogRemovalManager</code>, which is called
-     * to remove this log from the managed set of logs.
-     */
-    private final LogRemovalManager logMgr;
-    /** 
-     * Flag that indicates validity of this log. Set to false
-     * by call to <code>invalidate()</code>.
-     */
-    private boolean valid = true;
-    /**
-     * Flag to indicate that the log file has been created via
-     * the read-only constructor. This flag is set to false via
-     * the non-read-only constructor or a call to <code>recover()</code>
-     */
-    private boolean readonly = false;
-
-    /** Logger for persistence related messages */
-    private static final Logger persistenceLogger = 
-        Logger.getLogger(TxnManager.MAHALO + ".persistence");
-
-    /** Logger for operations related messages */
-    private static final Logger operationsLogger = 
-        Logger.getLogger(TxnManager.MAHALO + ".operations");
-
-    /** Logger for initialization related messages */
-    private static final Logger initLogger = 
-        Logger.getLogger(TxnManager.MAHALO + ".init");
-
-    /**
-     * This class extends <tt>ObjectInputStream</tt> and overrides the 
-     * <code>readStreamHeader</code> method to a no-op operation. This class
-     * is intended to work in conjunction with 
-     * <code>HeaderlessObjectOutputStream</code>.
-     */ 
-    private static class HeaderlessObjectInputStream extends ObjectInputStream {
-		
-	/**
-	 * Simple constructor that passes its argument to the superclass
-         *
-         * @exception IOException if an I/O error occurs
-	 */
-	public HeaderlessObjectInputStream(InputStream in) throws IOException {
-	    super(in);
-	}
-	
-	/**
-	 * Overrides <tt>ObjectInputStream</tt>'s method with no-op
-	 * functionality. 
-         * @see HeaderlessObjectOutputStream#writeStreamHeader
-         * @exception IOException if an I/O error occurs
-	 */
-	protected void readStreamHeader() throws IOException {
-	    // Do nothing
-	}
-    }
-    
-    /**
-     * This class extends <tt>ObjectOutputStream</tt> and overrides the
-     * <code>writeStreamHeader</code> method to a no-op operation. This 
-     * class is intended to be used in conjunction with 
-     * <code>HeaderlessObjectInputStream</code>.
-     */
-    private static class HeaderlessObjectOutputStream extends ObjectOutputStream {
-	
-	/**
-	 * Simple constructor that passes its argument to the superclass
-         *
-         * @exception IOException if an I/O error occurs
-	 */
-	public HeaderlessObjectOutputStream(OutputStream out) throws IOException {
-	    super(out);
-	}
-	
-	/**
-	 * Overrides <tt>ObjectOutputStream</tt>'s method with no-op
-	 * functionality.  This prevents header information from being
-	 * sent to the stream, which makes appending to existing log files
-	 * easier. Otherwise, appending header info to an existing log file
-	 * would cause a corresponding <code>ObjectInputStream</code> to
-	 * throw a <code>StreamCorruptedException</code> when it encountered
-	 * the header information instead of the class/object type code 
-	 * information it was expecting.
-	 *
-         * @exception IOException if an I/O error occurs
-	 */
-	protected void writeStreamHeader() throws IOException {
-	    // Do nothing
-	}
-    }
-
-    /**
-     * Creates a read-only <code>SimpleLogFile</code>
-     *
-     * To be used for read-only access to a named <code>Log</code>.  This is
-     * desired when recovering information from a <code>Log</code>.
-     *
-     * @param name names the file in which information is stored.
-     *
-     * @param logMgr    <code>LogRemovalManager</code> managing this log.
-     *                  This object is called back to remove this log 
-     *                  from the manager's managed set of log files. 
-     *
-     * @see org.apache.river.mahalo.log.Log
-     * @see org.apache.river.mahalo.log.LogManager
-     * @see org.apache.river.mahalo.log.MultiLogManager
-     * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager
-     */
-    public SimpleLogFile(String name, LogRemovalManager logMgr) {
-	this(name, 0, logMgr);
-	readonly = true;
-    }
-
-    /**
-     * Creates a <code>SimpleLogFile</code>.
-     *
-     * @param name names the file in which information is stored.
-     *
-     * @param cookie identifier representing information being stored.
-     *
-     * @param logMgr    <code>LogRemovalManager</code> managing this log.
-     *                  This object is called back to remove this log 
-     *                  from the manager's responsibility. 
-     *
-     * @see org.apache.river.mahalo.log.Log
-     * @see org.apache.river.mahalo.log.LogManager
-     * @see org.apache.river.mahalo.log.MultiLogManager
-     * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager
-     */
-    public SimpleLogFile(String name, long cookie, LogRemovalManager logMgr) {
-	if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(SimpleLogFile.class.getName(), 
-	        "init", new Object[] {name, Long.valueOf(cookie), logMgr});
-	}
-        if (name == null)
-            throw new IllegalArgumentException("SimpleLogFile: null name");
- 
-	if (logMgr == null)
-            throw new IllegalArgumentException(
-		"SimpleLogFile: null log manager");
-
-        this.name = name;
-        this.cookie = cookie;
-	this.logMgr = logMgr;
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(SimpleLogFile.class.getName(), 
-	        "init");
-	}
-    }
-
-
-    /**
-     * Returns the identifier associated with information in
-     * this <code>Log</code>.
-     *
-     * @see org.apache.river.mahalo.log.Log
-     */
-    public synchronized long cookie() {
-	return cookie;
-    }
-
-    /**
-     * Add a <code>LogRecord</code> to the <code>Log</code>.
-     *
-     * @param rec the record to be logged.
-     *
-     * @see org.apache.river.mahalo.log.LogRecord
-     */
-    public synchronized void write(LogRecord rec) throws LogException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(SimpleLogFile.class.getName(), 
-	        "write", rec);
-	}
-	try {
-	    if (!valid)
-		throw new InvalidatedLogException("Cannot write to to " +
-						"invalidated log");
-	    if (readonly)
-		throw new LogException("Unable to write to read only log");
-
-	    if (out == null) {
-	        boolean append = true;
-		File log = new File(name);
-                outfile = new FileOutputStream(name, append);
-                out = 
-		    new HeaderlessObjectOutputStream(
-		        new BufferedOutputStream(outfile));
-		if (log.length() == 0) {
-		    out.writeLong(cookie);
-                }
-		out.reset();
-	    }
-
-	    out.writeObject(rec);
-	    out.flush();
-	    outfile.getFD().sync();
-
-	    if (persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST,
-		    "Wrote: {0}", rec);
-	    }	
-	} catch (InvalidClassException ice) {
-	    if (persistenceLogger.isLoggable(Level.WARNING)) {
-                persistenceLogger.log(Level.WARNING,
-		"Problem persisting LogRecord", ice);
-	    }
-// TODO - assertion error? ... should not happen
-	} catch (NotSerializableException nse) {
-	    if (persistenceLogger.isLoggable(Level.WARNING)) {
-                persistenceLogger.log(Level.WARNING,
-		"Problem persisting LogRecord", nse);
-	    }
-// TODO - assertion error? ... should not happen
-	} catch (IOException ioe) {
-	    if (persistenceLogger.isLoggable(Level.WARNING)) {
-                persistenceLogger.log(Level.WARNING,
-		"Problem persisting LogRecord", ioe);
-	    }
-// TODO - throw LogException?
-        } catch (SecurityException se) {
-	    if (persistenceLogger.isLoggable(Level.WARNING)) {
-                persistenceLogger.log(Level.WARNING,
-		"Problem persisting LogRecord", se);
-	    }
-// TODO - assertion error? ... should not happen
-        }
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(SimpleLogFile.class.getName(), 
-	        "write", rec);
-	}
-    }
-
-    /**
-     * Invalidate the log.
-     */
-    public synchronized void invalidate() throws LogException {
-        // No short circuit check because we allow repeat calls
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(MultiLogManager.class.getName(), 
-	        "invalidate");
-	}
-	
-	if (persistenceLogger.isLoggable(Level.FINEST)) {
-            persistenceLogger.log(Level.FINEST,
-                "Invalidating log for cookie: {0}", Long.valueOf(cookie));
-	}
-
-	if (valid) {
-	    // Set validity flag to false
-	    valid = false;
-
-	    // Ask log manager to remove us from its managed set
-	    logMgr.release(cookie);
-	}
-		
-	try { 
-	    if (out != null) {
-                if (persistenceLogger.isLoggable(Level.FINEST)) {
-                    persistenceLogger.log(Level.FINEST,
-                        "Closing log file for: {0}", Long.valueOf(cookie));
-                }
-	        out.close(); // calls outfile.close()
-            }
-	} catch (IOException ioe) { // just log it
-	    if (persistenceLogger.isLoggable(Levels.HANDLED)) {
-                persistenceLogger.log(Levels.HANDLED,
-		"Problem closing log file", ioe);
-	    }
-	}
-	
-	try {
-	    File fl = new File(name);
-            if (persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST,
-                    "Deleting log file for: {0}", Long.valueOf(cookie));
-            }
-	    if(!fl.delete()) {
-	        if (persistenceLogger.isLoggable(Levels.HANDLED)) {
-                    persistenceLogger.log(Levels.HANDLED,
-		        "Could not delete log file");
-		}
-	    }
-	} catch (SecurityException se) { // notify caller
-	    if (persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST,
-                    "SecurityException on log deletion", se);
-	    }
-	    throw new LogException("SimpleLogFile: invalidate: "
-	        + "cannot delete log file.");
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(MultiLogManager.class.getName(), 
-	        "invalidate");
-	}
-    }
-
-    /**
-     * Recover information from the log.
-     *
-     * @param client who to inform with information from the log.
-     *
-     * @see org.apache.river.mahalo.log.LogRecovery
-     */
-    public synchronized void recover(LogRecovery client) throws LogException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(MultiLogManager.class.getName(), 
-	        "recover", client);
-	}
-	if (!valid)
-	    throw new InvalidatedLogException("Cannot recover from " +
-						"invalidated log");
-	if (client == null)
-	    throw new IllegalArgumentException("Cannot have a <null> " 
-	        + "client argument.");
-	
-	ObjectInputStream in = null;
-      	ArrayList recList = new ArrayList();
-	try {
-	    if (persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST,
-                    "Recovering from: {0}", name);
-	    }
-	    in = new HeaderlessObjectInputStream(
-	             new BufferedInputStream(
-		         new FileInputStream(name)));
-
-	    this.cookie = in.readLong();
-	    LogRecord rec = null;
-	    boolean done = false;
-	    boolean update = true;
-	    try {
-	        while (!done) {
-		    // try to catch cast exceptions here
-	            rec = (LogRecord)in.readObject();
-		    if (rec != null) {
-		        recList.add(rec);
-		    } else { //TBD - ignore?
-		        update = false;
-			done = true; // bad log ... skip it
-		        if (persistenceLogger.isLoggable(Levels.HANDLED)) {
-                            persistenceLogger.log(Levels.HANDLED,
-		                "Log for cookie {0} contained a null "
-				+ "record object", Long.valueOf(cookie));
-		        }
-		    }
-	        }
-	    } catch (ClassNotFoundException cnfe) {
-                update = false;
-	        if (persistenceLogger.isLoggable(Level.WARNING)) {
-                    persistenceLogger.log(Level.WARNING,
-		    "Problem recovering log file", cnfe);
-	        }
-// TODO - assertion error? ... should not happen
-            } catch (ClassCastException cce) {
-                update = false;
-	        if (persistenceLogger.isLoggable(Level.WARNING)) {
-                    persistenceLogger.log(Level.WARNING,
-		    "Problem recovering log file", cce);
-	        }
-// TODO - assertion error? ... should not happen
-	    } catch (EOFException eofe) {
-		// OK. Assume we've hit the end of the log file
-            } catch (IOException ioe) {
-                update = false;
-	        if (persistenceLogger.isLoggable(Level.WARNING)) {
-                    persistenceLogger.log(Level.WARNING,
-		    "Problem recovering log file", ioe);
-	        }
-	    }
-	    
-	    if (update) {
-	        for (int i=0; i<recList.size(); i++) {
-	            client.recover(cookie, (LogRecord)recList.get(i));
-	        }
-	    } else {
-	        if (persistenceLogger.isLoggable(Level.WARNING)) {
-                    persistenceLogger.log(Level.WARNING,
-                        "Skipping log recovery for", name);
-	        }
-            }
-	} catch (IOException ioe) {
-	    // bogus log file -- skip it
-	    if (persistenceLogger.isLoggable(Level.WARNING)) {
-                persistenceLogger.log(Level.WARNING,
-		"Problem recovering log file", ioe);
-	    }
-        } finally {
-	    try {
-	        if (in != null) in.close(); // calls fin.close()
-	    } catch (IOException ioe) {
-	        if (persistenceLogger.isLoggable(Levels.HANDLED)) {
-                    persistenceLogger.log(Levels.HANDLED,
-		    "Problem closing recovered log file", ioe);
-	        }
-	    }
-	    readonly = false;
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.exiting(MultiLogManager.class.getName(), 
-	        "recover");
-	}
-    }
-    // TBD - add a toString() method for debugging purposes
-}
+/*
+ * 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.river.mahalo.log;
+
+import org.apache.river.logging.Levels;
+import org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager;
+import org.apache.river.mahalo.proxy.TxnManager;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidClassException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * An implementation of a re-usable <code>Log</code>.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ * @see org.apache.river.mahalo.log.Log
+ */
+public class SimpleLogFile implements Log {
+    /** Unique ID associated with this log */
+    private /*final*/ long cookie;
+    /** Output stream for writing log objects */
+    private /*final*/ ObjectOutputStream out;
+    /** 
+     * File output stream associated with <code>out</code>. 
+     * Used to get a handle to underlying file descriptor object.
+     */
+    private /*final*/ FileOutputStream outfile;
+    /** (Relative) File name of the log file */
+    private final String name;
+    /** 
+     * Reference to <code>LogRemovalManager</code>, which is called
+     * to remove this log from the managed set of logs.
+     */
+    private final LogRemovalManager logMgr;
+    /** 
+     * Flag that indicates validity of this log. Set to false
+     * by call to <code>invalidate()</code>.
+     */
+    private boolean valid = true;
+    /**
+     * Flag to indicate that the log file has been created via
+     * the read-only constructor. This flag is set to false via
+     * the non-read-only constructor or a call to <code>recover()</code>
+     */
+    private boolean readonly = false;
+
+    /** Logger for persistence related messages */
+    private static final Logger persistenceLogger = 
+        Logger.getLogger(TxnManager.MAHALO + ".persistence");
+
+    /** Logger for operations related messages */
+    private static final Logger operationsLogger = 
+        Logger.getLogger(TxnManager.MAHALO + ".operations");
+
+    /** Logger for initialization related messages */
+    private static final Logger initLogger = 
+        Logger.getLogger(TxnManager.MAHALO + ".init");
+
+    /**
+     * This class extends <tt>ObjectInputStream</tt> and overrides the 
+     * <code>readStreamHeader</code> method to a no-op operation. This class
+     * is intended to work in conjunction with 
+     * <code>HeaderlessObjectOutputStream</code>.
+     */ 
+    private static class HeaderlessObjectInputStream extends ObjectInputStream {
+		
+	/**
+	 * Simple constructor that passes its argument to the superclass
+         *
+         * @exception IOException if an I/O error occurs
+	 */
+	public HeaderlessObjectInputStream(InputStream in) throws IOException {
+	    super(in);
+	}
+	
+	/**
+	 * Overrides <tt>ObjectInputStream</tt>'s method with no-op
+	 * functionality. 
+         * @see HeaderlessObjectOutputStream#writeStreamHeader
+         * @exception IOException if an I/O error occurs
+	 */
+	protected void readStreamHeader() throws IOException {
+	    // Do nothing
+	}
+    }
+    
+    /**
+     * This class extends <tt>ObjectOutputStream</tt> and overrides the
+     * <code>writeStreamHeader</code> method to a no-op operation. This 
+     * class is intended to be used in conjunction with 
+     * <code>HeaderlessObjectInputStream</code>.
+     */
+    private static class HeaderlessObjectOutputStream extends ObjectOutputStream {
+	
+	/**
+	 * Simple constructor that passes its argument to the superclass
+         *
+         * @exception IOException if an I/O error occurs
+	 */
+	public HeaderlessObjectOutputStream(OutputStream out) throws IOException {
+	    super(out);
+	}
+	
+	/**
+	 * Overrides <tt>ObjectOutputStream</tt>'s method with no-op
+	 * functionality.  This prevents header information from being
+	 * sent to the stream, which makes appending to existing log files
+	 * easier. Otherwise, appending header info to an existing log file
+	 * would cause a corresponding <code>ObjectInputStream</code> to
+	 * throw a <code>StreamCorruptedException</code> when it encountered
+	 * the header information instead of the class/object type code 
+	 * information it was expecting.
+	 *
+         * @exception IOException if an I/O error occurs
+	 */
+	protected void writeStreamHeader() throws IOException {
+	    // Do nothing
+	}
+    }
+
+    /**
+     * Creates a read-only <code>SimpleLogFile</code>
+     *
+     * To be used for read-only access to a named <code>Log</code>.  This is
+     * desired when recovering information from a <code>Log</code>.
+     *
+     * @param name names the file in which information is stored.
+     *
+     * @param logMgr    <code>LogRemovalManager</code> managing this log.
+     *                  This object is called back to remove this log 
+     *                  from the manager's managed set of log files. 
+     *
+     * @see org.apache.river.mahalo.log.Log
+     * @see org.apache.river.mahalo.log.LogManager
+     * @see org.apache.river.mahalo.log.MultiLogManager
+     * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager
+     */
+    public SimpleLogFile(String name, LogRemovalManager logMgr) {
+	this(name, 0, logMgr);
+	readonly = true;
+    }
+
+    /**
+     * Creates a <code>SimpleLogFile</code>.
+     *
+     * @param name names the file in which information is stored.
+     *
+     * @param cookie identifier representing information being stored.
+     *
+     * @param logMgr    <code>LogRemovalManager</code> managing this log.
+     *                  This object is called back to remove this log 
+     *                  from the manager's responsibility. 
+     *
+     * @see org.apache.river.mahalo.log.Log
+     * @see org.apache.river.mahalo.log.LogManager
+     * @see org.apache.river.mahalo.log.MultiLogManager
+     * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager
+     */
+    public SimpleLogFile(String name, long cookie, LogRemovalManager logMgr) {
+	if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(SimpleLogFile.class.getName(), 
+	        "init", new Object[] {name, Long.valueOf(cookie), logMgr});
+	}
+        if (name == null)
+            throw new IllegalArgumentException("SimpleLogFile: null name");
+ 
+	if (logMgr == null)
+            throw new IllegalArgumentException(
+		"SimpleLogFile: null log manager");
+
+        this.name = name;
+        this.cookie = cookie;
+	this.logMgr = logMgr;
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(SimpleLogFile.class.getName(), 
+	        "init");
+	}
+    }
+
+
+    /**
+     * Returns the identifier associated with information in
+     * this <code>Log</code>.
+     *
+     * @see org.apache.river.mahalo.log.Log
+     */
+    public synchronized long cookie() {
+	return cookie;
+    }
+
+    /**
+     * Add a <code>LogRecord</code> to the <code>Log</code>.
+     *
+     * @param rec the record to be logged.
+     *
+     * @see org.apache.river.mahalo.log.LogRecord
+     */
+    public synchronized void write(LogRecord rec) throws LogException {
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(SimpleLogFile.class.getName(), 
+	        "write", rec);
+	}
+	try {
+	    if (!valid)
+		throw new InvalidatedLogException("Cannot write to to " +
+						"invalidated log");
+	    if (readonly)
+		throw new LogException("Unable to write to read only log");
+
+	    if (out == null) {
+	        boolean append = true;
+		File log = new File(name);
+                outfile = new FileOutputStream(name, append);
+                out = 
+		    new HeaderlessObjectOutputStream(
+		        new BufferedOutputStream(outfile));
+		if (log.length() == 0) {
+		    out.writeLong(cookie);
+                }
+		out.reset();
+	    }
+
+	    out.writeObject(rec);
+	    out.flush();
+	    outfile.getFD().sync();
+
+	    if (persistenceLogger.isLoggable(Level.FINEST)) {
+                persistenceLogger.log(Level.FINEST,
+		    "Wrote: {0}", rec);
+	    }	
+	} catch (InvalidClassException ice) {
+	    if (persistenceLogger.isLoggable(Level.WARNING)) {
+                persistenceLogger.log(Level.WARNING,
+		"Problem persisting LogRecord", ice);
+	    }
+// TODO - assertion error? ... should not happen
+	} catch (NotSerializableException nse) {
+	    if (persistenceLogger.isLoggable(Level.WARNING)) {
+                persistenceLogger.log(Level.WARNING,
+		"Problem persisting LogRecord", nse);
+	    }
+// TODO - assertion error? ... should not happen
+	} catch (IOException ioe) {
+	    if (persistenceLogger.isLoggable(Level.WARNING)) {
+                persistenceLogger.log(Level.WARNING,
+		"Problem persisting LogRecord", ioe);
+	    }
+// TODO - throw LogException?
+        } catch (SecurityException se) {
+	    if (persistenceLogger.isLoggable(Level.WARNING)) {
+                persistenceLogger.log(Level.WARNING,
+		"Problem persisting LogRecord", se);
+	    }
+// TODO - assertion error? ... should not happen
+        }
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(SimpleLogFile.class.getName(), 
+	        "write", rec);
+	}
+    }
+
+    /**
+     * Invalidate the log.
+     */
+    public synchronized void invalidate() throws LogException {
+        // No short circuit check because we allow repeat calls
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(MultiLogManager.class.getName(), 
+	        "invalidate");
+	}
+	
+	if (persistenceLogger.isLoggable(Level.FINEST)) {
+            persistenceLogger.log(Level.FINEST,
+                "Invalidating log for cookie: {0}", Long.valueOf(cookie));
+	}
+
+	if (valid) {
+	    // Set validity flag to false
+	    valid = false;
+
+	    // Ask log manager to remove us from its managed set
+	    logMgr.release(cookie);
+	}
+		
+	try { 
+	    if (out != null) {
+                if (persistenceLogger.isLoggable(Level.FINEST)) {
+                    persistenceLogger.log(Level.FINEST,
+                        "Closing log file for: {0}", Long.valueOf(cookie));
+                }
+	        out.close(); // calls outfile.close()
+            }
+	} catch (IOException ioe) { // just log it
+	    if (persistenceLogger.isLoggable(Levels.HANDLED)) {
+                persistenceLogger.log(Levels.HANDLED,
+		"Problem closing log file", ioe);
+	    }
+	}
+	
+	try {
+	    File fl = new File(name);
+            if (persistenceLogger.isLoggable(Level.FINEST)) {
+                persistenceLogger.log(Level.FINEST,
+                    "Deleting log file for: {0}", Long.valueOf(cookie));
+            }
+	    if(!fl.delete()) {
+	        if (persistenceLogger.isLoggable(Levels.HANDLED)) {
+                    persistenceLogger.log(Levels.HANDLED,
+		        "Could not delete log file");
+		}
+	    }
+	} catch (SecurityException se) { // notify caller
+	    if (persistenceLogger.isLoggable(Level.FINEST)) {
+                persistenceLogger.log(Level.FINEST,
+                    "SecurityException on log deletion", se);
+	    }
+	    throw new LogException("SimpleLogFile: invalidate: "
+	        + "cannot delete log file.");
+	}
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(MultiLogManager.class.getName(), 
+	        "invalidate");
+	}
+    }
+
+    /**
+     * Recover information from the log.
+     *
+     * @param client who to inform with information from the log.
+     *
+     * @see org.apache.river.mahalo.log.LogRecovery
+     */
+    public synchronized void recover(LogRecovery client) throws LogException {
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.entering(MultiLogManager.class.getName(), 
+	        "recover", client);
+	}
+	if (!valid)
+	    throw new InvalidatedLogException("Cannot recover from " +
+						"invalidated log");
+	if (client == null)
+	    throw new IllegalArgumentException("Cannot have a <null> " 
+	        + "client argument.");
+	
+	ObjectInputStream in = null;
+      	ArrayList recList = new ArrayList();
+	try {
+	    if (persistenceLogger.isLoggable(Level.FINEST)) {
+                persistenceLogger.log(Level.FINEST,
+                    "Recovering from: {0}", name);
+	    }
+	    in = new HeaderlessObjectInputStream(
+	             new BufferedInputStream(
+		         new FileInputStream(name)));
+
+	    this.cookie = in.readLong();
+	    LogRecord rec = null;
+	    boolean done = false;
+	    boolean update = true;
+	    try {
+	        while (!done) {
+		    // try to catch cast exceptions here
+	            rec = (LogRecord)in.readObject();
+		    if (rec != null) {
+		        recList.add(rec);
+		    } else { //TBD - ignore?
+		        update = false;
+			done = true; // bad log ... skip it
+		        if (persistenceLogger.isLoggable(Levels.HANDLED)) {
+                            persistenceLogger.log(Levels.HANDLED,
+		                "Log for cookie {0} contained a null "
+				+ "record object", Long.valueOf(cookie));
+		        }
+		    }
+	        }
+	    } catch (ClassNotFoundException cnfe) {
+                update = false;
+	        if (persistenceLogger.isLoggable(Level.WARNING)) {
+                    persistenceLogger.log(Level.WARNING,
+		    "Problem recovering log file", cnfe);
+	        }
+// TODO - assertion error? ... should not happen
+            } catch (ClassCastException cce) {
+                update = false;
+	        if (persistenceLogger.isLoggable(Level.WARNING)) {
+                    persistenceLogger.log(Level.WARNING,
+		    "Problem recovering log file", cce);
+	        }
+// TODO - assertion error? ... should not happen
+	    } catch (EOFException eofe) {
+		// OK. Assume we've hit the end of the log file
+            } catch (IOException ioe) {
+                update = false;
+	        if (persistenceLogger.isLoggable(Level.WARNING)) {
+                    persistenceLogger.log(Level.WARNING,
+		    "Problem recovering log file", ioe);
+	        }
+	    }
+	    
+	    if (update) {
+	        for (int i=0; i<recList.size(); i++) {
+	            client.recover(cookie, (LogRecord)recList.get(i));
+	        }
+	    } else {
+	        if (persistenceLogger.isLoggable(Level.WARNING)) {
+                    persistenceLogger.log(Level.WARNING,
+                        "Skipping log recovery for", name);
+	        }
+            }
+	} catch (IOException ioe) {
+	    // bogus log file -- skip it
+	    if (persistenceLogger.isLoggable(Level.WARNING)) {
+                persistenceLogger.log(Level.WARNING,
+		"Problem recovering log file", ioe);
+	    }
+        } finally {
+	    try {
+	        if (in != null) in.close(); // calls fin.close()
+	    } catch (IOException ioe) {
+	        if (persistenceLogger.isLoggable(Levels.HANDLED)) {
+                    persistenceLogger.log(Levels.HANDLED,
+		    "Problem closing recovered log file", ioe);
+	        }
+	    }
+	    readonly = false;
+	}
+        if (operationsLogger.isLoggable(Level.FINER)) {
+            operationsLogger.exiting(MultiLogManager.class.getName(), 
+	        "recover");
+	}
+    }
+    // TBD - add a toString() method for debugging purposes
+}