All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.plexus.archiver.zip.PlexusIoZipFileResourceCollection Maven / Gradle / Ivy

There is a newer version: 4.10.0
Show newest version
package org.codehaus.plexus.archiver.zip;

/*
 * Copyright 2007 The Codehaus Foundation.
 *
 * Licensed 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.
 */

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier;
import org.codehaus.plexus.components.io.resources.AbstractPlexusIoArchiveResourceCollection;
import org.codehaus.plexus.components.io.resources.EncodingSupported;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.components.io.resources.PlexusIoURLResource;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Iterator;


public class PlexusIoZipFileResourceCollection
    extends AbstractPlexusIoArchiveResourceCollection
    implements EncodingSupported
{
    /**
     * The zip file resource collections role hint.
     */
    public static final String ROLE_HINT = "zipFile";

    /**
     * The zip file resource collections role hint for jar files.
     */
    public static final String JAR_ROLE_HINT = "jarFile";

    private Charset charset = Charset.forName("UTF-8");

    public PlexusIoZipFileResourceCollection()
    {

    }

    @Override
    public boolean isConcurrentAccessSupported()
    {
        // Maybe we could support concurrent some time in the future
        return false;
    }

    protected Iterator getEntries()
        throws IOException
    {
        final File f = getFile();
        if ( f == null )
        {
            throw new IOException( "The zip file has not been set." );
        }
        final URLClassLoader urlClassLoader = new URLClassLoader( new URL[]{ f.toURI().toURL() }, null )
        {
            public URL getResource( String name )
            {
                return findResource( name );
            }
        };

        final URL url = new URL( "jar:" + f.toURI().toURL() + "!/" );
        final ZipFile zipFile = new ZipFile( f, charset != null ? charset.name() : "UTF8");
        final Enumeration en = zipFile.getEntriesInPhysicalOrder();
        return new ZipFileResourceIterator( en, url, zipFile, urlClassLoader );
    }

    private static class ZipFileResourceIterator
        implements Iterator, Closeable
    {
        private class ZipFileResource
            extends PlexusIoURLResource
        {
            private ZipFileResource( ZipArchiveEntry entry )
            {
                super( entry.getName(), entry.getTime() == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : entry.getTime(),
                    entry.isDirectory() ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : entry.getSize(),
                    !entry.isDirectory(), entry.isDirectory(), true );
            }

            public URL getURL()
                throws IOException
            {
                String spec = getName();
                if ( spec.startsWith( "/" ) )
                {
                    // Code path for PLXCOMP-170. Note that urlClassloader does not seem to produce correct
                    // urls for this. Which again means files loaded via this path cannot have file names
                    // requiring url encoding
                    spec = "./" + spec;
                    return new URL( url, spec );
                }
                return urlClassLoader.getResource( spec );
            }
        }

        private class ZipFileSymlinkResource
            extends ZipFileResource
            implements SymlinkDestinationSupplier
        {
            private final ZipArchiveEntry entry;

            private ZipFileSymlinkResource( ZipArchiveEntry entry )
            {
                super( entry );

                this.entry = entry;
            }

            @Override
            public String getSymlinkDestination()
                throws IOException
            {
                return zipFile.getUnixSymlink( entry );
            }

            @Override
            public boolean isSymbolicLink()
            {
                return true;
            }
       }

        private final Enumeration en;

        private final URL url;

        private final ZipFile zipFile;

        private final URLClassLoader urlClassLoader;

        public ZipFileResourceIterator( Enumeration en, URL url, ZipFile zipFile, URLClassLoader urlClassLoader )
        {
            this.en = en;
            this.url = url;
            this.zipFile = zipFile;
            this.urlClassLoader = urlClassLoader;
        }

        public boolean hasNext()
        {
            return en.hasMoreElements();
        }

        public PlexusIoResource next()
        {
            final ZipArchiveEntry entry = en.nextElement();

            return entry.isUnixSymlink()
                ? new ZipFileSymlinkResource( entry )
                : new ZipFileResource( entry );
        }

        public void remove()
        {
            throw new UnsupportedOperationException( "Removing isn't implemented." );
        }

        public void close()
            throws IOException
        {
            zipFile.close();
        }
    }

    public void setEncoding( Charset charset )
    {
        this.charset = charset;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy