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

com.espertech.esper.compiler.client.util.EPCompiledIOUtil Maven / Gradle / Ivy

There is a newer version: 9.0.0
Show newest version
/*
 ***************************************************************************************
 *  Copyright (C) 2006 EsperTech, Inc. All rights reserved.                            *
 *  http://www.espertech.com/esper                                                     *
 *  http://www.espertech.com                                                           *
 *  ---------------------------------------------------------------------------------- *
 *  The software in this package is published under the terms of the GPL license       *
 *  a copy of which has been included with this distribution in the license.txt file.  *
 ***************************************************************************************
 */
package com.espertech.esper.compiler.client.util;

import com.espertech.esper.common.client.EPCompiled;
import com.espertech.esper.common.client.EPCompiledManifest;

import java.io.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.*;

/**
 * IO-related utilized for {@link EPCompiled}
 */
public class EPCompiledIOUtil {
    /**
     * Name of the attribute providing the compiler version.
     */
    public final static String MANIFEST_COMPILER_VERSION = "Esper-CompilerVersion";

    /**
     * Name of the attribute providing the module provider class name.
     */
    public final static String MANIFEST_MODULEPROVIDERCLASSNAME = "Esper-ModuleProvider";

    /**
     * Name of the attribute providing the fire-and-forget query provider class name.
     */
    public final static String MANIFEST_QUERYPROVIDERCLASSNAME = "Esper-QueryProvider";

    /**
     * Write the compiled to a jar file. Overwrites the existing jar file.
     *
     * @param compiled compiled
     * @param file     the target file
     * @throws IOException when the write failed
     */
    public static void write(EPCompiled compiled, File file) throws IOException {

        Manifest manifest = new Manifest();
        manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
        manifest.getMainAttributes().put(new Attributes.Name(MANIFEST_COMPILER_VERSION), compiled.getManifest().getCompilerVersion());
        manifest.getMainAttributes().put(new Attributes.Name(MANIFEST_MODULEPROVIDERCLASSNAME), compiled.getManifest().getModuleProviderClassName());
        manifest.getMainAttributes().put(new Attributes.Name(MANIFEST_QUERYPROVIDERCLASSNAME), compiled.getManifest().getQueryProviderClassName());

        JarOutputStream target = new JarOutputStream(new FileOutputStream(file), manifest);

        try {
            for (Map.Entry entry : compiled.getClasses().entrySet()) {
                write(entry.getKey(), entry.getValue(), target);
            }
        } finally {
            target.close();
        }
    }

    /**
     * Reads the jar file into an {@link EPCompiled} compiled for deployment into a runtime.
     *
     * @param file is the source jar file
     * @return compiled
     * @throws IOException when the read failed
     */
    public static EPCompiled read(File file) throws IOException {
        JarFile jarFile = new JarFile(file);

        Attributes attributes = jarFile.getManifest().getMainAttributes();
        String compilerVersion = getAttribute(attributes, MANIFEST_COMPILER_VERSION);
        if (compilerVersion == null) {
            throw new IOException("Manifest is missing " + MANIFEST_COMPILER_VERSION);
        }
        String moduleProvider = getAttribute(attributes, MANIFEST_MODULEPROVIDERCLASSNAME);
        String queryProvider = getAttribute(attributes, MANIFEST_QUERYPROVIDERCLASSNAME);
        if (moduleProvider == null && queryProvider == null) {
            throw new IOException("Manifest is missing both " + MANIFEST_MODULEPROVIDERCLASSNAME + " and " + MANIFEST_QUERYPROVIDERCLASSNAME);
        }

        Map classes = new HashMap<>();
        try {
            Enumeration entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                read(jarFile, entries.nextElement(), classes);
            }

        } finally {
            jarFile.close();
        }

        return new EPCompiled(classes, new EPCompiledManifest(compilerVersion, moduleProvider, queryProvider));
    }

    private static String getAttribute(Attributes attributes, String name) {
        Attributes.Name attr = new Attributes.Name(name);
        String value = attributes.getValue(attr);
        if (value == null || value.equals("null")) {
            return null;
        }
        return value;
    }

    private static void write(String name, byte[] value, JarOutputStream target) throws IOException {
        name = name.replace(".", "/") + ".class";
        JarEntry entry = new JarEntry(name);
        entry.setTime(System.currentTimeMillis());
        target.putNextEntry(entry);
        target.write(value, 0, value.length);
        target.closeEntry();
    }

    private static void read(JarFile jarFile, JarEntry jarEntry, Map classes) throws IOException {
        if (jarEntry.isDirectory() || jarEntry.getName().equals("META-INF/MANIFEST.MF")) {
            return;
        }

        long size = jarEntry.getSize();
        if (size > Integer.MAX_VALUE - 1) {
            throw new IOException("Encountered jar entry with size " + size + " greater than max integer size");
        }

        InputStream in = jarFile.getInputStream(jarEntry);
        byte[] bytes;
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            bytes = os.toByteArray();
        } finally {
            in.close();
        }

        String className = jarEntry.getName().replace("/", ".");
        if (className.endsWith(".class")) {
            className = className.substring(0, className.length() - 6);
        }
        classes.put(className, bytes);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy