    001/*
    002 *  Licensed to the Apache Software Foundation (ASF) under one or more
    003 *  contributor license agreements.  See the NOTICE file distributed with
    004 *  this work for additional information regarding copyright ownership.
    005 *  The ASF licenses this file to You under the Apache License, Version 2.0
    006 *  (the "License"); you may not use this file except in compliance with
    007 *  the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 *  Unless required by applicable law or agreed to in writing, software
    012 *  distributed under the License is distributed on an "AS IS" BASIS,
    013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 *  See the License for the specific language governing permissions and
    015 *  limitations under the License.
    016 *
    017 */
    018
    019package org.apache.commons.compress.archivers;
    020
    021import java.io.BufferedInputStream;
    022import java.io.File;
    023import java.io.IOException;
    024import java.io.InputStream;
    025import java.nio.file.Files;
    026import java.util.Enumeration;
    027import org.apache.commons.compress.archivers.sevenz.SevenZFile;
    028import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
    029import org.apache.commons.compress.archivers.tar.TarFile;
    030import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
    031import org.apache.commons.compress.archivers.zip.ZipFile;
    032
    033/**
    034 * Simple command line application that lists the contents of an archive.
    035 *
    036 * <p>The name of the archive must be given as a command line argument.</p>
    037 * <p>The optional second argument defines the archive type, in case the format is not recognized.</p>
    038 *
    039 * @since 1.1
    040 */
    041public final class Lister {
    042
    043    private static final ArchiveStreamFactory FACTORY = ArchiveStreamFactory.DEFAULT;
    044
    045    public static void main(final String[] args) throws Exception {
    046        if (args.length == 0) {
    047            usage();
    048            return;
    049        }
    050        System.out.println("Analysing " + args[0]);
    051        final File f = new File(args[0]);
    052        if (!f.isFile()) {
    053            System.err.println(f + " doesn't exist or is a directory");
    054        }
    055        final String format = args.length > 1 ? args[1] : detectFormat(f);
    056        if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) {
    057            list7z(f);
    058        } else if ("zipfile".equals(format)) {
    059            listZipUsingZipFile(f);
    060        } else if ("tarfile".equals(format)) {
    061            listZipUsingTarFile(f);
    062        } else {
    063            listStream(f, args);
    064        }
    065    }
    066
    067    private static void listStream(final File f, final String[] args) throws ArchiveException, IOException {
    068        try (final InputStream fis = new BufferedInputStream(Files.newInputStream(f.toPath()));
    069                final ArchiveInputStream ais = createArchiveInputStream(args, fis)) {
    070            System.out.println("Created " + ais.toString());
    071            ArchiveEntry ae;
    072            while ((ae = ais.getNextEntry()) != null) {
    073                System.out.println(ae.getName());
    074            }
    075        }
    076    }
    077
    078    private static ArchiveInputStream createArchiveInputStream(final String[] args, final InputStream fis)
    079            throws ArchiveException {
    080        if (args.length > 1) {
    081            return FACTORY.createArchiveInputStream(args[1], fis);
    082        }
    083        return FACTORY.createArchiveInputStream(fis);
    084    }
    085
    086    private static String detectFormat(final File f) throws ArchiveException, IOException {
    087        try (final InputStream fis = new BufferedInputStream(Files.newInputStream(f.toPath()))) {
    088            return ArchiveStreamFactory.detect(fis);
    089        }
    090    }
    091
    092    private static void list7z(final File f) throws ArchiveException, IOException {
    093        try (SevenZFile z = new SevenZFile(f)) {
    094            System.out.println("Created " + z.toString());
    095            ArchiveEntry ae;
    096            while ((ae = z.getNextEntry()) != null) {
    097                final String name = ae.getName() == null ? z.getDefaultName() + " (entry name was null)"
    098                    : ae.getName();
    099                System.out.println(name);
    100            }
    101        }
    102    }
    103
    104    private static void listZipUsingZipFile(final File f) throws ArchiveException, IOException {
    105        try (ZipFile z = new ZipFile(f)) {
    106            System.out.println("Created " + z.toString());
    107            for (final Enumeration<ZipArchiveEntry> en = z.getEntries(); en.hasMoreElements(); ) {
    108                System.out.println(en.nextElement().getName());
    109            }
    110        }
    111    }
    112
    113    private static void listZipUsingTarFile(final File f) throws ArchiveException, IOException {
    114        try (TarFile t = new TarFile(f)) {
    115            System.out.println("Created " + t.toString());
    116            for (TarArchiveEntry en : t.getEntries()) {
    117                System.out.println(en.getName());
    118            }
    119        }
    120    }
    121
    122    private static void usage() {
    123        System.out.println("Parameters: archive-name [archive-type]\n");
    124        System.out.println("the magic archive-type 'zipfile' prefers ZipFile over ZipArchiveInputStream");
    125        System.out.println("the magic archive-type 'tarfile' prefers TarFile over TarArchiveInputStream");
    126    }
    127
    128}