Author: ogusakov
Date: Tue Sep  9 19:51:37 2008
New Revision: 693690

URL: http://svn.apache.org/viewvc?rev=693690&view=rev
Log:
added directory locking mechanism to be used in Local Repository

Added:
    
maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties
      - copied, changed from r693178, 
maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties
Removed:
    
maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties
Modified:
    
maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java
    
maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java
    
maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java

Modified: 
maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java?rev=693690&r1=693689&r2=693690&view=diff
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java
 (original)
+++ 
maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java
 Tue Sep  9 19:51:37 2008
@@ -104,7 +104,6 @@
 
     artifactBinary = File.createTempFile( "test-repo-writer", "bin" );
     FileUtil.writeRawData( artifactBinary, getClass().getResourceAsStream( 
"/maven-core-2.0.9.jar" ) );
-    
   }
   
   
@@ -113,11 +112,6 @@
   throws Exception
   {
     super.tearDown();
-//    if( nexusForkedAppBooter != null )
-//    {
-//      nexusForkedAppBooter.stop();
-//      nexusForkedAppBooter = null;
-//    }
   }
 
   public void testWriteArtifact()
@@ -226,4 +220,10 @@
     assertEquals( 7785, ap.length() );  
   }
   
+  public void testWriteContention()
+  throws Exception
+  {
+    
+  }
+  
 }

Modified: 
maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java?rev=693690&r1=693689&r2=693690&view=diff
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java
 (original)
+++ 
maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java
 Tue Sep  9 19:51:37 2008
@@ -5,11 +5,16 @@
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -44,6 +49,7 @@
  */
 public class FileUtil
 {
+  public static final String LOCK_FILE = ".lock";
   public static final String DEFAULT_CHARSET = "utf-8";
   public static final int    K = 1024;
   public static final int    DEFAULT_BUFFER_SIZE = 10 * K;
@@ -678,5 +684,57 @@
     }
   }
   
//---------------------------------------------------------------------------------------------------------------
+  /**
+   * try to acquire lock on specfied directory for <code>millis<code> millis
+   * 
+   * @param dir directory to lock
+   * @param millis how long to wait for the lock before surrendering
+   * @param sleepFor how long to sleep between attempts
+   * 
+   * @return obtained FileLock or null
+   * @throws IOException if there were problems obtaining the lock
+   */
+  public static boolean lockDir( String dir, long millis, long sleepFor )
+  throws IOException
+  {
+    File df = new File(dir);
+    if( !df.isDirectory() )
+      throw new IOException( _lang.getMessage( "file.is.not.directory", dir ) 
);
+    
+    File lock = new File(dir,LOCK_FILE);
+    long start = System.currentTimeMillis();
+    
+    for(;;)
+      try
+      {
+        if( lock.exists() )
+          throw new OverlappingFileLockException();
+        FileOutputStream fos = new FileOutputStream( lock );
+        fos.write( 32 );
+        fos.flush();
+        fos.close();
+
+        return true;
+      }
+      catch( OverlappingFileLockException le )
+      {
+        try { Thread.sleep( sleepFor ); } catch( InterruptedException e ){}
+        if( System.currentTimeMillis() - start > millis )
+          return false;
+      }
+  }
+  
//---------------------------------------------------------------------------------------------------------------
+  public static void unlockDir( String dir )
+  throws IOException
+  {
+    File df = new File(dir);
+    if( !df.isDirectory() )
+      throw new IOException( _lang.getMessage( "file.is.not.directory", dir ) 
);
+    
+    File lock = new File(dir,LOCK_FILE);
+    if( lock.exists() )
+      lock.delete();
+  }
+  
//---------------------------------------------------------------------------------------------------------------
   
//---------------------------------------------------------------------------------------------------------------
 }

Copied: 
maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties
 (from r693178, 
maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties)
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties?p2=maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties&p1=maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties&r1=693178&r2=693690&rev=693690&view=diff
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties
 (original)
+++ 
maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties
 Tue Sep  9 19:51:37 2008
@@ -16,3 +16,5 @@
 file.is.directory=File "{0}" is a folder and no recursive option is specified. 
Skipping ..
 no.mandatory.signature=Mandatory signature {1} does not exist for file {0}
 file.failed.verification=File {0} failed following verifications: {1}
+
+file.is.not.directory=Specified file {0} is not a directory

Modified: 
maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java?rev=693690&r1=693689&r2=693690&view=diff
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java
 (original)
+++ 
maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java
 Tue Sep  9 19:51:37 2008
@@ -2,6 +2,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.channels.FileLock;
 import java.util.HashSet;
 
 import junit.framework.TestCase;
@@ -147,4 +148,95 @@
     FileUtil.verify( b, vFacs, false, true );
   }
   
//----------------------------------------------------------------------------------------
+  public void testLock()
+  throws Exception
+  {
+    class TestThread1
+    extends Thread
+    {
+      boolean lock;
+      String dir;
+
+      public TestThread1( String dir )
+      {
+        this.dir = dir;
+      }
+      @Override
+      public void run()
+      {
+        try
+        {
+          lock = FileUtil.lockDir( dir, 1000L, 100L );
+          assertTrue( lock );
+          System.out.println("Thread1: lock "+dir+" obtained");
+          
+          try { sleep( 2000L ); } catch( InterruptedException e ) {}
+          System.out.println("Thread1: slept for 2s");
+          
+          FileUtil.unlockDir( dir );
+          System.out.println("Thread1: lock "+dir+" released");
+        }
+        catch( Exception e )
+        {
+          fail( e.getMessage() );
+        }
+      }
+      
+    }
+    
+    class TestThread2
+    extends Thread
+    {
+      boolean lock;
+      String dir;
+
+      public TestThread2( String dir )
+      {
+        this.dir = dir;
+      }
+      @Override
+      public void run()
+      {
+        try
+        {
+          lock = FileUtil.lockDir( dir, 10L, 10L );
+          assertFalse( lock );
+          System.out.println("Thread2: resource "+dir+" locked");
+          
+          lock = FileUtil.lockDir( dir, 5000L, 100L );
+          assertNotNull( lock );
+          
+          FileUtil.unlockDir( dir );
+          System.out.println("Thread2: lock "+dir+" released");
+        }
+        catch( Exception e )
+        {
+          fail( e.getMessage() );
+        }
+      }
+      
+    }
+    
+    File dir = File.createTempFile( "test-", "-dir" );
+    String dirName = dir.getAbsolutePath();
+    dir.delete();
+    dir = new File( dirName );
+    dir.mkdir();
+    dir.deleteOnExit();
+    
+    TestThread1 th1 = new TestThread1( dirName );
+    TestThread2 th2 = new TestThread2( dirName );
+    
+    th1.start();
+    th2.start();
+    
+    for(;;)
+      if( th1.isAlive() || th2.isAlive() )
+        Thread.sleep( 1000L );
+      else
+        break;
+    
+    System.out.println("Multi-threaded test finished successfully");
+  }
+  
//----------------------------------------------------------------------------------------
 }


Reply via email to