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

org.bardframework.commons.utils.JarFileUtils Maven / Gradle / Ivy

There is a newer version: 3.6.1
Show newest version
package org.bardframework.commons.utils;

import lombok.experimental.UtilityClass;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@UtilityClass
public class JarFileUtils {

    public static void update(File file, Map newEntries) throws Exception {
        if (MapUtils.isEmpty(newEntries)) {
            return;
        }
        try (FileSystem zipFileSystem = FileSystems.newFileSystem(file.toPath(), ClassLoader.getPlatformClassLoader())) {
            for (String entryPath : newEntries.keySet()) {
                Path pathInJarFile = zipFileSystem.getPath(entryPath);
                /*
                    copy a file into the zip file
                 */
                Files.copy(new ByteArrayInputStream(newEntries.get(entryPath)), pathInJarFile, StandardCopyOption.REPLACE_EXISTING);
            }
        }
    }

    public static void modify(File file, List modifiers) throws Exception {
        try (JarFile jarFile = new JarFile(file)) {
            for (JarModifier modifier : modifiers) {
                modifier.doWork(jarFile);
            }
        }
    }

    public interface JarModifier {
        void doWork(JarFile jarFile) throws IOException;
    }

    public static class JarDirectoryExtractor implements JarModifier {
        protected final String zipDirectoryEntry;
        protected final Path savePath;

        public JarDirectoryExtractor(String zipDirectoryEntry, Path savePath) {
            this.zipDirectoryEntry = zipDirectoryEntry;
            this.savePath = savePath;
        }

        @Override
        public void doWork(JarFile jarFile) {
            jarFile.stream().filter(jarEntry -> !jarEntry.isDirectory() && jarEntry.toString().startsWith(this.getZipDirectoryEntry())).forEach(jarEntry -> {
                File targetFile = this.getSavePath().resolve(jarEntry.toString()).toFile();
                try {
                    FileUtils.copyInputStreamToFile(jarFile.getInputStream(jarEntry), targetFile);
                } catch (IOException e) {
                    throw new IllegalStateException(e);
                }
            });
        }

        public String getZipDirectoryEntry() {
            return zipDirectoryEntry;
        }

        public Path getSavePath() {
            return savePath;
        }
    }

    public static class JarTextFileExtractor implements JarModifier {
        protected final String zipEntry;
        protected final File savePath;
        protected final Map replacements = new HashMap<>();

        public JarTextFileExtractor(String jarEntry, File savePath) {
            this(jarEntry, savePath, Collections.emptyMap());
        }

        public JarTextFileExtractor(String jarEntry, File savePath, Map replacements) {
            this.zipEntry = jarEntry;
            this.savePath = savePath;
            this.replacements.putAll(replacements);
        }

        @Override
        public void doWork(JarFile jarFile) throws IOException {
            String content;
            try (InputStream inputStream = jarFile.getInputStream(jarFile.getEntry(this.getZipEntry()))) {
                content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
                for (Map.Entry entry : this.getReplacements().entrySet()) {
                    Matcher matcher = Pattern.compile(entry.getKey()).matcher(content);
                    if (!matcher.find()) {
                        throw new IllegalStateException(String.format("can't find [%s] in [%s@%s] to replace it!", entry.getKey(), this.getZipEntry(), jarFile.getName()));
                    }
                    content = matcher.replaceAll(entry.getValue());
                }
            }
            FileUtils.writeStringToFile(this.getSavePath(), content, StandardCharsets.UTF_8);
        }

        public String getZipEntry() {
            return zipEntry;
        }

        public File getSavePath() {
            return savePath;
        }

        public Map getReplacements() {
            return replacements;
        }
    }

    public static class JarFileEntrySaver implements JarModifier {
        protected final String zipEntry;
        protected final File savePath;
        protected final Map replacements = new HashMap<>();

        public JarFileEntrySaver(String jarEntry, File savePath) {
            this(jarEntry, savePath, Collections.emptyMap());
        }

        public JarFileEntrySaver(String jarEntry, File savePath, Map replacements) {
            this.zipEntry = jarEntry;
            this.savePath = savePath;
            this.replacements.putAll(replacements);
        }

        @Override
        public void doWork(JarFile jarFile) throws IOException {
            byte[] entryBytes;
            try (InputStream inputStream = jarFile.getInputStream(jarFile.getEntry(this.getZipEntry()))) {
                entryBytes = IOUtils.toByteArray(inputStream);
                for (Map.Entry entry : this.getReplacements().entrySet()) {
                    if (!BytesUtils.isExist(entryBytes, entry.getKey())) {
                        throw new IllegalStateException(String.format("can't find [%s] in [%s@%s] to replace it!", Arrays.toString(entry.getKey()), this.getZipEntry(), jarFile.getName()));
                    }
                    entryBytes = BytesUtils.replace(entryBytes, entry.getKey(), entry.getValue());
                }
            }
            FileUtils.writeByteArrayToFile(this.getSavePath(), entryBytes);
        }

        public String getZipEntry() {
            return zipEntry;
        }

        public File getSavePath() {
            return savePath;
        }

        public Map getReplacements() {
            return replacements;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy