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.zip.ZipArchiveEntry;
029import org.apache.commons.compress.archivers.zip.ZipFile;
030
031/**
032 * Simple command line application that lists the contents of an archive.
033 *
034 * <p>The name of the archive must be given as a command line argument.</p>
035 * <p>The optional second argument defines the archive type, in case the format is not recognized.</p>
036 *
037 * @since 1.1
038 */
039public final class Lister {
040    private static final ArchiveStreamFactory factory = new ArchiveStreamFactory();
041
042    public static void main(final String[] args) throws Exception {
043        if (args.length == 0) {
044            usage();
045            return;
046        }
047        System.out.println("Analysing " + args[0]);
048        final File f = new File(args[0]);
049        if (!f.isFile()) {
050            System.err.println(f + " doesn't exist or is a directory");
051        }
052        String format = args.length > 1 ? args[1] : detectFormat(f);
053        if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) {
054            list7z(f);
055        } else if ("zipfile".equals(format)) {
056            listZipUsingZipFile(f);
057        } else {
058            listStream(f, args);
059        }
060    }
061
062    private static void listStream(File f, String[] args) throws ArchiveException, IOException {
063        try (final InputStream fis = new BufferedInputStream(Files.newInputStream(f.toPath()));
064                final ArchiveInputStream ais = createArchiveInputStream(args, fis)) {
065            System.out.println("Created " + ais.toString());
066            ArchiveEntry ae;
067            while ((ae = ais.getNextEntry()) != null) {
068                System.out.println(ae.getName());
069            }
070        }
071    }
072
073    private static ArchiveInputStream createArchiveInputStream(final String[] args, final InputStream fis)
074            throws ArchiveException {
075        if (args.length > 1) {
076            return factory.createArchiveInputStream(args[1], fis);
077        }
078        return factory.createArchiveInputStream(fis);
079    }
080
081    private static String detectFormat(File f) throws ArchiveException, IOException {
082        try (final InputStream fis = new BufferedInputStream(Files.newInputStream(f.toPath()))) {
083            return factory.detect(fis);
084        }
085    }
086
087    private static void list7z(File f) throws ArchiveException, IOException {
088        try (SevenZFile z = new SevenZFile(f)) {
089            System.out.println("Created " + z.toString());
090            ArchiveEntry ae;
091            while ((ae = z.getNextEntry()) != null) {
092                String name = ae.getName() == null ? z.getDefaultName() + " (entry name was null)"
093                    : ae.getName();
094                System.out.println(name);
095            }
096        }
097    }
098
099    private static void listZipUsingZipFile(File f) throws ArchiveException, IOException {
100        try (ZipFile z = new ZipFile(f)) {
101            System.out.println("Created " + z.toString());
102            for (Enumeration<ZipArchiveEntry> en = z.getEntries(); en.hasMoreElements(); ) {
103                System.out.println(en.nextElement().getName());
104            }
105        }
106    }
107
108    private static void usage() {
109        System.out.println("Parameters: archive-name [archive-type]\n");
110        System.out.println("the magic archive-type 'zipfile' prefers ZipFile over ZipArchiveInputStream");
111    }
112
113}