b2s.idea.mavenize.JarCombiner.java Source code

Java tutorial

Introduction

Here is the source code for b2s.idea.mavenize.JarCombiner.java

Source

/**
 *
 * Copyright to the original author or authors.
 *
 * 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.
 */
package b2s.idea.mavenize;

import org.apache.commons.io.IOUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class JarCombiner {
    public void combineAllJarsIn(File folderOfJars, File output) {
        ZipOutputStream zipOut = null;
        try {
            JarContext context = new JarContext();
            zipOut = new ZipOutputStream(new FileOutputStream(output));
            for (File jarFile : folderOfJars.listFiles(new IntellijJarFileFilter())) {
                copyContentsOf(jarFile, zipOut, context);
                System.out.println(jarFile.getName());
            }

            addServiceEntries(zipOut, context);

            zipOut.finish();
        } catch (IOException e) {
            throw new RuntimeException("A problem occurred when combining the JARs", e);
        } finally {
            IOUtils.closeQuietly(zipOut);
        }
    }

    private void addServiceEntries(ZipOutputStream zipOut, JarContext context) throws IOException {
        for (Map.Entry<String, StringBuilder> entry : context.getServices()) {
            zipOut.putNextEntry(new ZipEntry(entry.getKey()));
            zipOut.write(entry.getValue().toString().getBytes());
            zipOut.closeEntry();
        }
    }

    private static void copyContentsOf(File input, ZipOutputStream output, JarContext context) throws IOException {
        ZipFile zip = null;
        try {
            zip = new ZipFile(input);
            Enumeration<? extends ZipEntry> entries = zip.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                if (fileCanBeIgnored(entry, context)) {
                    continue;
                }

                if (isServiceEntry(entry)) {
                    context.addService(entry.getName(), contentsOf(entry, zip));
                    continue;
                }

                output.putNextEntry(new ZipEntry(entry.getName()));
                output.write(contentsOf(entry, zip));
                output.flush();
                output.closeEntry();

                context.addVisitedEntry(entry);
            }
        } finally {
            close(zip);
        }
    }

    private static boolean isServiceEntry(ZipEntry entry) {
        return entry.getName().startsWith("META-INF/services/");
    }

    private static boolean fileCanBeIgnored(ZipEntry entry, JarContext context) {
        return entry.getName().endsWith("MANIFEST.MF") || context.alreadyHaveSeen(entry);
    }

    private static byte[] contentsOf(ZipEntry entry, ZipFile file) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        InputStream input = null;
        try {
            input = file.getInputStream(entry);
            IOUtils.copy(input, output);
        } finally {
            IOUtils.closeQuietly(input);
        }
        return output.toByteArray();
    }

    private static void close(ZipFile zip) {
        if (zip != null) {
            try {
                zip.close();
            } catch (IOException e) {

            }
        }
    }

    private static class IntellijJarFileFilter implements FileFilter {
        private final List<String> FILES_WANTED;

        private IntellijJarFileFilter() {
            InputStream input = null;
            try {
                input = Thread.currentThread().getContextClassLoader().getResourceAsStream("intellij-jars.txt");
                FILES_WANTED = Arrays.asList(IOUtils.toString(input).split("\r\n|\n"));
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                IOUtils.closeQuietly(input);
            }
        }

        @Override
        public boolean accept(File file) {
            String filename = file.getName().toLowerCase();
            return FILES_WANTED.contains(filename);
        }
    }
}