Coverage Report - org.codehaus.plexus.archiver.dir.DirectoryArchiver
 
Classes in this File Line Coverage Branch Coverage Complexity
DirectoryArchiver
71 %
54/76
67 %
27/40
5
DirectoryArchiver$1
60 %
3/5
N/A
5
 
 1  0
 /*
 2  
  * Copyright 2001-2005 The Apache Software Foundation.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.codehaus.plexus.archiver.dir;
 17  
 
 18  
 import java.io.File;
 19  
 import java.io.IOException;
 20  
 import java.util.ArrayList;
 21  
 import java.util.List;
 22  
 import org.codehaus.plexus.archiver.AbstractArchiver;
 23  
 import org.codehaus.plexus.archiver.ArchiveEntry;
 24  
 import org.codehaus.plexus.archiver.ArchiverException;
 25  
 import org.codehaus.plexus.archiver.ResourceIterator;
 26  
 import org.codehaus.plexus.archiver.exceptions.EmptyArchiveException;
 27  
 import org.codehaus.plexus.archiver.util.ArchiveEntryUtils;
 28  
 import org.codehaus.plexus.archiver.util.ResourceUtils;
 29  
 import org.codehaus.plexus.components.io.attributes.SymlinkUtils;
 30  
 import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier;
 31  
 import org.codehaus.plexus.components.io.resources.PlexusIoResource;
 32  
 
 33  
 /**
 34  
  * A plexus archiver implementation that stores the files to archive in a directory.
 35  
  */
 36  11
 public class DirectoryArchiver
 37  
     extends AbstractArchiver
 38  
 {
 39  
 
 40  3
     private final List<Runnable> directoryChmods = new ArrayList<Runnable>();
 41  
 
 42  
     public void resetArchiver()
 43  
         throws IOException
 44  
     {
 45  0
         cleanUp();
 46  0
     }
 47  
 
 48  
     @Override
 49  
     public void execute()
 50  
         throws ArchiverException, IOException
 51  
     {
 52  
         // Most of this method was copied from org.codehaus.plexus.archiver.tar.TarArchiver
 53  
         // and modified to store files in a directory, not a tar archive.
 54  3
         final ResourceIterator iter = getResources();
 55  3
         if ( !iter.hasNext() )
 56  
         {
 57  0
             throw new EmptyArchiveException( "archive cannot be empty" );
 58  
         }
 59  
 
 60  3
         final File destDirectory = getDestFile();
 61  3
         if ( destDirectory == null )
 62  
         {
 63  0
             throw new ArchiverException( "You must set the destination directory." );
 64  
         }
 65  3
         if ( destDirectory.exists() && !destDirectory.isDirectory() )
 66  
         {
 67  0
             throw new ArchiverException( destDirectory + " is not a directory." );
 68  
         }
 69  3
         if ( destDirectory.exists() && !destDirectory.canWrite() )
 70  
         {
 71  0
             throw new ArchiverException( destDirectory + " is not writable." );
 72  
         }
 73  
 
 74  3
         getLogger().info( "Copying files to " + destDirectory.getAbsolutePath() );
 75  
 
 76  
         try
 77  
         {
 78  29
             while ( iter.hasNext() )
 79  
             {
 80  26
                 final ArchiveEntry f = iter.next();
 81  
                 // Check if we don't add directory file in itself
 82  26
                 if ( ResourceUtils.isSame( f.getResource(), destDirectory ) )
 83  
                 {
 84  0
                     throw new ArchiverException( "The destination directory cannot include itself." );
 85  
                 }
 86  26
                 String fileName = f.getName();
 87  26
                 final String destDir = destDirectory.getCanonicalPath();
 88  26
                 fileName = destDir + File.separator + fileName;
 89  26
                 PlexusIoResource resource = f.getResource();
 90  26
                 if ( resource instanceof SymlinkDestinationSupplier )
 91  
                 {
 92  7
                     String dest = ( (SymlinkDestinationSupplier) resource ).getSymlinkDestination();
 93  7
                     File target = new File( dest );
 94  7
                     SymlinkUtils.createSymbolicLink( new File( fileName ), target );
 95  7
                 }
 96  
                 else
 97  
                 {
 98  19
                     copyFile( f, fileName );
 99  
                 }
 100  26
             }
 101  
 
 102  3
             for ( Runnable directoryChmod : directoryChmods )
 103  
             {
 104  8
                 directoryChmod.run();
 105  8
             }
 106  3
             directoryChmods.clear();
 107  0
         }
 108  0
         catch ( final IOException ioe )
 109  
         {
 110  0
             final String message = "Problem copying files : " + ioe.getMessage();
 111  0
             throw new ArchiverException( message, ioe );
 112  3
         }
 113  3
     }
 114  
 
 115  
     /**
 116  
      * Copies the specified file to the specified path, creating any ancestor directory structure as necessary.
 117  
      *
 118  
      * @param entry The file to copy (IOException will be thrown if this does not exist)
 119  
      * @param vPath The fully qualified path to copy the file to.
 120  
      *
 121  
      * @throws ArchiverException If there is a problem creating the directory structure
 122  
      * @throws IOException If there is a problem copying the file
 123  
      */
 124  
     protected void copyFile( final ArchiveEntry entry, final String vPath )
 125  
         throws ArchiverException, IOException
 126  
     {
 127  
         // don't add "" to the archive
 128  19
         if ( vPath.length() <= 0 )
 129  
         {
 130  0
             return;
 131  
         }
 132  
 
 133  19
         final PlexusIoResource in = entry.getResource();
 134  19
         final File outFile = new File( vPath );
 135  
 
 136  19
         final long inLastModified = in.getLastModified();
 137  19
         final long outLastModified = outFile.lastModified();
 138  19
         if ( ResourceUtils.isUptodate( inLastModified, outLastModified ) )
 139  
         {
 140  1
             return;
 141  
         }
 142  
 
 143  18
         if ( !in.isDirectory() )
 144  
         {
 145  10
             if ( !outFile.getParentFile().exists() )
 146  
             {
 147  
                 // create the parent directory...
 148  1
                 if ( !outFile.getParentFile().mkdirs() )
 149  
                 {
 150  
                     // Failure, unable to create specified directory for some unknown reason.
 151  0
                     throw new ArchiverException( "Unable to create directory or parent directory of " + outFile );
 152  
                 }
 153  
             }
 154  10
             ResourceUtils.copyFile( entry.getInputStream(), outFile );
 155  
 
 156  10
             setFileModes( entry, outFile, inLastModified );
 157  0
         }
 158  
         else
 159  
         { // file is a directory
 160  8
             if ( outFile.exists() )
 161  
             {
 162  8
                 if ( !outFile.isDirectory() )
 163  
                 {
 164  
                     // should we just delete the file and replace it with a directory?
 165  
                     // throw an exception, let the user delete the file manually.
 166  0
                     throw new ArchiverException(
 167  0
                         "Expected directory and found file at copy destination of " + in.getName() + " to " + outFile );
 168  
                 }
 169  
             }
 170  0
             else if ( !outFile.mkdirs() )
 171  
             {
 172  
                 // Failure, unable to create specified directory for some unknown reason.
 173  0
                 throw new ArchiverException( "Unable to create directory or parent directory of " + outFile );
 174  
             }
 175  
 
 176  0
             directoryChmods.add( new Runnable()
 177  8
             {
 178  
 
 179  
                 @Override
 180  
                 public void run()
 181  
                 {
 182  8
                     setFileModes( entry, outFile, inLastModified );
 183  8
                 }
 184  
 
 185  
             } );
 186  
         }
 187  
 
 188  18
     }
 189  
 
 190  0
     private void setFileModes( ArchiveEntry entry, File outFile, long inLastModified )
 191  
     {
 192  18
         if ( !isIgnorePermissions() )
 193  
         {
 194  18
             ArchiveEntryUtils.chmod( outFile, entry.getMode() );
 195  
         }
 196  
 
 197  18
         outFile.setLastModified( inLastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
 198  0
                                      ? System.currentTimeMillis()
 199  0
                                      : inLastModified );
 200  18
     }
 201  
 
 202  
     @Override
 203  
     protected void cleanUp()
 204  
         throws IOException
 205  
     {
 206  3
         super.cleanUp();
 207  3
         setIncludeEmptyDirs( false );
 208  3
         setIncludeEmptyDirs( true );
 209  3
     }
 210  
 
 211  
     @Override
 212  
     protected void close()
 213  
         throws IOException
 214  
     {
 215  3
     }
 216  
 
 217  
     @Override
 218  
     protected String getArchiveType()
 219  
     {
 220  0
         return "directory";
 221  
     }
 222  
 
 223  
 }