Coverage Report - org.codehaus.plexus.archiver.zip.PlexusIoZipFileResourceCollection
 
Classes in this File Line Coverage Branch Coverage Complexity
PlexusIoZipFileResourceCollection
92%
13/14
50%
2/4
1,6
PlexusIoZipFileResourceCollection$1
100%
2/2
N/A
1,6
PlexusIoZipFileResourceCollection$ZipFileResourceIterator
92%
12/13
100%
2/2
1,6
PlexusIoZipFileResourceCollection$ZipFileResourceIterator$ZipFileResource
100%
9/9
87%
7/8
1,6
PlexusIoZipFileResourceCollection$ZipFileResourceIterator$ZipFileSymlinkResource
100%
7/7
N/A
1,6
 
 1  
 /*
 2  
  * Copyright 2007 The Codehaus 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.zip;
 17  
 
 18  
 import java.io.Closeable;
 19  
 import java.io.File;
 20  
 import java.io.IOException;
 21  
 import java.net.URL;
 22  
 import java.net.URLClassLoader;
 23  
 import java.nio.charset.Charset;
 24  
 import java.util.Enumeration;
 25  
 import java.util.Iterator;
 26  
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 27  
 import org.apache.commons.compress.archivers.zip.ZipFile;
 28  
 import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier;
 29  
 import org.codehaus.plexus.components.io.resources.AbstractPlexusIoArchiveResourceCollection;
 30  
 import org.codehaus.plexus.components.io.resources.EncodingSupported;
 31  
 import org.codehaus.plexus.components.io.resources.PlexusIoResource;
 32  
 import org.codehaus.plexus.components.io.resources.PlexusIoURLResource;
 33  
 
 34  
 public class PlexusIoZipFileResourceCollection
 35  
     extends AbstractPlexusIoArchiveResourceCollection
 36  
     implements EncodingSupported
 37  
 {
 38  
 
 39  
     /**
 40  
      * The zip file resource collections role hint.
 41  
      */
 42  
     public static final String ROLE_HINT = "zipFile";
 43  
 
 44  
     /**
 45  
      * The zip file resource collections role hint for jar files.
 46  
      */
 47  
     public static final String JAR_ROLE_HINT = "jarFile";
 48  
 
 49  9
     private Charset charset = Charset.forName( "UTF-8" );
 50  
 
 51  
     public PlexusIoZipFileResourceCollection()
 52  9
     {
 53  
 
 54  9
     }
 55  
 
 56  
     @Override
 57  
     public boolean isConcurrentAccessSupported()
 58  
     {
 59  
         // Maybe we could support concurrent some time in the future
 60  9
         return false;
 61  
     }
 62  
 
 63  
     @Override
 64  
     protected Iterator<PlexusIoResource> getEntries()
 65  
         throws IOException
 66  
     {
 67  7
         final File f = getFile();
 68  7
         if ( f == null )
 69  
         {
 70  0
             throw new IOException( "The zip file has not been set." );
 71  
         }
 72  7
         final URLClassLoader urlClassLoader = new URLClassLoader( new URL[]
 73  
         {
 74  
             f.toURI().toURL()
 75  
         }, null )
 76  7
         {
 77  
 
 78  
             @Override
 79  
             public URL getResource( String name )
 80  
             {
 81  18
                 return findResource( name );
 82  
             }
 83  
 
 84  
         };
 85  
 
 86  7
         final URL url = new URL( "jar:" + f.toURI().toURL() + "!/" );
 87  7
         final ZipFile zipFile = new ZipFile( f, charset != null ? charset.name() : "UTF8" );
 88  7
         final Enumeration<ZipArchiveEntry> en = zipFile.getEntriesInPhysicalOrder();
 89  7
         return new ZipFileResourceIterator( en, url, zipFile, urlClassLoader );
 90  
     }
 91  
 
 92  63
     private static class ZipFileResourceIterator
 93  
         implements Iterator<PlexusIoResource>, Closeable
 94  
     {
 95  
 
 96  36
         private class ZipFileResource
 97  
             extends PlexusIoURLResource
 98  
         {
 99  
 
 100  
             private ZipFileResource( ZipArchiveEntry entry )
 101  36
             {
 102  36
                 super( entry.getName(),
 103  
                        entry.getTime() == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : entry.getTime(),
 104  
                        entry.isDirectory() ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : entry.getSize(),
 105  
                        !entry.isDirectory(), entry.isDirectory(), true );
 106  
 
 107  36
             }
 108  
 
 109  
             @Override
 110  
             public URL getURL()
 111  
                 throws IOException
 112  
             {
 113  21
                 String spec = getName();
 114  21
                 if ( spec.startsWith( "/" ) )
 115  
                 {
 116  
                     // Code path for PLXCOMP-170. Note that urlClassloader does not seem to produce correct
 117  
                     // urls for this. Which again means files loaded via this path cannot have file names
 118  
                     // requiring url encoding
 119  3
                     spec = "./" + spec;
 120  3
                     return new URL( url, spec );
 121  
                 }
 122  18
                 return urlClassLoader.getResource( spec );
 123  
             }
 124  
 
 125  
         }
 126  
 
 127  6
         private class ZipFileSymlinkResource
 128  
             extends ZipFileResource
 129  
             implements SymlinkDestinationSupplier
 130  
         {
 131  
 
 132  
             private final ZipArchiveEntry entry;
 133  
 
 134  
             private ZipFileSymlinkResource( ZipArchiveEntry entry )
 135  6
             {
 136  6
                 super( entry );
 137  
 
 138  6
                 this.entry = entry;
 139  6
             }
 140  
 
 141  
             @Override
 142  
             public String getSymlinkDestination()
 143  
                 throws IOException
 144  
             {
 145  6
                 return zipFile.getUnixSymlink( entry );
 146  
             }
 147  
 
 148  
             @Override
 149  
             public boolean isSymbolicLink()
 150  
             {
 151  6
                 return true;
 152  
             }
 153  
 
 154  
         }
 155  
 
 156  
         private final Enumeration<ZipArchiveEntry> en;
 157  
 
 158  
         private final URL url;
 159  
 
 160  
         private final ZipFile zipFile;
 161  
 
 162  
         private final URLClassLoader urlClassLoader;
 163  
 
 164  
         public ZipFileResourceIterator( Enumeration<ZipArchiveEntry> en, URL url, ZipFile zipFile,
 165  
                                         URLClassLoader urlClassLoader )
 166  7
         {
 167  7
             this.en = en;
 168  7
             this.url = url;
 169  7
             this.zipFile = zipFile;
 170  7
             this.urlClassLoader = urlClassLoader;
 171  7
         }
 172  
 
 173  
         @Override
 174  
         public boolean hasNext()
 175  
         {
 176  41
             return en.hasMoreElements();
 177  
         }
 178  
 
 179  
         @Override
 180  
         public PlexusIoResource next()
 181  
         {
 182  36
             final ZipArchiveEntry entry = en.nextElement();
 183  36
             return entry.isUnixSymlink()
 184  
                        ? new ZipFileSymlinkResource( entry )
 185  
                        : new ZipFileResource( entry );
 186  
 
 187  
         }
 188  
 
 189  
         @Override
 190  
         public void remove()
 191  
         {
 192  0
             throw new UnsupportedOperationException( "Removing isn't implemented." );
 193  
         }
 194  
 
 195  
         @Override
 196  
         public void close()
 197  
             throws IOException
 198  
         {
 199  2
             zipFile.close();
 200  2
         }
 201  
 
 202  
     }
 203  
 
 204  
     @Override
 205  
     public void setEncoding( Charset charset )
 206  
     {
 207  1
         this.charset = charset;
 208  1
     }
 209  
 
 210  
 }