You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2010/08/23 20:08:42 UTC

svn commit: r988237 [14/24] - in /incubator/lcf/trunk: modules/connectors/activedirectory/connector/org/apache/acf/authorities/authorities/activedirectory/ modules/connectors/documentum/connector/org/apache/acf/crawler/authorities/DCTM/ modules/connect...

Modified: incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockManager.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockManager.java?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockManager.java (original)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockManager.java Mon Aug 23 18:08:32 2010
@@ -20,7 +20,7 @@ package org.apache.acf.core.lockmanager;
 
 import org.apache.acf.core.interfaces.*;
 import org.apache.acf.core.system.Logging;
-import org.apache.acf.core.system.LCF;
+import org.apache.acf.core.system.ACF;
 import java.util.*;
 import java.io.*;
 
@@ -51,13 +51,13 @@ public class LockManager implements ILoc
   protected File synchDirectory = null;
 
   public LockManager()
-    throws LCFException
+    throws ACFException
   {
-    synchDirectory = LCF.getFileProperty(synchDirectoryProperty);
+    synchDirectory = ACF.getFileProperty(synchDirectoryProperty);
     if (synchDirectory != null)
     {
       if (!synchDirectory.isDirectory())
-        throw new LCFException("Property "+synchDirectoryProperty+" must point to an existing, writeable directory!",LCFException.SETUP_ERROR);
+        throw new ACFException("Property "+synchDirectoryProperty+" must point to an existing, writeable directory!",ACFException.SETUP_ERROR);
     }
   }
 
@@ -70,7 +70,7 @@ public class LockManager implements ILoc
     return "flag-"+flagName;
   }
   
-  /** Global flag information.  This is used only when all of LCF is run within one process. */
+  /** Global flag information.  This is used only when all of ACF is run within one process. */
   protected static HashMap globalFlags = new HashMap();
   
   /** Raise a flag.  Use this method to assert a condition, or send a global signal.  The flag will be reset when the
@@ -78,7 +78,7 @@ public class LockManager implements ILoc
   *@param flagName is the name of the flag to set.
   */
   public void setGlobalFlag(String flagName)
-    throws LCFException
+    throws ACFException
   {
     if (synchDirectory == null)
     {
@@ -93,18 +93,18 @@ public class LockManager implements ILoc
       String resourceName = getFlagResourceName(flagName);
       String path = makeFilePath(resourceName);
       (new File(path)).mkdirs();
-      File f = new File(path,LCF.safeFileName(resourceName));
+      File f = new File(path,ACF.safeFileName(resourceName));
       try
       {
         f.createNewFile();
       }
       catch (InterruptedIOException e)
       {
-        throw new LCFException("Interrupted: "+e.getMessage(),e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted: "+e.getMessage(),e,ACFException.INTERRUPTED);
       }
       catch (IOException e)
       {
-        throw new LCFException(e.getMessage(),e);
+        throw new ACFException(e.getMessage(),e);
       }
     }
   }
@@ -113,7 +113,7 @@ public class LockManager implements ILoc
   *@param flagName is the name of the flag to clear.
   */
   public void clearGlobalFlag(String flagName)
-    throws LCFException
+    throws ACFException
   {
     if (synchDirectory == null)
     {
@@ -126,7 +126,7 @@ public class LockManager implements ILoc
     else
     {
       String resourceName = getFlagResourceName(flagName);
-      File f = new File(makeFilePath(resourceName),LCF.safeFileName(resourceName));
+      File f = new File(makeFilePath(resourceName),ACF.safeFileName(resourceName));
       f.delete();
     }
   }
@@ -136,7 +136,7 @@ public class LockManager implements ILoc
   *@return true if the flag is set, false otherwise.
   */
   public boolean checkGlobalFlag(String flagName)
-    throws LCFException
+    throws ACFException
   {
     if (synchDirectory == null)
     {
@@ -149,12 +149,12 @@ public class LockManager implements ILoc
     else
     {
       String resourceName = getFlagResourceName(flagName);
-      File f = new File(makeFilePath(resourceName),LCF.safeFileName(resourceName));
+      File f = new File(makeFilePath(resourceName),ACF.safeFileName(resourceName));
       return f.exists();
     }
   }
 
-  /** Global resource data.  Used only when LCF is run entirely out of one process. */
+  /** Global resource data.  Used only when ACF is run entirely out of one process. */
   protected static HashMap globalData = new HashMap();
   
   /** Read data from a shared data resource.  Use this method to read any existing data, or get a null back if there is no such resource.
@@ -163,7 +163,7 @@ public class LockManager implements ILoc
   *@return a byte array containing the data, or null.
   */
   public byte[] readData(String resourceName)
-    throws LCFException
+    throws ACFException
   {
     if (synchDirectory == null)
     {
@@ -175,7 +175,7 @@ public class LockManager implements ILoc
     }
     else
     {
-      File f = new File(makeFilePath(resourceName),LCF.safeFileName(resourceName));
+      File f = new File(makeFilePath(resourceName),ACF.safeFileName(resourceName));
       try
       {
         InputStream is = new FileInputStream(f);
@@ -202,11 +202,11 @@ public class LockManager implements ILoc
       }
       catch (InterruptedIOException e)
       {
-        throw new LCFException("Interrupted: "+e.getMessage(),e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted: "+e.getMessage(),e,ACFException.INTERRUPTED);
       }
       catch (IOException e)
       {
-        throw new LCFException("IO exception: "+e.getMessage(),e);
+        throw new ACFException("IO exception: "+e.getMessage(),e);
       }
     }
   }
@@ -217,7 +217,7 @@ public class LockManager implements ILoc
   *@param data is the byte array containing the data.  Pass null if you want to delete the resource completely.
   */
   public void writeData(String resourceName, byte[] data)
-    throws LCFException
+    throws ACFException
   {
     if (synchDirectory == null)
     {
@@ -237,7 +237,7 @@ public class LockManager implements ILoc
         String path = makeFilePath(resourceName);
         // Make sure the directory exists
         (new File(path)).mkdirs();
-        File f = new File(path,LCF.safeFileName(resourceName));
+        File f = new File(path,ACF.safeFileName(resourceName));
         if (data == null)
         {
           f.delete();
@@ -255,11 +255,11 @@ public class LockManager implements ILoc
       }
       catch (InterruptedIOException e)
       {
-        throw new LCFException("Interrupted: "+e.getMessage(),e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted: "+e.getMessage(),e,ACFException.INTERRUPTED);
       }
       catch (IOException e)
       {
-        throw new LCFException("IO exception: "+e.getMessage(),e);
+        throw new ACFException("IO exception: "+e.getMessage(),e);
       }
     }
   }
@@ -267,7 +267,7 @@ public class LockManager implements ILoc
   /** Wait for a time before retrying a lock.
   */
   public void timedWait(int time)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -277,11 +277,11 @@ public class LockManager implements ILoc
 
     try
     {
-      LCF.sleep(time);
+      ACF.sleep(time);
     }
     catch (InterruptedException e)
     {
-      throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+      throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
     }
   }
 
@@ -292,7 +292,7 @@ public class LockManager implements ILoc
   * interfere with one another (use of another, standard, write lock per item can guarantee this).
   */
   public void enterNonExWriteLock(String lockKey)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -315,7 +315,7 @@ public class LockManager implements ILoc
     // Check for illegalities
     if (ll.hasReadLock())
     {
-      throw new LCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",LCFException.GENERAL_ERROR);
+      throw new ACFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ACFException.GENERAL_ERROR);
     }
 
     // We don't own a local non-ex write lock.  Get one.  The global lock will need
@@ -330,7 +330,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -342,7 +342,7 @@ public class LockManager implements ILoc
   }
 
   public void enterNonExWriteLockNoWait(String lockKey)
-    throws LCFException, LockException
+    throws ACFException, LockException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -365,7 +365,7 @@ public class LockManager implements ILoc
     // Check for illegalities
     if (ll.hasReadLock())
     {
-      throw new LCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",LCFException.GENERAL_ERROR);
+      throw new ACFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ACFException.GENERAL_ERROR);
     }
 
     // We don't own a local non-ex write lock.  Get one.  The global lock will need
@@ -394,7 +394,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -408,7 +408,7 @@ public class LockManager implements ILoc
   /** Leave a non-exclusive write lock.
   */
   public void leaveNonExWriteLock(String lockKey)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -438,17 +438,17 @@ public class LockManager implements ILoc
           try
           {
             lo.leaveNonExWriteLock();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
           catch (InterruptedException e2)
           {
             ll.incrementNonExWriteLocks();
-            throw new LCFException("Interrupted",e2,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e2,ACFException.INTERRUPTED);
           }
           catch (ExpiredObjectException e2)
           {
             ll.incrementNonExWriteLocks();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
         }
         catch (ExpiredObjectException e)
@@ -465,7 +465,7 @@ public class LockManager implements ILoc
   * NOTE: Can't enter until all readers have left.
   */
   public void enterWriteLock(String lockKey)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -487,7 +487,7 @@ public class LockManager implements ILoc
     // Check for illegalities
     if (ll.hasReadLock() || ll.hasNonExWriteLock())
     {
-      throw new LCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",LCFException.GENERAL_ERROR);
+      throw new ACFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ACFException.GENERAL_ERROR);
     }
 
     // We don't own a local write lock.  Get one.  The global lock will need
@@ -503,7 +503,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -515,7 +515,7 @@ public class LockManager implements ILoc
   }
 
   public void enterWriteLockNoWait(String lockKey)
-    throws LCFException, LockException
+    throws ACFException, LockException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -537,7 +537,7 @@ public class LockManager implements ILoc
     // Check for illegalities
     if (ll.hasReadLock() || ll.hasNonExWriteLock())
     {
-      throw new LCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",LCFException.GENERAL_ERROR);
+      throw new ACFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ACFException.GENERAL_ERROR);
     }
 
     // We don't own a local write lock.  Get one.  The global lock will need
@@ -566,7 +566,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -579,7 +579,7 @@ public class LockManager implements ILoc
   }
 
   public void leaveWriteLock(String lockKey)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -606,17 +606,17 @@ public class LockManager implements ILoc
           try
           {
             lo.leaveWriteLock();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
           catch (InterruptedException e2)
           {
             ll.incrementWriteLocks();
-            throw new LCFException("Interrupted",e2,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e2,ACFException.INTERRUPTED);
           }
           catch (ExpiredObjectException e2)
           {
             ll.incrementWriteLocks();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
         }
         catch (ExpiredObjectException e)
@@ -632,7 +632,7 @@ public class LockManager implements ILoc
   /** Enter a read-only locked area (i.e., block ONLY if there's a writer)
   */
   public void enterReadLock(String lockKey)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -663,7 +663,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -675,7 +675,7 @@ public class LockManager implements ILoc
   }
 
   public void enterReadLockNoWait(String lockKey)
-    throws LCFException, LockException
+    throws ACFException, LockException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -718,7 +718,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -731,7 +731,7 @@ public class LockManager implements ILoc
   }
 
   public void leaveReadLock(String lockKey)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -758,17 +758,17 @@ public class LockManager implements ILoc
           try
           {
             lo.leaveReadLock();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
           catch (InterruptedException e2)
           {
             ll.incrementReadLocks();
-            throw new LCFException("Interrupted",e2,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e2,ACFException.INTERRUPTED);
           }
           catch (ExpiredObjectException e2)
           {
             ll.incrementReadLocks();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
         }
         catch (ExpiredObjectException e)
@@ -781,7 +781,7 @@ public class LockManager implements ILoc
   }
 
   public void clearLocks()
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -807,7 +807,7 @@ public class LockManager implements ILoc
   /** Enter multiple locks
   */
   public void enterLocks(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks)
-    throws LCFException
+    throws ACFException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -860,7 +860,7 @@ public class LockManager implements ILoc
           // Check for illegalities
           if ((ll.hasReadLock() || ll.hasNonExWriteLock()) && !ll.hasWriteLock())
           {
-            throw new LCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",LCFException.GENERAL_ERROR);
+            throw new ACFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ACFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -888,7 +888,7 @@ public class LockManager implements ILoc
           // Check for illegalities
           if (ll.hasReadLock() && !(ll.hasNonExWriteLock() || ll.hasWriteLock()))
           {
-            throw new LCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",LCFException.GENERAL_ERROR);
+            throw new ACFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ACFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -942,7 +942,7 @@ public class LockManager implements ILoc
     catch (Throwable ex)
     {
       // No matter what, undo the locks we've taken
-      LCFException ae = null;
+      ACFException ae = null;
       int errno = 0;
 
       while (--locksProcessed >= 0)
@@ -965,7 +965,7 @@ public class LockManager implements ILoc
             break;
           }
         }
-        catch (LCFException e)
+        catch (ACFException e)
         {
           ae = e;
         }
@@ -975,14 +975,14 @@ public class LockManager implements ILoc
       {
         throw ae;
       }
-      if (ex instanceof LCFException)
+      if (ex instanceof ACFException)
       {
-        throw (LCFException)ex;
+        throw (ACFException)ex;
       }
       if (ex instanceof InterruptedException)
       {
         // It's InterruptedException
-        throw new LCFException("Interrupted",ex,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",ex,ACFException.INTERRUPTED);
       }
       if (!(ex instanceof Error))
       {
@@ -993,7 +993,7 @@ public class LockManager implements ILoc
   }
 
   public void enterLocksNoWait(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks)
-    throws LCFException, LockException
+    throws ACFException, LockException
   {
 
     if (Logging.lock.isDebugEnabled())
@@ -1046,7 +1046,7 @@ public class LockManager implements ILoc
           // Check for illegalities
           if ((ll.hasReadLock() || ll.hasNonExWriteLock()) && !ll.hasWriteLock())
           {
-            throw new LCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",LCFException.GENERAL_ERROR);
+            throw new ACFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ACFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -1077,7 +1077,7 @@ public class LockManager implements ILoc
           // Check for illegalities
           if (ll.hasReadLock() && !(ll.hasNonExWriteLock() || ll.hasWriteLock()))
           {
-            throw new LCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",LCFException.GENERAL_ERROR);
+            throw new ACFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ACFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -1137,7 +1137,7 @@ public class LockManager implements ILoc
     catch (Throwable ex)
     {
       // No matter what, undo the locks we've taken
-      LCFException ae = null;
+      ACFException ae = null;
       int errno = 0;
 
       while (--locksProcessed >= 0)
@@ -1160,7 +1160,7 @@ public class LockManager implements ILoc
             break;
           }
         }
-        catch (LCFException e)
+        catch (ACFException e)
         {
           ae = e;
         }
@@ -1170,9 +1170,9 @@ public class LockManager implements ILoc
       {
         throw ae;
       }
-      if (ex instanceof LCFException)
+      if (ex instanceof ACFException)
       {
-        throw (LCFException)ex;
+        throw (ACFException)ex;
       }
       if (ex instanceof LockException || ex instanceof LocalLockException)
       {
@@ -1182,7 +1182,7 @@ public class LockManager implements ILoc
       }
       if (ex instanceof InterruptedException)
       {
-        throw new LCFException("Interrupted",ex,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",ex,ACFException.INTERRUPTED);
       }
       if (!(ex instanceof Error))
       {
@@ -1197,11 +1197,11 @@ public class LockManager implements ILoc
   /** Leave multiple locks
   */
   public void leaveLocks(String[] readLocks, String[] writeNonExLocks, String[] writeLocks)
-    throws LCFException
+    throws ACFException
   {
     LockDescription[] lds = getSortedUniqueLocks(readLocks,writeNonExLocks,writeLocks);
     // Free them all... one at a time is fine
-    LCFException ae = null;
+    ACFException ae = null;
     int i = lds.length;
     while (--i >= 0)
     {
@@ -1223,7 +1223,7 @@ public class LockManager implements ILoc
           break;
         }
       }
-      catch (LCFException e)
+      catch (ACFException e)
       {
         ae = e;
       }
@@ -1241,7 +1241,7 @@ public class LockManager implements ILoc
   * section at a time.
   */
   public void enterReadCriticalSection(String sectionKey)
-    throws LCFException
+    throws ACFException
   {
     LocalLock ll = getLocalSection(sectionKey);
 
@@ -1264,7 +1264,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -1280,7 +1280,7 @@ public class LockManager implements ILoc
   * section at a time.
   */
   public void leaveReadCriticalSection(String sectionKey)
-    throws LCFException
+    throws ACFException
   {
     LocalLock ll = getLocalSection(sectionKey);
 
@@ -1301,17 +1301,17 @@ public class LockManager implements ILoc
           try
           {
             lo.leaveReadLock();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
           catch (InterruptedException e2)
           {
             ll.incrementReadLocks();
-            throw new LCFException("Interrupted",e2,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e2,ACFException.INTERRUPTED);
           }
           catch (ExpiredObjectException e2)
           {
             ll.incrementReadLocks();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
         }
         catch (ExpiredObjectException e)
@@ -1330,7 +1330,7 @@ public class LockManager implements ILoc
   * section at a time.
   */
   public void enterNonExWriteCriticalSection(String sectionKey)
-    throws LCFException
+    throws ACFException
   {
     LocalLock ll = getLocalSection(sectionKey);
 
@@ -1346,7 +1346,7 @@ public class LockManager implements ILoc
     // Check for illegalities
     if (ll.hasReadLock())
     {
-      throw new LCFException("Illegal lock sequence: NonExWrite critical section can't be within read critical section",LCFException.GENERAL_ERROR);
+      throw new ACFException("Illegal lock sequence: NonExWrite critical section can't be within read critical section",ACFException.GENERAL_ERROR);
     }
 
     // We don't own a local non-ex write lock.  Get one.  The global lock will need
@@ -1361,7 +1361,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -1377,7 +1377,7 @@ public class LockManager implements ILoc
   * section at a time.
   */
   public void leaveNonExWriteCriticalSection(String sectionKey)
-    throws LCFException
+    throws ACFException
   {
     LocalLock ll = getLocalSection(sectionKey);
 
@@ -1401,17 +1401,17 @@ public class LockManager implements ILoc
           try
           {
             lo.leaveNonExWriteLock();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
           catch (InterruptedException e2)
           {
             ll.incrementNonExWriteLocks();
-            throw new LCFException("Interrupted",e2,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e2,ACFException.INTERRUPTED);
           }
           catch (ExpiredObjectException e2)
           {
             ll.incrementNonExWriteLocks();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
         }
         catch (ExpiredObjectException e)
@@ -1430,7 +1430,7 @@ public class LockManager implements ILoc
   * section at a time.
   */
   public void enterWriteCriticalSection(String sectionKey)
-    throws LCFException
+    throws ACFException
   {
     LocalLock ll = getLocalSection(sectionKey);
 
@@ -1445,7 +1445,7 @@ public class LockManager implements ILoc
     // Check for illegalities
     if (ll.hasReadLock() || ll.hasNonExWriteLock())
     {
-      throw new LCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",LCFException.GENERAL_ERROR);
+      throw new ACFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ACFException.GENERAL_ERROR);
     }
 
     // We don't own a local write lock.  Get one.  The global lock will need
@@ -1461,7 +1461,7 @@ public class LockManager implements ILoc
       }
       catch (InterruptedException e)
       {
-        throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
       }
       catch (ExpiredObjectException e)
       {
@@ -1478,7 +1478,7 @@ public class LockManager implements ILoc
   * section at a time.
   */
   public void leaveWriteCriticalSection(String sectionKey)
-    throws LCFException
+    throws ACFException
   {
     LocalLock ll = getLocalSection(sectionKey);
 
@@ -1499,17 +1499,17 @@ public class LockManager implements ILoc
           try
           {
             lo.leaveWriteLock();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
           catch (InterruptedException e2)
           {
             ll.incrementWriteLocks();
-            throw new LCFException("Interrupted",e2,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e2,ACFException.INTERRUPTED);
           }
           catch (ExpiredObjectException e2)
           {
             ll.incrementWriteLocks();
-            throw new LCFException("Interrupted",e,LCFException.INTERRUPTED);
+            throw new ACFException("Interrupted",e,ACFException.INTERRUPTED);
           }
         }
         catch (ExpiredObjectException e)
@@ -1528,7 +1528,7 @@ public class LockManager implements ILoc
   *@param writeSectionKeys is an array of write section descriptors, or null if there are none desired.
   */
   public void enterCriticalSections(String[] readSectionKeys, String[] nonExSectionKeys, String[] writeSectionKeys)
-    throws LCFException
+    throws ACFException
   {
     // Sort the locks.  This improves the chances of making it through the locking process without
     // contention!
@@ -1549,7 +1549,7 @@ public class LockManager implements ILoc
           // Check for illegalities
           if ((ll.hasReadLock() || ll.hasNonExWriteLock()) && !ll.hasWriteLock())
           {
-            throw new LCFException("Illegal lock sequence: Write critical section can't be within read critical section or non-ex write critical section",LCFException.GENERAL_ERROR);
+            throw new ACFException("Illegal lock sequence: Write critical section can't be within read critical section or non-ex write critical section",ACFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -1577,7 +1577,7 @@ public class LockManager implements ILoc
           // Check for illegalities
           if (ll.hasReadLock() && !(ll.hasNonExWriteLock() || ll.hasWriteLock()))
           {
-            throw new LCFException("Illegal lock sequence: NonExWrite critical section can't be within read critical section",LCFException.GENERAL_ERROR);
+            throw new ACFException("Illegal lock sequence: NonExWrite critical section can't be within read critical section",ACFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -1630,7 +1630,7 @@ public class LockManager implements ILoc
     catch (Throwable ex)
     {
       // No matter what, undo the locks we've taken
-      LCFException ae = null;
+      ACFException ae = null;
       int errno = 0;
 
       while (--locksProcessed >= 0)
@@ -1653,7 +1653,7 @@ public class LockManager implements ILoc
             break;
           }
         }
-        catch (LCFException e)
+        catch (ACFException e)
         {
           ae = e;
         }
@@ -1663,14 +1663,14 @@ public class LockManager implements ILoc
       {
         throw ae;
       }
-      if (ex instanceof LCFException)
+      if (ex instanceof ACFException)
       {
-        throw (LCFException)ex;
+        throw (ACFException)ex;
       }
       if (ex instanceof InterruptedException)
       {
         // It's InterruptedException
-        throw new LCFException("Interrupted",ex,LCFException.INTERRUPTED);
+        throw new ACFException("Interrupted",ex,ACFException.INTERRUPTED);
       }
       if (!(ex instanceof Error))
       {
@@ -1686,11 +1686,11 @@ public class LockManager implements ILoc
   *@param writeSectionKeys is an array of write section descriptors, or null if there are none desired.
   */
   public void leaveCriticalSections(String[] readSectionKeys, String[] nonExSectionKeys, String[] writeSectionKeys)
-    throws LCFException
+    throws ACFException
   {
     LockDescription[] lds = getSortedUniqueLocks(readSectionKeys,nonExSectionKeys,writeSectionKeys);
     // Free them all... one at a time is fine
-    LCFException ae = null;
+    ACFException ae = null;
     int i = lds.length;
     while (--i >= 0)
     {
@@ -1712,7 +1712,7 @@ public class LockManager implements ILoc
           break;
         }
       }
-      catch (LCFException e)
+      catch (ACFException e)
       {
         ae = e;
       }

Modified: incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockObject.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockObject.java?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockObject.java (original)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/lockmanager/LockObject.java Mon Aug 23 18:08:32 2010
@@ -19,7 +19,7 @@
 package org.apache.acf.core.lockmanager;
 
 import org.apache.acf.core.interfaces.*;
-import org.apache.acf.core.system.LCF;
+import org.apache.acf.core.system.ACF;
 import org.apache.acf.core.system.Logging;
 import java.io.*;
 
@@ -77,7 +77,7 @@ public class LockObject
 
   private static String createFileName(Object lockKey)
   {
-    return "lock-"+LCF.safeFileName(lockKey.toString());
+    return "lock-"+ACF.safeFileName(lockKey.toString());
   }
 
   /** This method WILL NOT BE CALLED UNLESS we are actually committing a write lock for the
@@ -116,7 +116,7 @@ public class LockObject
       catch (LockException le2)
       {
         // Cross JVM lock; sleep!
-        LCF.sleep(10);
+        ACF.sleep(10);
       }
     }
   }
@@ -220,7 +220,7 @@ public class LockObject
       }
       catch (LockException le)
       {
-        LCF.sleep(10);
+        ACF.sleep(10);
         // Loop around
       }
     }
@@ -257,7 +257,7 @@ public class LockObject
       catch (LockException le2)
       {
         // Cross JVM lock; sleep!
-        LCF.sleep(10);
+        ACF.sleep(10);
       }
     }
   }
@@ -373,7 +373,7 @@ public class LockObject
       }
       catch (LockException le)
       {
-        LCF.sleep(10);
+        ACF.sleep(10);
         // Loop around
       }
     }
@@ -412,7 +412,7 @@ public class LockObject
       }
       catch (LockException le)
       {
-        LCF.sleep(10);
+        ACF.sleep(10);
         // Loop around
       }
     }
@@ -531,7 +531,7 @@ public class LockObject
       }
       catch (LockException le)
       {
-        LCF.sleep(10);
+        ACF.sleep(10);
         // Loop around
       }
     }
@@ -567,7 +567,7 @@ public class LockObject
           e.printStackTrace();
         }
         // Winnt sometimes throws an exception when you can't do the lock
-        LCF.sleep(100);
+        ACF.sleep(100);
         continue;
       }
     }
@@ -610,7 +610,7 @@ public class LockObject
           e.printStackTrace();
         }
         ie = e;
-        LCF.sleep(100);
+        ACF.sleep(100);
         continue;
       }
       catch (RuntimeException e)
@@ -629,7 +629,7 @@ public class LockObject
           e.printStackTrace();
         }
         ie = e;
-        LCF.sleep(100);
+        ACF.sleep(100);
         continue;
       }
     }

Added: incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACF.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACF.java?rev=988237&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACF.java (added)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACF.java Mon Aug 23 18:08:32 2010
@@ -0,0 +1,1270 @@
+/* $Id: ACF.java 960994 2010-07-06 19:45:53Z kwright $ */
+
+/**
+* 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.acf.core.system;
+
+import org.apache.acf.core.interfaces.*;
+import java.io.*;
+import java.util.*;
+import java.security.MessageDigest;
+
+public class ACF
+{
+  public static final String _rcsid = "@(#)$Id: ACF.java 960994 2010-07-06 19:45:53Z kwright $";
+
+  // Configuration XML node names and attribute names
+  public static final String NODE_PROPERTY = "property";
+  public static final String ATTRIBUTE_NAME = "name";
+  public static final String ATTRIBUTE_VALUE = "value";
+  public static final String NODE_LIBDIR = "libdir";
+  public static final String ATTRIBUTE_PATH = "path";
+  
+  // "Working directory"
+  
+  /** This is the working directory file object. */
+  protected static File workingDirectory = null;
+  
+  // Class loader
+  
+  /** The object that manages ACF plugin class loading.  This is initialized when the initialize method is called. */
+  protected static ACFResourceLoader resourceLoader = null;
+
+  // Shutdown hooks
+  /** Temporary file collector */
+  protected static FileTrack tracker = null;
+  /** Database handle cleanup */
+  protected static DatabaseShutdown dbShutdown = null;
+  
+  /** Array of cleanup hooks (for managing shutdown) */
+  protected static ArrayList cleanupHooks = new ArrayList(); 
+  
+  /** Shutdown thread */
+  protected static Thread shutdownThread;
+  /** Static initializer for setting up shutdown thread */
+  static
+  {
+    shutdownThread = new ShutdownThread();
+    try
+    {
+      Runtime.getRuntime().addShutdownHook(shutdownThread);
+    }
+    catch (Exception e)
+    {
+      // Guess we can't do it - dump a trace and continue
+      e.printStackTrace();
+    }
+    catch (Error e)
+    {
+      e.printStackTrace();
+    }
+  }
+  
+  // Flag indicating whether system initialized or not, and synchronizer to protect that flag.
+  protected static boolean isInitialized = false;
+  protected static boolean alreadyClosed = false;
+  protected static Integer initializeFlagLock = new Integer(0);
+
+  // Local member variables
+  protected static String masterDatabaseName = null;
+  protected static String masterDatabaseUsername = null;
+  protected static String masterDatabasePassword = null;
+  protected static ACFConfiguration localConfiguration = null;
+  protected static Map localProperties = null;
+  protected static long propertyFilelastMod = -1L;
+  protected static String propertyFilePath = null;
+
+  protected static final String applicationName = "lcf";
+
+  // System property names
+  public static final String lcfConfigFileProperty = "org.apache.acf.configfile";
+
+  // System property/config file property names
+  
+  // Database access properties
+  /** Database name property */
+  public static final String masterDatabaseNameProperty = "org.apache.acf.database.name";
+  /** Database user name property */
+  public static final String masterDatabaseUsernameProperty = "org.apache.acf.database.username";
+  /** Database password property */
+  public static final String masterDatabasePasswordProperty = "org.apache.acf.database.password";
+
+  // Database connection pooling properties
+  /** Maximum open database handles property */
+  public static final String databaseHandleMaxcountProperty = "org.apache.acf.database.maxhandles";
+  /** Database handle timeout property */
+  public static final String databaseHandleTimeoutProperty = "org.apache.acf.database.handletimeout";
+
+  // Log configuration properties
+  /** Location of log configuration file */
+  public static final String logConfigFileProperty = "org.apache.acf.logconfigfile";
+  
+  // Implementation class properties
+  /** Lock manager implementation class */
+  public static final String lockManagerImplementation = "org.apache.acf.lockmanagerclass";
+  /** Database implementation class */
+  public static final String databaseImplementation = "org.apache.acf.databaseimplementationclass";
+  
+  // The following are system integration properties
+  /** Script to invoke when configuration changes, if any */
+  public static final String configSignalCommandProperty = "org.apache.acf.configuration.change.command";
+  /** File to look for to block access to UI during database maintenance */
+  public static final String maintenanceFileSignalProperty = "org.apache.acf.database.maintenanceflag";
+
+  /** Initialize environment.
+  */
+  public static void initializeEnvironment()
+    throws ACFException
+  {
+    synchronized (initializeFlagLock)
+    {
+      if (isInitialized)
+        return;
+
+      try
+      {
+        
+        // Get system properties
+        java.util.Properties props = System.getProperties();
+        // First, look for a define that might indicate where to look
+      
+        propertyFilePath = (String)props.get(lcfConfigFileProperty);
+        if (propertyFilePath == null)
+        {
+          System.err.println("Couldn't find "+lcfConfigFileProperty+" property; using default");
+          String configPath = (String)props.get("user.home") + "/"+applicationName;
+          configPath = configPath.replace('\\', '/');
+          propertyFilePath = new File(configPath,"properties.xml").toString();
+        }
+
+        // Initialize working directory.  We cannot use the actual system cwd, because different ACF processes will have different ones.
+        // So, instead, we use the location of the property file itself, and call that the "working directory".
+        workingDirectory = new File(propertyFilePath).getAbsoluteFile().getParentFile();
+
+        // Initialize resource loader.
+        resourceLoader = new ACFResourceLoader(Thread.currentThread().getContextClassLoader());
+        
+        // Read configuration!
+        localConfiguration = new ACFConfiguration();
+        localProperties = new HashMap();
+        checkProperties();
+
+        File logConfigFile = getFileProperty(logConfigFileProperty);
+        if (logConfigFile == null)
+        {
+          System.err.println("Couldn't find "+logConfigFileProperty+" property; using default");
+          String configPath = (String)props.get("user.home") + "/"+applicationName;
+          configPath = configPath.replace('\\', '/');
+          logConfigFile = new File(configPath,"logging.ini");
+        }
+
+        Logging.initializeLoggingSystem(logConfigFile);
+
+        // Set up local loggers
+        Logging.initializeLoggers();
+        Logging.setLogLevels();
+
+        masterDatabaseName = getProperty(masterDatabaseNameProperty);
+        if (masterDatabaseName == null)
+          masterDatabaseName = "dbname";
+        masterDatabaseUsername = getProperty(masterDatabaseUsernameProperty);
+        if (masterDatabaseUsername == null)
+          masterDatabaseUsername = "lcf";
+        masterDatabasePassword = getProperty(masterDatabasePasswordProperty);
+        if (masterDatabasePassword == null)
+          masterDatabasePassword = "local_pg_passwd";
+
+        // Register the file tracker for cleanup on shutdown
+	tracker = new FileTrack();
+        addShutdownHook(tracker);
+        // Register the database cleanup hook
+        addShutdownHook(new DatabaseShutdown());
+
+        // Open the database.  Done once per JVM.
+        IThreadContext threadcontext = ThreadContextFactory.make();
+        DBInterfaceFactory.make(threadcontext,masterDatabaseName,masterDatabaseUsername,masterDatabasePassword).openDatabase();
+        isInitialized = true;
+      }
+      catch (ACFException e)
+      {
+        throw new ACFException("Initialization failed: "+e.getMessage(),e,ACFException.SETUP_ERROR);
+      }
+    }
+
+  }
+
+  /** Reloads properties as needed.
+  */
+  public static final void checkProperties()
+    throws ACFException
+  {
+    File f = new File(propertyFilePath);    // for re-read
+    try
+    {
+      if (propertyFilelastMod != f.lastModified())
+      {
+        InputStream is = new FileInputStream(f);
+        try
+        {
+          localConfiguration.fromXML(is);
+	  System.err.println("Configuration file successfully read");
+          propertyFilelastMod = f.lastModified();
+        }
+        finally
+        {
+          is.close();
+        }
+      }
+      else
+      {
+	System.err.println("Configuration file not read because it didn't change");
+        return;
+      }
+    }
+    catch (Exception e)
+    {
+      throw new ACFException("Could not read configuration file '"+f.toString()+"'",e);
+    }
+    
+    // For convenience, post-process all "property" nodes so that we have a semblance of the earlier name/value pairs available, by default.
+    // e.g. <property name= value=/>
+    localProperties.clear();
+    ArrayList libDirs = new ArrayList();
+    int i = 0;
+    while (i < localConfiguration.getChildCount())
+    {
+      ConfigurationNode cn = localConfiguration.findChild(i++);
+      if (cn.getType().equals(NODE_PROPERTY))
+      {
+        String name = cn.getAttributeValue(ATTRIBUTE_NAME);
+        String value = cn.getAttributeValue(ATTRIBUTE_VALUE);
+        if (name == null)
+          throw new ACFException("Node type '"+NODE_PROPERTY+"' requires a '"+ATTRIBUTE_NAME+"' attribute");
+        localProperties.put(name,value);
+      }
+      else if (cn.getType().equals(NODE_LIBDIR))
+      {
+        String path = cn.getAttributeValue(ATTRIBUTE_PATH);
+        if (path == null)
+          throw new ACFException("Node type '"+NODE_LIBDIR+"' requires a '"+ATTRIBUTE_PATH+" attribute");
+        // What exactly should I do with this classpath information?  The classloader can be dynamically updated, but if I do that will everything work?
+        // I'm going to presume the answer is "yes" for now...
+        libDirs.add(resolvePath(path));
+      }
+    }
+    // Apply libdirs to the resource loader.
+    resourceLoader.setClassPath(libDirs);
+  }
+
+  /** Resolve a file path, possibly relative to ACF's concept of its "working directory".
+  *@param path is the path, to be calculated relative to the ACF "working directory".
+  *@return the resolved file.
+  */
+  public static File resolvePath(String path)
+  {
+    File r = new File(path);
+    return r.isAbsolute() ? r : new File(workingDirectory, path);
+  }
+
+  /** Read a (string) property, either from the system properties, or from the local configuration file.
+  *@param s is the property name.
+  *@return the property value, as a string.
+  */
+  public static String getProperty(String s)
+  {
+    String rval = System.getProperty(s);
+    if (rval == null)
+      rval = (String)localProperties.get(s);
+    return rval;
+  }
+
+  /** Read a File property, either from the system properties, or from the local configuration file.
+  * Relative file references are resolved according to the "working directory" for ACF.
+  */
+  public static File getFileProperty(String s)
+  {
+    String value = getProperty(s);
+    if (value == null)
+      return null;
+    return resolvePath(value);
+  }
+  
+  /** Attempt to make sure a path is a folder
+  * @param path
+  */
+  public static void ensureFolder(String path)
+    throws ACFException
+  {
+    try
+    {
+      File f = new File(path);
+      if (!f.isDirectory())
+      {
+        f.mkdirs();
+      }
+    }
+    catch (Exception e)
+    {
+      throw new ACFException("Can't make folder",e,ACFException.GENERAL_ERROR);
+    }
+  }
+
+  /** Delete a folder path.
+  *@param path is the folder path.
+  */
+  public static void deleteFolder(String path)
+  {
+    File directoryPath = new File(path);
+    recursiveDelete(directoryPath);
+  }
+
+  /** Recursive delete: for cleaning up company folder.
+  *@param directoryPath is the File describing the directory to be removed.
+  */
+  protected static void recursiveDelete(File directoryPath)
+  {
+    File[] children = directoryPath.listFiles();
+    if (children != null)
+    {
+      int i = 0;
+      while (i < children.length)
+      {
+        File x = children[i++];
+        if (x.isDirectory())
+          recursiveDelete(x);
+        else
+          x.delete();
+      }
+    }
+    directoryPath.delete();
+  }
+
+  /** Discover if a path is a folder
+  * @param path spec, 'unix' form mostly
+  */
+  public static boolean isFolder(String path)
+  {
+    File f = new File(path);
+    return f.isDirectory();
+  }
+
+  /** Convert a string into a safe, unique filename.
+  *@param value is the string.
+  *@return the file name.
+  */
+  public static String safeFileName(String value)
+  {
+    StringBuffer rval = new StringBuffer();
+    int i = 0;
+    while (i < value.length())
+    {
+      char x = value.charAt(i++);
+      if (x == '/' || x == '"' || x == '\\' || x == '|' || (x >= 0 && x < ' ') ||
+        x == '+' || x == ',' || x == ':' || x == ';' || x == '<' || x == '>' ||
+        x == '=' || x == '[' || x == ']' || x == '&')
+      {
+        // Stuff the character
+        rval.append("&").append(Integer.toString((int)x)).append("!");
+      }
+      else
+        rval.append(x);
+    }
+    return rval.toString();
+  }
+
+  /** Get the master database name.
+  *@return the master database name
+  */
+  public static String getMasterDatabaseName()
+  {
+    return masterDatabaseName;
+  }
+
+  /** Get the master database username.
+  *@return the master database username.
+  */
+  public static String getMasterDatabaseUsername()
+  {
+    return masterDatabaseUsername;
+  }
+
+  /** Get the master database password.
+  *@return the master database password.
+  */
+  public static String getMasterDatabasePassword()
+  {
+    return masterDatabasePassword;
+  }
+
+  /** Find a child database name given a company database instance and the child
+  * database identifier.
+  *@param companyDatabase is the company database.
+  *@param childDBIdentifier is the identifier.
+  *@return the child database name.
+  */
+  public static String getChildDatabaseName(IDBInterface companyDatabase, String childDBIdentifier)
+  {
+    return companyDatabase.getDatabaseName()+"_"+childDBIdentifier;
+  }
+
+  /** Perform standard hashing of a string
+  *  @param input is the string to hash.
+  *  @return the encrypted string.
+  *   */
+  public static String hash(String input)
+    throws ACFException
+  {
+    return encrypt(input);
+  }
+
+  /** Start creating a hash
+  */
+  public static MessageDigest startHash()
+    throws ACFException
+  {
+    try
+    {
+      return MessageDigest.getInstance("SHA");
+    }
+    catch (Exception e)
+    {
+      throw new ACFException("Couldn't encrypt: "+e.getMessage(),e,ACFException.GENERAL_ERROR);
+    }
+  }
+
+  /** Add to hash
+  */
+  public static void addToHash(MessageDigest digest, String input)
+    throws ACFException
+  {
+    try
+    {
+      byte[] inputBytes = input.getBytes("UTF-8");
+      digest.update(inputBytes);
+    }
+    catch (Exception e)
+    {
+      throw new ACFException("Couldn't encrypt: "+e.getMessage(),e,ACFException.GENERAL_ERROR);
+    }
+  }
+
+  /** Calculate final hash value
+  */
+  public static String getHashValue(MessageDigest digest)
+    throws ACFException
+  {
+    try
+    {
+      byte[] encryptedBytes = digest.digest();
+      StringBuffer rval = new StringBuffer();
+      int i = 0;
+      while (i < encryptedBytes.length)
+      {
+        byte x = encryptedBytes[i++];
+        rval.append(writeNibble((((int)x) >> 4) & 15));
+        rval.append(writeNibble(((int)x) & 15));
+      }
+      return rval.toString();
+    }
+    catch (Exception e)
+    {
+      throw new ACFException("Couldn't encrypt: "+e.getMessage(),e,ACFException.GENERAL_ERROR);
+    }
+  }
+
+  /** Perform standard one-way encryption of a string.
+  *@param input is the string to encrypt.
+  *@return the encrypted string.
+  */
+  public static String encrypt(String input)
+    throws ACFException
+  {
+    MessageDigest hash = startHash();
+    addToHash(hash,input);
+    return getHashValue(hash);
+  }
+
+  /** Encode a string in a reversible obfuscation.
+  *@param input is the input string.
+  *@return the output string.
+  */
+  public static String obfuscate(String input)
+    throws ACFException
+  {
+    try
+    {
+      if (input == null)
+        return null;
+      if (input.length() == 0)
+        return input;
+      // First, convert to binary
+      byte[] array = input.getBytes("UTF-8");
+      // Shift and xor
+      // We shift by some number not a multiple of 4.
+      // The resulting hexadecimal is then not a simple shift.
+      int i = 0;
+      int carryover = (((int)array[array.length-1]) & 0x1f);
+      while (i < array.length)
+      {
+        int x = (int)array[i];
+        int newCarryover = x & 0x1f;
+        x = ((x >> 5) & 0x7) + (carryover << 3);
+        carryover = newCarryover;
+        array[i++] = (byte)(x ^ 0x59);
+      }
+      // Now, convert to hex
+      StringBuffer rval = new StringBuffer();
+      i = 0;
+      while (i < array.length)
+      {
+        int x = (int)array[i++];
+        rval.append(writeNibble((x >> 4) & 0x0f));
+        rval.append(writeNibble(x & 0x0f));
+      }
+      return rval.toString();
+    }
+    catch (java.io.UnsupportedEncodingException e)
+    {
+      throw new ACFException("UTF-8 not supported",e,ACFException.GENERAL_ERROR);
+    }
+  }
+
+  /** Write a hex nibble.
+  *@param value is the value to write.
+  *@return the character.
+  */
+  protected static char writeNibble(int value)
+  {
+    if (value >= 10)
+      return (char)(value-10+'A');
+    else
+      return (char)(value+'0');
+  }
+
+  /** Decode a string encoded using the obfuscation
+  * technique.
+  *@param input is the input string.
+  *@return the decoded string.
+  */
+  public static String deobfuscate(String input)
+    throws ACFException
+  {
+    try
+    {
+      if (input == null)
+        return null;
+      if (input.length() == 0)
+        return input;
+
+      if ((input.length() >> 1) * 2 != input.length())
+        throw new ACFException("Decoding error",ACFException.GENERAL_ERROR);
+
+      byte[] bytes = new byte[input.length() >> 1];
+      int i = 0;
+      int j = 0;
+      while (i < input.length())
+      {
+        int x0 = readNibble(input.charAt(i++));
+        int x1 = readNibble(input.charAt(i++));
+        int x = (x0 << 4) + x1;
+        bytes[j++] = (byte)x;
+      }
+
+      // Process the array in reverse order
+      int carryover = ((((int)bytes[0]) ^ 0x59) >> 3) & 0x1f;
+      i = bytes.length;
+      while (i > 0)
+      {
+        i--;
+        int x = ((int)bytes[i]) ^ 0x59;
+        int newCarryover = (x >> 3) & 0x1f;
+        x = (x << 5) + carryover;
+        bytes[i] = (byte)x;
+        carryover = newCarryover;
+      }
+
+      // Convert from utf-8 to a string
+      return new String(bytes,"UTF-8");
+    }
+    catch (java.io.UnsupportedEncodingException e)
+    {
+      throw new ACFException("UTF-8 unsupported",e,ACFException.GENERAL_ERROR);
+    }
+  }
+
+  /** Read a hex nibble.
+  *@param value is the character.
+  *@return the value.
+  */
+  protected static int readNibble(char value)
+    throws ACFException
+  {
+    if (value >= 'A' && value <= 'F')
+      return (int)(value - 'A' + 10);
+    else if (value >= '0' && value <= '9')
+      return (int)(value - '0');
+    else
+      throw new ACFException("Bad hexadecimal value",ACFException.GENERAL_ERROR);
+  }
+
+
+  /** Install system database.
+  *@param threadcontext is the thread context.
+  *@param masterUsername is the master database user name.
+  *@param masterPassword is the master database password.
+  */
+  public static void createSystemDatabase(IThreadContext threadcontext, String masterUsername, String masterPassword)
+    throws ACFException
+  {
+    String databaseName = getMasterDatabaseName();
+    String databaseUsername = getMasterDatabaseUsername();
+    String databasePassword = getMasterDatabasePassword();
+
+    IDBInterface master = DBInterfaceFactory.make(threadcontext,databaseName,databaseUsername,databasePassword);
+    master.createUserAndDatabase(masterUsername,masterPassword,null);
+  }
+
+  /** Drop system database.
+  *@param threadcontext is the thread context.
+  *@param masterUsername is the master database user name.
+  *@param masterPassword is the master database password.
+  */
+  public static void dropSystemDatabase(IThreadContext threadcontext, String masterUsername, String masterPassword)
+    throws ACFException
+  {
+    String databaseName = getMasterDatabaseName();
+    String databaseUsername = getMasterDatabaseUsername();
+    String databasePassword = getMasterDatabasePassword();
+
+    IDBInterface master = DBInterfaceFactory.make(threadcontext,databaseName,databaseUsername,databasePassword);
+    master.dropUserAndDatabase(masterUsername,masterPassword,null);
+  }
+
+  /** Add a file to the tracking system. */
+  public static void addFile(File f)
+  {
+    tracker.addFile(f);
+  }
+
+  /** Use the tracking system to delete a file.  You MUST use this to
+  * delete any file that was added to the tracking system with addFile(). */
+  public static void deleteFile(File f)
+  {
+    tracker.deleteFile(f);
+  }
+
+  /** Check if maintenance is underway.
+  */
+  public static boolean checkMaintenanceUnderway()
+  {
+    String fileToCheck = getProperty(maintenanceFileSignalProperty);
+    if (fileToCheck != null && fileToCheck.length() > 0)
+    {
+      File f = new File(fileToCheck);
+      return f.exists();
+    }
+    return false;
+  }
+
+  /** Note configuration change.
+  */
+  public static void noteConfigurationChange()
+    throws ACFException
+  {
+    String configChangeSignalCommand = getProperty(configSignalCommandProperty);
+    if (configChangeSignalCommand == null || configChangeSignalCommand.length() == 0)
+      return;
+
+    // Do stuff to the file to note change.  This involves
+    // shelling out to the os and involving whatever is desired.
+
+    // We should try to convert the command into arguments.
+    ArrayList list = new ArrayList();
+    int currentIndex = 0;
+    while (currentIndex < configChangeSignalCommand.length())
+    {
+      // Suck up the leading whitespace
+      while (currentIndex < configChangeSignalCommand.length())
+      {
+        char x = configChangeSignalCommand.charAt(currentIndex);
+        if (x < 0 || x > ' ')
+          break;
+        currentIndex++;
+      }
+      StringBuffer argBuffer = new StringBuffer();
+      boolean isQuoted = false;
+      while (currentIndex < configChangeSignalCommand.length())
+      {
+        char x = configChangeSignalCommand.charAt(currentIndex);
+        if (isQuoted)
+        {
+          if (x == '"')
+          {
+            currentIndex++;
+            isQuoted = false;
+          }
+          else if (x == '\\')
+          {
+            currentIndex++;
+            if (currentIndex < configChangeSignalCommand.length())
+            {
+              x = configChangeSignalCommand.charAt(currentIndex);
+              argBuffer.append(x);
+            }
+            else
+              break;
+          }
+          else
+          {
+            currentIndex++;
+            argBuffer.append(x);
+          }
+        }
+        else
+        {
+          if (x == '"')
+          {
+            currentIndex++;
+            isQuoted = true;
+          }
+          else if (x == '\\')
+          {
+            currentIndex++;
+            if (currentIndex < configChangeSignalCommand.length())
+            {
+              x = configChangeSignalCommand.charAt(currentIndex);
+              argBuffer.append(x);
+            }
+            else
+              break;
+          }
+          else if (x >= 0 && x <= ' ')
+            break;
+          else
+          {
+            currentIndex++;
+            argBuffer.append(x);
+          }
+        }
+      }
+      list.add(argBuffer.toString());
+    }
+
+    // Set up for command invocation
+    String[] commandArray = new String[list.size()];
+    int i = 0;
+    while (i < commandArray.length)
+    {
+      commandArray[i] = (String)list.get(i);
+      i++;
+    }
+
+    if (commandArray.length == 0)
+      return;
+
+    String[] env = new String[0];
+    File dir = new File("/");
+
+    try
+    {
+      // Do the exec.
+      Process p = Runtime.getRuntime().exec(commandArray,env,dir);
+      try
+      {
+        // To make this truly "safe", we really ought to spin up a thread to handle both the standard error and the standard output streams - otherwise
+        // we run the risk of getting blocked here.  In practice, there's enough buffering in the OS to handle what we need right now.
+        int rval = p.waitFor();
+        if (rval != 0)
+        {
+          InputStream is = p.getErrorStream();
+          try
+          {
+            Reader r = new InputStreamReader(is);
+            try
+            {
+              BufferedReader br = new BufferedReader(r);
+              try
+              {
+                StringBuffer sb = new StringBuffer();
+                while (true)
+                {
+                  String value = br.readLine();
+                  if (value == null)
+                    break;
+                  sb.append(value).append("; ");
+                }
+                throw new ACFException("Shelled process '"+configChangeSignalCommand+"' failed with error "+Integer.toString(rval)+": "+sb.toString());
+              }
+              finally
+              {
+                br.close();
+              }
+            }
+            finally
+            {
+              r.close();
+            }
+          }
+          finally
+          {
+            is.close();
+          }
+        }
+      }
+      finally
+      {
+        p.destroy();
+      }
+    }
+    catch (InterruptedException e)
+    {
+      throw new ACFException("Process wait interrupted: "+e.getMessage(),e,ACFException.INTERRUPTED);
+    }
+    catch (InterruptedIOException e)
+    {
+      throw new ACFException("IO with subprocess interrupted: "+e.getMessage(),e,ACFException.INTERRUPTED);
+    }
+    catch (IOException e)
+    {
+      throw new ACFException("IO exception signalling change: "+e.getMessage(),e);
+    }
+  }
+
+  /** Use this method to sleep instead of Thread.sleep().  Thread.sleep() doesn't seem to work well when the system
+  * time is reset.
+  */
+  public static void sleep(long milliseconds)
+    throws InterruptedException
+  {
+    // Unfortunately we need to create an object for every time that we sleep
+    Integer x = new Integer(0);
+    synchronized (x)
+    {
+      x.wait(milliseconds);
+    }
+  }
+
+  /** Write a bunch of bytes to the output stream */
+  public static void writeBytes(OutputStream os, byte[] byteArray)
+    throws IOException
+  {
+    os.write(byteArray,0,byteArray.length);
+  }
+
+  /** Write a byte to an output stream */
+  public static void writeByte(OutputStream os, int byteValue)
+    throws IOException
+  {
+    writeBytes(os,new byte[]{(byte)byteValue});
+  }
+
+  /** Write a word to an output stream */
+  public static void writeWord(OutputStream os, int wordValue)
+    throws IOException
+  {
+    byte[] buffer = new byte[2];
+    buffer[0] = (byte)(wordValue & 0xff);
+    buffer[1] = (byte)((wordValue >>> 8) & 0xff);
+    writeBytes(os,buffer);
+  }
+
+  /** Write a dword to an output stream */
+  public static void writeDword(OutputStream os, int dwordValue)
+    throws IOException
+  {
+    if (dwordValue < 0)
+      throw new IllegalArgumentException("Attempt to use an unsigned operator to write a signed value");
+    writeSdword(os,dwordValue);
+  }
+
+  /** Write a signed dword to an output stream */
+  public static void writeSdword(OutputStream os, int dwordValue)
+    throws IOException
+  {
+    byte[] buffer = new byte[4];
+    buffer[0] = (byte)(dwordValue & 0xff);
+    buffer[1] = (byte)((dwordValue >>> 8) & 0xff);
+    buffer[2] = (byte)((dwordValue >>> 16) & 0xff);
+    buffer[3] = (byte)((dwordValue >>> 24) & 0xff);
+    writeBytes(os,buffer);
+  }
+
+  /** Write a Long to an output stream */
+  public static void writeLong(OutputStream os, Long longValue)
+    throws IOException
+  {
+    if (longValue == null)
+      writeByte(os,1);
+    else
+    {
+      writeByte(os,0);
+      long value = longValue.longValue();
+      byte[] buffer = new byte[8];
+      buffer[0] = (byte)(value & 0xff);
+      buffer[1] = (byte)(Long.rotateRight(value,8) & 0xff);
+      buffer[2] = (byte)(Long.rotateRight(value,16) & 0xff);
+      buffer[3] = (byte)(Long.rotateRight(value,24) & 0xff);
+      buffer[4] = (byte)(Long.rotateRight(value,32) & 0xff);
+      buffer[5] = (byte)(Long.rotateRight(value,40) & 0xff);
+      buffer[6] = (byte)(Long.rotateRight(value,48) & 0xff);
+      buffer[7] = (byte)(Long.rotateRight(value,56) & 0xff);
+      writeBytes(os,buffer);
+    }
+  }
+
+  /** Write a String to an output stream */
+  public static void writeString(OutputStream os, String stringValue)
+    throws IOException
+  {
+    byte[] characters;
+    if (stringValue == null)
+      characters = null;
+    else
+      characters = stringValue.getBytes("utf-8");
+    writeByteArray(os,characters);
+  }
+
+  /** Write a byte array to an output stream */
+  public static void writeByteArray(OutputStream os, byte[] byteArray)
+    throws IOException
+  {
+    if (byteArray == null)
+      writeSdword(os,-1);
+    else
+    {
+      writeSdword(os,byteArray.length);
+      writeBytes(os,byteArray);
+    }
+  }
+
+  /** Write a float value to an output stream */
+  public static void writefloat(OutputStream os, float floatValue)
+    throws IOException
+  {
+    writeSdword(os,Float.floatToIntBits(floatValue));
+  }
+
+  /** Read  bytes from the input stream into specified array. */
+  public static void readBytes(InputStream is, byte[] byteArray)
+    throws IOException
+  {
+    int amtSoFar = 0;
+    while (amtSoFar < byteArray.length)
+    {
+      int amt = is.read(byteArray,amtSoFar,byteArray.length-amtSoFar);
+      if (amt == -1)
+        throw new IOException("Unexpected EOF");
+      amtSoFar += amt;
+    }
+  }
+
+  /** Read a byte from an input stream */
+  public static int readByte(InputStream is)
+    throws IOException
+  {
+    byte[] inputArray = new byte[1];
+    readBytes(is,inputArray);
+    return ((int)inputArray[0]) & 0xff;
+  }
+
+  /** Read a word from an input stream */
+  public static int readWord(InputStream is)
+    throws IOException
+  {
+    byte[] inputArray = new byte[2];
+    readBytes(is,inputArray);
+    return (((int)inputArray[0]) & 0xff) +
+      ((((int)inputArray[1]) & 0xff) << 8);
+  }
+
+  /** Read a dword from an input stream */
+  public static int readDword(InputStream is)
+    throws IOException
+  {
+    byte[] inputArray = new byte[4];
+    readBytes(is,inputArray);
+    return (((int)inputArray[0]) & 0xff) +
+      ((((int)inputArray[1]) & 0xff) << 8) +
+      ((((int)inputArray[2]) & 0xff) << 16) +
+      ((((int)inputArray[3]) & 0xff) << 24);
+  }
+
+  /** Read a signed dword from an input stream */
+  public static int readSdword(InputStream is)
+    throws IOException
+  {
+    byte[] inputArray = new byte[4];
+    readBytes(is,inputArray);
+    return (((int)inputArray[0]) & 0xff) +
+      ((((int)inputArray[1]) & 0xff) << 8) +
+      ((((int)inputArray[2]) & 0xff) << 16) +
+      (((int)inputArray[3]) << 24);
+  }
+
+  /** Read a Long from an input stream */
+  public static Long readLong(InputStream is)
+    throws IOException
+  {
+    int value = readByte(is);
+    if (value == 1)
+      return null;
+    byte[] inputArray = new byte[8];
+    readBytes(is,inputArray);
+    return new Long((long)(((int)inputArray[0]) & 0xff) +
+      Long.rotateLeft(((int)inputArray[1]) & 0xff, 8) +
+      Long.rotateLeft(((int)inputArray[2]) & 0xff, 16) +
+      Long.rotateLeft(((int)inputArray[3]) & 0xff, 24) +
+      Long.rotateLeft(((int)inputArray[4]) & 0xff, 32) +
+      Long.rotateLeft(((int)inputArray[5]) & 0xff, 40) +
+      Long.rotateLeft(((int)inputArray[6]) & 0xff, 48) +
+      Long.rotateLeft(((int)inputArray[7]) & 0xff, 56));
+
+  }
+
+  /** Read a String from an input stream */
+  public static String readString(InputStream is)
+    throws IOException
+  {
+    byte[] bytes = readByteArray(is);
+    if (bytes == null)
+      return null;
+    return new String(bytes,"utf-8");
+  }
+
+  /** Read a byte array from an input stream */
+  public static byte[] readByteArray(InputStream is)
+    throws IOException
+  {
+    int length = readSdword(is);
+    if (length == -1)
+      return null;
+    byte[] byteArray = new byte[length];
+    readBytes(is,byteArray);
+    return byteArray;
+  }
+
+  /** Read a float value from an input stream */
+  public static float readfloat(InputStream os)
+    throws IOException
+  {
+    return Float.intBitsToFloat(readSdword(os));
+  }
+
+  /** Add a cleanup hook to the list.  These hooks will be evaluated in the
+  * reverse order than the order in which they were added.
+  *@param hook is the shutdown hook that needs to be added to the sequence.
+  */
+  public static void addShutdownHook(IShutdownHook hook)
+  {
+    synchronized (cleanupHooks)
+    {
+      cleanupHooks.add(hook);
+    }
+  }
+  
+  
+  /** Locate a class in the configuration-determined class path.  This method
+  * is designed for loading plugin classes, and their downstream dependents.
+  */
+  public static Class findClass(String cname)
+    throws ClassNotFoundException,ACFException
+  {
+    return resourceLoader.findClass(cname);
+  }
+  
+  /** Perform system shutdown, using the registered shutdown hooks. */
+  protected static void cleanUpSystem()
+  {
+    // It needs to call all registered shutdown hooks, in reverse order.
+    // A failure of any one hook should cause the cleanup to continue, after a logging attempt is made.
+    synchronized (cleanupHooks)
+    {
+      int i = cleanupHooks.size();
+      while (i > 0)
+      {
+	i--;
+	IShutdownHook hook = (IShutdownHook)cleanupHooks.get(i);
+	try
+	{
+	  hook.doCleanup();
+	}
+	catch (ACFException e)
+	{
+	  Logging.root.warn("Error during system shutdown: "+e.getMessage(),e);
+	}
+      }
+      cleanupHooks.clear();
+    }
+  }
+
+  /** Class that tracks files that need to be cleaned up on exit */
+  protected static class FileTrack implements IShutdownHook
+  {
+    /** Key and value are both File objects */
+    protected HashMap filesToDelete = new HashMap();
+
+    /** Constructor */
+    public FileTrack()
+    {
+    }
+
+    /** Add a file to track */
+    public synchronized void addFile(File f)
+    {
+      filesToDelete.put(f,f);
+    }
+
+    /** Delete a file */
+    public synchronized void deleteFile(File f)
+    {
+      f.delete();
+      filesToDelete.remove(f);
+    }
+
+    /** Delete all remaining files */
+    public void doCleanup()
+      throws ACFException
+    {
+      synchronized (this)
+      {
+	Iterator iter = filesToDelete.keySet().iterator();
+	while (iter.hasNext())
+	{
+	  File f = (File)iter.next();
+	  f.delete();
+	}
+	filesToDelete.clear();
+      }
+    }
+
+    /** Finalizer, which is designed to catch class unloading that tomcat 5.5 does.
+    */
+    protected void finalize()
+      throws Throwable
+    {
+      try
+      {
+        doCleanup();
+      }
+      finally
+      {
+        super.finalize();
+      }
+    }
+
+  }
+
+  /** Class that cleans up database handles on exit */
+  protected static class DatabaseShutdown implements IShutdownHook
+  {
+    public DatabaseShutdown()
+    {
+    }
+    
+    public void doCleanup()
+      throws ACFException
+    {
+      // Clean up the database handles
+      Thread t = new DatabaseConnectionReleaseThread();
+      t.start();
+      try
+      {
+        // Wait 15 seconds for database cleanup to finish.  If we haven't managed to close database connections by then, we give up and just exit.
+        t.join(15000L);
+      }
+      catch (InterruptedException e)
+      {
+      }
+      closeDatabase();
+    }
+    
+    protected void closeDatabase()
+      throws ACFException
+    {
+      synchronized (initializeFlagLock)
+      {
+        if (isInitialized && !alreadyClosed)
+        {
+          IThreadContext threadcontext = ThreadContextFactory.make();
+          
+          String databaseName = getMasterDatabaseName();
+          String databaseUsername = getMasterDatabaseUsername();
+          String databasePassword = getMasterDatabasePassword();
+
+          DBInterfaceFactory.make(threadcontext,databaseName,databaseUsername,databasePassword).closeDatabase();
+          alreadyClosed = true;
+        }
+      }
+    }
+    
+    /** Finalizer, which is designed to catch class unloading that tomcat 5.5 does.
+    */
+    protected void finalize()
+      throws Throwable
+    {
+      try
+      {
+        // The database handle cleanup is handled inside the finalizers for the pools that hold onto connections.
+        closeDatabase();
+      }
+      finally
+      {
+        super.finalize();
+      }
+    }
+
+  }
+  
+  /** Finisher thread, to be registered with the runtime */
+  protected static class ShutdownThread extends Thread
+  {
+    /** Constructor.
+    */
+    public ShutdownThread()
+    {
+      super();
+      setName("Shutdown thread");
+    }
+
+    public void run()
+    {
+      // This thread is run at shutdown time.
+      cleanUpSystem();
+    }
+  }
+
+  /** The thread that actually releases database connections
+  */
+  protected static class DatabaseConnectionReleaseThread extends Thread
+  {
+    /** Constructor. */
+    public DatabaseConnectionReleaseThread()
+    {
+      super();
+      setName("Database connection release thread");
+      // May be abandoned if it takes too long
+      setDaemon(true);
+    }
+
+    public void run()
+    {
+      // Clean up the database handles
+      org.apache.acf.core.database.ConnectionFactory.releaseAll();
+    }
+  }
+}
+

Added: incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFConfiguration.java?rev=988237&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFConfiguration.java (added)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFConfiguration.java Mon Aug 23 18:08:32 2010
@@ -0,0 +1,56 @@
+/* $Id: ACFConfiguration.java 964702 2010-07-16 07:45:44Z kwright $ */
+
+/**
+* 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.acf.core.system;
+
+import org.apache.acf.core.interfaces.*;
+import java.util.*;
+import java.io.*;
+
+/** This class represents the configuration data read from the main ACF configuration
+* XML file.
+*/
+public class ACFConfiguration extends Configuration
+{
+  public static final String _rcsid = "@(#)$Id: ACFConfiguration.java 964702 2010-07-16 07:45:44Z kwright $";
+
+  /** Constructor.
+  */
+  public ACFConfiguration()
+  {
+    super("configuration");
+  }
+
+  /** Construct from XML.
+  *@param xmlStream is the input XML stream.
+  */
+  public ACFConfiguration(InputStream xmlStream)
+    throws ACFException
+  {
+    super("configuration");
+    fromXML(xmlStream);
+  }
+
+  /** Create a new object of the appropriate class.
+  */
+  protected Configuration createNew()
+  {
+    return new ACFConfiguration();
+  }
+  
+}

Added: incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFResourceLoader.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFResourceLoader.java?rev=988237&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFResourceLoader.java (added)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/ACFResourceLoader.java Mon Aug 23 18:08:32 2010
@@ -0,0 +1,185 @@
+/**
+ * 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.acf.core.system;
+
+import org.apache.acf.core.interfaces.*;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.MalformedURLException;
+import java.util.*;
+import java.io.*;
+
+/** An instance of this class is capable of minting URLClassLoader objects on
+* demand, for the purpose of loading plugins.
+*/
+public class ACFResourceLoader
+{
+  public static final String _rcsid = "@(#)$Id: ACFResourceLoader.java 960994 2010-07-06 19:45:53Z kwright $";
+
+  /** The parent class loader */
+  protected ClassLoader parent;
+  /** The class loader we're caching */
+  protected ClassLoader classLoader = null;
+  /** The current 'classpath' - a list of File objects */
+  protected ArrayList currentClasspath = new ArrayList();
+  
+  /** Construct a resource manager.
+  *@param parent is the parent class loader.
+  */
+  public ACFResourceLoader(ClassLoader parent)
+    throws ACFException
+  {
+    this.parent = parent;
+  }
+
+  /** Set the classpath to a given list of libdirs.
+  *@param libdirList is an arraylist of File objects, each representing a directory.
+  */
+  public synchronized void setClassPath(ArrayList libdirList)
+    throws ACFException
+  {
+    if (currentClasspath.size() > 0)
+    {
+      currentClasspath.clear();
+      classLoader = null;
+    }
+    int i = 0;
+    while (i < libdirList.size())
+    {
+      File dir = (File)libdirList.get(i++);
+      addToClassPath(dir,null);
+    }
+  }
+  
+  /** Clear the class-search path.
+  */
+  public synchronized void clearClassPath()
+  {
+    if (currentClasspath.size() == 0)
+      return;
+    currentClasspath.clear();
+    classLoader = null;
+  }
+  
+  /** Add to the class-search path.
+  *@param file is the jar or class root.
+  */
+  public synchronized void addToClassPath(final File file)
+    throws ACFException
+  {
+    if (file.canRead())
+    {
+      addDirsToClassPath(new File[]{file.getParentFile()},
+        new FileFilter[]{new FileFilter() {
+          public boolean accept(final File pathname)
+          {
+            return pathname.equals(file);
+          }
+        } } );
+    }
+    else
+      throw new ACFException("Path '"+file.toString()+"' does not exist or is not readable");
+  }
+  
+  /** Add to the class-search path.
+  *@param dir is the directory to add.
+  *@param filter is the file filter to use on that directory.
+  */
+  public synchronized void addToClassPath(File dir, FileFilter filter)
+    throws ACFException
+  {
+    addDirsToClassPath(new File[]{dir}, new FileFilter[]{filter});
+  }
+
+  /** Get the specified class using the proper classloader.
+  *@param cname is the fully-qualified class name.
+  */
+  public synchronized Class findClass(String cname)
+    throws ClassNotFoundException,ACFException
+  {
+    if (classLoader == null)
+    {
+      // Mint a class loader on demand
+      if (currentClasspath.size() == 0)
+        classLoader = parent;
+      else
+      {
+        URL[] elements = new URL[currentClasspath.size()];
+        
+        for (int j = 0; j < currentClasspath.size(); j++)
+        {
+          try
+          {
+            URL element = ((File)currentClasspath.get(j)).toURI().normalize().toURL();
+            elements[j] = element;
+          }
+          catch (MalformedURLException e)
+          {
+            // Should never happen, but...
+            throw new ACFException(e.getMessage(),e);
+          }
+        }
+        classLoader = URLClassLoader.newInstance(elements, parent);
+      }
+    }
+    
+    // If we ever get this far, we have a classloader at least...
+    return Class.forName(cname,true,classLoader);
+  }
+
+  /** Add fully-resolved directories (with filters) to the current class path.
+  *@param baseList is the list of library directories.
+  *@param filterList is the corresponding list of filters.
+  */
+  protected void addDirsToClassPath(File[] baseList, FileFilter[] filterList)
+    throws ACFException
+  {
+    int i = 0;
+    while (i < baseList.length)
+    {
+      File base = baseList[i];
+      FileFilter filter;
+      if (filterList != null)
+        filter = filterList[i];
+      else
+        filter = null;
+      
+      if (base.canRead() && base.isDirectory())
+      {
+        File[] files = base.listFiles(filter);
+        
+        if (files != null && files.length > 0)
+        {
+          int j = 0;
+          while (j < files.length)
+          {
+            File file = files[j++];
+            currentClasspath.add(file);
+            // Invalidate the current classloader
+            classLoader = null;
+          }
+        }
+      }
+      else
+        throw new ACFException("Supposed directory '"+base.toString()+"' is either not a directory, or is unreadable.");
+      i++;
+    }
+  }
+  
+
+}

Modified: incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/Logging.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/Logging.java?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/Logging.java (original)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/acf/core/system/Logging.java Mon Aug 23 18:08:32 2010
@@ -72,7 +72,7 @@ public class Logging
     // Initialize the logger
     PropertyConfigurator.configure(logConfigFile.toString());
 
-    //System.err.println("LCF logger setup complete");
+    //System.err.println("ACF logger setup complete");
   }
 
   /** Set up loggers used by core package.
@@ -107,7 +107,7 @@ public class Logging
       String loggername = (String)e.getKey();
 
       // logger level
-      String level = LCF.getProperty(loggername);
+      String level = ACF.getProperty(loggername);
 
       Level loglevel = null;
       if (level != null && level.length() > 0)

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/adminDefaults.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/adminDefaults.jsp?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/adminDefaults.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/adminDefaults.jsp Mon Aug 23 18:08:32 2010
@@ -28,7 +28,7 @@
 %>
 
 <%
-	org.apache.acf.crawler.system.LCF.initializeEnvironment();
+	org.apache.acf.crawler.system.ACF.initializeEnvironment();
 %>
 
 <jsp:useBean id="thread" class="org.apache.acf.ui.beans.ThreadContext" scope="request"/>

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/adminHeaders.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/adminHeaders.jsp?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/adminHeaders.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/adminHeaders.jsp Mon Aug 23 18:08:32 2010
@@ -35,7 +35,7 @@ response.setContentType("text/html;chars
 <%@ page import="java.util.*" %>
 
 <%
-	org.apache.acf.crawler.system.LCF.initializeEnvironment();
+	org.apache.acf.crawler.system.ACF.initializeEnvironment();
 %>
 
 <jsp:useBean id="thread" class="org.apache.acf.ui.beans.ThreadContext" scope="request"/>

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/documentstatus.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/documentstatus.jsp?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/documentstatus.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/documentstatus.jsp Mon Aug 23 18:08:32 2010
@@ -20,7 +20,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-boolean maintenanceUnderway = org.apache.acf.crawler.system.LCF.checkMaintenanceUnderway();
+boolean maintenanceUnderway = org.apache.acf.crawler.system.ACF.checkMaintenanceUnderway();
 
 %>
 

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/editauthority.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/editauthority.jsp?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/editauthority.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/editauthority.jsp Mon Aug 23 18:08:32 2010
@@ -455,7 +455,7 @@
 
 <%
     }
-    catch (LCFException e)
+    catch (ACFException e)
     {
 	e.printStackTrace();
 	variableContext.setParameter("text",e.getMessage());

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/editconnection.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/editconnection.jsp?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/editconnection.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/editconnection.jsp Mon Aug 23 18:08:32 2010
@@ -608,7 +608,7 @@
 
 <%
     }
-    catch (LCFException e)
+    catch (ACFException e)
     {
 	e.printStackTrace();
 	variableContext.setParameter("text",e.getMessage());

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/editjob.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/editjob.jsp?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/editjob.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/editjob.jsp Mon Aug 23 18:08:32 2010
@@ -1176,7 +1176,7 @@
 
 <%
     }
-    catch (LCFException e)
+    catch (ACFException e)
     {
 	e.printStackTrace();
 	variableContext.setParameter("text",e.getMessage());

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/editoutput.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/editoutput.jsp?rev=988237&r1=988236&r2=988237&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/editoutput.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/editoutput.jsp Mon Aug 23 18:08:32 2010
@@ -456,7 +456,7 @@
 
 <%
     }
-    catch (LCFException e)
+    catch (ACFException e)
     {
 	e.printStackTrace();
 	variableContext.setParameter("text",e.getMessage());