FELIX-474: fix remote locking

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@616650 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java
index 0a3f9ec..6f32f4d 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java
@@ -19,23 +19,15 @@
 package org.apache.felix.obr.plugin;
 
 
-import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
 import java.net.URI;
 
 import org.apache.maven.artifact.manager.WagonManager;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.settings.Settings;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.TransferFailedException;
-import org.apache.maven.wagon.authorization.AuthorizationException;
 
 
 /**
@@ -98,10 +90,9 @@
     /**
      * main method for this goal.
      * @implements org.apache.maven.plugin.Mojo.execute 
-     * @throws MojoExecutionException if the plugin failed
-     * @throws MojoFailureException if the plugin failed
+     * @throws MojoExecutionException
      */
-    public void execute() throws MojoExecutionException, MojoFailureException
+    public void execute() throws MojoExecutionException
     {
         ArtifactRepository ar = m_project.getDistributionManagementArtifactRepository();
 
@@ -118,29 +109,13 @@
         RemoteFileManager remoteFile = new RemoteFileManager( ar, m_wagonManager, m_settings, getLog() );
         remoteFile.connect();
 
-        // create a non-empty file used to lock the repository descriptor file
-        File lockFile = null;
-        Writer output = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-            output = new BufferedWriter( new FileWriter( lockFile ) );
-            output.write( "locked" );
-            output.close();
-        }
-        catch ( IOException e )
-        {
-            getLog().error( "Unable to create temporary file" );
-            throw new MojoFailureException( "IOException" );
-        }
-
         if ( !m_ignoreLock )
         {
             int countError = 0;
-            while ( remoteFile.isLockedFile( remoteFile, m_repositoryName ) && countError < 2 )
+            while ( remoteFile.isLockedFile( m_repositoryName ) && countError < 2 )
             {
                 countError++;
-                getLog().warn( "File is locked, retry in 10s" );
+                getLog().warn( "OBR is locked, retry in 10s" );
                 try
                 {
                     Thread.sleep( 10000 );
@@ -153,57 +128,16 @@
 
             if ( countError == 2 )
             {
-                getLog().error(
-                    "File: " + m_repositoryName + " is locked. Try -Dignore-lock=true if you want to force uploading" );
-                throw new MojoFailureException( "fileLocked" );
+                getLog().error( "OBR " + m_repositoryName + " is locked. Use -Dignore-lock to force uploading" );
+                throw new MojoExecutionException( "OBR locked" );
             }
         }
 
-        try
-        {
-            // file is not locked, so we lock it now
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-            lockFile.delete();
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
+        // ======== LOCK REMOTE OBR ========
+        remoteFile.lockFile( m_repositoryName );
 
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-
-        try
-        {
-            repoDescriptorFile = remoteFile.get( m_repositoryName, ".xml" );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
+        // ======== DOWNLOAD REMOTE OBR ========
+        repoDescriptorFile = remoteFile.get( m_repositoryName, ".xml" );
 
         // get the path to local maven repository
         String mavenRepository = m_localRepo.getBasedir();
@@ -225,64 +159,12 @@
 
         update.updateRepository();
 
-        // the reposiroty descriptor file is modified, we upload it on the remote repository
-        try
-        {
-            remoteFile.put( repoDescriptorFile, m_repositoryName );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            getLog().error( "Resource does not exist:" + repoDescriptorFile.getName() );
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
+        // ======== UPLOAD MODIFIED OBR ========
+        remoteFile.put( repoDescriptorFile, m_repositoryName );
         repoDescriptorFile.delete();
 
-        // we remove lockFile activation
-        lockFile = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
-        try
-        {
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-            lockFile.delete();
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
+        // ======== UNLOCK REMOTE OBR ========
+        remoteFile.unlockFile( m_repositoryName );
 
         remoteFile.disconnect();
     }
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java
index 4c7daf7..beaa4b6 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java
@@ -19,23 +19,15 @@
 package org.apache.felix.obr.plugin;
 
 
-import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
 import java.net.URI;
 
 import org.apache.maven.artifact.manager.WagonManager;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.settings.Settings;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.TransferFailedException;
-import org.apache.maven.wagon.authorization.AuthorizationException;
 
 
 /**
@@ -105,10 +97,9 @@
     /**
      * main method for this goal.
      * @implements org.apache.maven.plugin.Mojo.execute 
-     * @throws MojoExecutionException if the plugin failed
-     * @throws MojoFailureException if the plugin failed
+     * @throws MojoExecutionException
      */
-    public void execute() throws MojoExecutionException, MojoFailureException
+    public void execute() throws MojoExecutionException
     {
         ArtifactRepository ar = m_project.getDistributionManagementArtifactRepository();
 
@@ -125,29 +116,13 @@
         RemoteFileManager remoteFile = new RemoteFileManager( ar, m_wagonManager, m_settings, getLog() );
         remoteFile.connect();
 
-        // create a non-empty file used to lock the repository descriptor file
-        File lockFile = null;
-        Writer output = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-            output = new BufferedWriter( new FileWriter( lockFile ) );
-            output.write( "locked" );
-            output.close();
-        }
-        catch ( IOException e )
-        {
-            getLog().error( "Unable to create temporary file" );
-            throw new MojoFailureException( "IOException" );
-        }
-
         if ( !m_ignoreLock )
         {
             int countError = 0;
-            while ( remoteFile.isLockedFile( remoteFile, m_repositoryName ) && countError < 2 )
+            while ( remoteFile.isLockedFile( m_repositoryName ) && countError < 2 )
             {
                 countError++;
-                getLog().warn( "File is locked, retry in 10s" );
+                getLog().warn( "OBR is locked, retry in 10s" );
                 try
                 {
                     Thread.sleep( 10000 );
@@ -160,57 +135,16 @@
 
             if ( countError == 2 )
             {
-                getLog().error(
-                    "File: " + m_repositoryName + " is locked. Try -Dignore-lock=true if you want to force uploading" );
-                throw new MojoFailureException( "fileLocked" );
+                getLog().error( "OBR " + m_repositoryName + " is locked. Use -Dignore-lock to force uploading" );
+                throw new MojoExecutionException( "OBR locked" );
             }
         }
 
-        try
-        {
-            // file is not locked, so we lock it now
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-            lockFile.delete();
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
+        // ======== LOCK REMOTE OBR ========
+        remoteFile.lockFile( m_repositoryName );
 
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-
-        try
-        {
-            repoDescriptorFile = remoteFile.get( m_repositoryName, ".xml" );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
+        // ======== DOWNLOAD REMOTE OBR ========
+        repoDescriptorFile = remoteFile.get( m_repositoryName, ".xml" );
 
         // get the path to local maven repository
         String mavenRepository = m_localRepo.getBasedir();
@@ -232,64 +166,12 @@
 
         update.updateRepository();
 
-        // the reposiroty descriptor file is modified, we upload it on the remote repository
-        try
-        {
-            remoteFile.put( repoDescriptorFile, m_repositoryName );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            getLog().error( "Resource does not exist:" + repoDescriptorFile.getName() );
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
+        // ======== UPLOAD MODIFIED OBR ========
+        remoteFile.put( repoDescriptorFile, m_repositoryName );
         repoDescriptorFile.delete();
 
-        // we remove lockFile activation
-        lockFile = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
-        try
-        {
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-            lockFile.delete();
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
+        // ======== UNLOCK REMOTE OBR ========
+        remoteFile.unlockFile( m_repositoryName );
 
         remoteFile.disconnect();
     }
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java
index a0f3cb4..cee8dd8 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java
@@ -19,14 +19,16 @@
 package org.apache.felix.obr.plugin;
 
 
+import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.Writer;
 
 import org.apache.maven.artifact.manager.WagonConfigurationException;
 import org.apache.maven.artifact.manager.WagonManager;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.settings.Proxy;
 import org.apache.maven.settings.Settings;
@@ -48,7 +50,6 @@
  */
 public class RemoteFileManager
 {
-
     /**
      * save the connection.
      */
@@ -103,6 +104,7 @@
             m_log.error( "must be connected first!" );
             return;
         }
+
         try
         {
             m_wagon.disconnect();
@@ -116,7 +118,7 @@
 
     /**
      * connect the current object to artifact repository given in constructor.
-     * @throws MojoExecutionException if connection failed
+     * @throws MojoExecutionException
      */
     public void connect() throws MojoExecutionException
     {
@@ -157,11 +159,11 @@
         }
         catch ( ConnectionException e )
         {
-            throw new MojoExecutionException( "Error uploading file", e );
+            throw new MojoExecutionException( "Connection failed", e );
         }
         catch ( AuthenticationException e )
         {
-            throw new MojoExecutionException( "Error uploading file", e );
+            throw new MojoExecutionException( "Authentication failed", e );
         }
     }
 
@@ -170,38 +172,40 @@
      * get a file from the current repository connected.
      * @param url url to the targeted file
      * @param suffix suggested file suffix
-     * @return  get a file descriptor on the requiered resource
-     * @throws IOException if an IO error occurs
-     * @throws TransferFailedException  if the transfer failed
-     * @throws AuthorizationException if the connection authorization failed
+     * @return get a file descriptor on the required resource
+     * @throws MojoExecutionException
      */
-    public File get( String url, String suffix ) throws IOException, TransferFailedException, AuthorizationException
+    public File get( String url, String suffix ) throws MojoExecutionException
     {
-
         if ( m_wagon == null )
         {
             m_log.error( "must be connected first!" );
             return null;
         }
 
-        File file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), suffix );
+        File file = null;
         try
         {
+            file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), suffix );
             m_wagon.get( url, file );
         }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "I/O problem", e );
+        }
         catch ( TransferFailedException e )
         {
-            file.delete();
-            throw e;
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            file.delete();
+            file.delete(); // cleanup on failure
+            throw new MojoExecutionException( "Transfer failed", e );
         }
         catch ( AuthorizationException e )
         {
-            file.delete();
-            throw e;
+            file.delete(); // cleanup on failure
+            throw new MojoExecutionException( "Authorization failed", e );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            file.delete(); // return non-existent file
         }
 
         return file;
@@ -212,19 +216,32 @@
      * put a file on the current repository connected.
      * @param file file to upload
      * @param url url to copy file
-     * @throws TransferFailedException if the transfer failed 
-     * @throws ResourceDoesNotExistException if the targeted resource doesn't exist
-     * @throws AuthorizationException if the connection authorization failed
+     * @throws MojoExecutionException
      */
-    public void put( File file, String url ) throws TransferFailedException, ResourceDoesNotExistException,
-        AuthorizationException
+    public void put( File file, String url ) throws MojoExecutionException
     {
         if ( m_wagon == null )
         {
             m_log.error( "must be connected first!" );
             return;
         }
-        m_wagon.put( file, url );
+
+        try
+        {
+            m_wagon.put( file, url );
+        }
+        catch ( TransferFailedException e )
+        {
+            throw new MojoExecutionException( "Transfer failed", e );
+        }
+        catch ( AuthorizationException e )
+        {
+            throw new MojoExecutionException( "Authorization failed", e );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            throw new MojoExecutionException( "Resource does not exist:" + file, e );
+        }
     }
 
 
@@ -253,39 +270,23 @@
     }
 
 
-    /**
-     * this method indicates if the targeted file is locked or not.
-     * @param remote connection manager
-     * @param fileName name targeted
-     * @return  true if the required file is locked, else false
-     * @throws MojoFailureException if the plugin failed
-     */
-    public boolean isLockedFile( RemoteFileManager remote, String fileName ) throws MojoFailureException
+    public void lockFile( String fileName ) throws MojoExecutionException
     {
         File file = null;
         try
         {
-            file = remote.get( fileName + ".lock", ".lock" );
-            if ( null != file && file.length() == 0 )
-            {
-                return false;
-            }
-            return true;
-        }
-        catch ( TransferFailedException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
+            // create a non-empty file used to lock the remote file
+            file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), ".lock" );
+
+            Writer writer = new BufferedWriter( new FileWriter( file ) );
+            writer.write( "LOCKED" );
+            writer.close();
+
+            put( file, fileName + ".lock" );
         }
         catch ( IOException e )
         {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
+            throw new MojoExecutionException( "I/O problem", e );
         }
         finally
         {
@@ -296,4 +297,63 @@
         }
     }
 
+
+    public void unlockFile( String fileName ) throws MojoExecutionException
+    {
+        File file = null;
+        try
+        {
+            // clear the contents of the file used to lock the remote file
+            file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), ".lock" );
+
+            Writer writer = new BufferedWriter( new FileWriter( file ) );
+            writer.write( " " ); // write 1 byte to force wagon upload
+            writer.close();
+
+            put( file, fileName + ".lock" );
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "I/O problem", e );
+        }
+        finally
+        {
+            if ( null != file )
+            {
+                file.delete();
+            }
+        }
+    }
+
+
+    /**
+     * this method indicates if the targeted file is locked or not.
+     * @param remote connection manager
+     * @param fileName name targeted
+     * @return  true if the required file is locked, else false
+     * @throws MojoExecutionException
+     */
+    public boolean isLockedFile( String fileName ) throws MojoExecutionException
+    {
+        File file = null;
+        try
+        {
+            file = get( fileName + ".lock", ".lock" );
+
+            // file is locked with contents "LOCKED"
+            if ( null != file && file.length() <= 2 )
+            {
+                return false;
+            }
+        }
+        finally
+        {
+            if ( null != file )
+            {
+                file.delete();
+            }
+        }
+
+        return true;
+    }
 }