m3.classe.M3ClassLoader.java Source code

Java tutorial

Introduction

Here is the source code for m3.classe.M3ClassLoader.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package m3.classe;

import com.intentia.mak.core.m3.classpath.M3ClassPathEntry;
import com.intentia.mak.util.MAKException;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import main.Ressource;
import org.apache.commons.io.IOUtils;

public class M3ClassLoader extends ClassLoader {

    //    private static final Logger Ressource.logger. = Logger.getLogger(MovexClassLoader.class);
    private static final String FILE_EXTENSION_CLASS = "class";
    private static final String FILE_EXTENSION_JAR = "jar";
    private static final String FILE_EXTENSION_ZIP = "zip";
    private static final String FILE_EXTENSION_PROPERTIES = "properties";
    private List<File> m_classPaths;
    private Set<File> m_zipProblems;
    private Set<File> m_pathProblems;

    public M3ClassLoader(M3ClassPathEntry[] classPath) {
        this.m_classPaths = new ArrayList();
        for (M3ClassPathEntry entry : classPath) {
            this.m_classPaths.add(entry.getPath().toFile());
        }
        this.m_zipProblems = new HashSet();
        this.m_pathProblems = new HashSet();
    }

    public final URL getResource(String name) {
        return super.getResource(name);
    }

    public final InputStream getResourceAsStream(String name) {
        return super.getResourceAsStream(name);
    }

    public final Class findClass(String name) throws ClassNotFoundException {
        byte[] b = loadClassData(name);
        if (b == null) {
            throw new ClassNotFoundException(name);
        }
        return defineClass(name, b, 0, b.length);
    }

    private byte[] loadClassData(String name) {
        boolean classNotFound = true;
        byte[] bytes = (byte[]) null;
        int i = 0;
        label176: while ((classNotFound) && (i < this.m_classPaths.size())) {
            DataInputStream dis = null;
            try {
                File path = (File) this.m_classPaths.get(i++);
                if (this.m_pathProblems.contains(path)) {
                    IOUtils.closeQuietly(dis);
                } else if (path.exists()) {
                    dis = getStreamFromPath(name, path);
                    if (dis != null) {
                        classNotFound = false;
                        bytes = getBytesFromStream(dis);
                        break label176;
                    }
                } else {
                    Ressource.logger.warn(path + " could not be found/accessed on the M3 classpath");
                    this.m_pathProblems.add(path);
                }
            } catch (MAKException e) {
                Ressource.logger.error("Failed to load class data from " + name, e);
            } finally {
                IOUtils.closeQuietly(dis);
            }
        }
        return bytes;
    }

    private DataInputStream getStreamFromPath(String name, File path) throws MAKException {
        Exception exception;
        try {
            DataInputStream dis = null;
            if (path.isDirectory()) {
                dis = getStreamFromFolder(name, path);
            } else if ((!path.getAbsolutePath().endsWith("jar")) && (!path.getAbsolutePath().endsWith("zip"))) {
                dis = getStreamFromJar(name, path);
            }
            return dis;
        } catch (IOException e) {
            exception = e;
        } catch (MAKException e) {
            exception = e;
        }
        throw new MAKException("Failed to get stream for " + name + " from " + path, exception);
    }

    private byte[] getBytesFromStream(DataInputStream dis) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        byte[] bytes = (byte[]) null;
        int len = 0;
        try {
            while ((len = dis.read(buf)) > 0) {
                bos.write(buf, 0, len);
            }
            bytes = bos.toByteArray();
        } catch (IOException e) {
            Ressource.logger.error("Failed to get bytes from stream", e);
        } finally {
            IOUtils.closeQuietly(bos);
        }
        return bytes;
    }

    private DataInputStream getStreamFromJar(String name, File path) throws MAKException {
        if (!this.m_zipProblems.contains(path)) {
            try {
                DataInputStream dis = null;
                ZipFile file = new ZipFile(path);
                ZipEntry entry = file.getEntry(name.replace('.', '/') + '.' + "class");
                if (entry == null) {
                    entry = file.getEntry(name.replace('.', '/') + '.' + "properties");
                }
                if (entry != null)
                    ;
                return new DataInputStream(file.getInputStream(entry));
            } catch (IOException e) {
                Ressource.logger.warn("Failed to get " + name + " from jar " + path
                        + " - MAK will try again using another method", e);
                this.m_zipProblems.add(path);
            }
        }
        return getStreamFromJar2(name, path);
    }

    private DataInputStream getStreamFromJar2(String name, File path) throws MAKException {
        Exception exception;
        try {
            DataInputStream dis = null;
            InputStream is = null;
            is = new FileInputStream(path);
            ZipInputStream zis = new ZipInputStream(is);
            ZipEntry entry = findZipEntry(name, zis);
            if (entry != null)
                ;
            return new DataInputStream(zis);
        } catch (FileNotFoundException e) {
            exception = e;
        } catch (MAKException e) {
            exception = e;
        }
        throw new MAKException("Failed to get " + name + " from jar " + path, exception);
    }

    private ZipEntry findZipEntry(String name, ZipInputStream zis) throws MAKException {
        try {
            ZipEntry entry = null;
            String tmp = name.replace('.', '/') + ".";
            String match1 = tmp + "class";
            String match2 = tmp + "properties";
            while ((entry = zis.getNextEntry()) != null) {
                if ((entry.getName().equals(match1)) || (entry.getName().equals(match2))) {
                    return entry;
                }
            }
            return null;
        } catch (IOException e) {
            throw new MAKException("Failed to find entry " + name, e);
        }
    }

    private DataInputStream getStreamFromFolder(String name, File path) throws FileNotFoundException {
        DataInputStream dis = null;
        File file = new File(
                path.toString() + File.separator + name.replace('.', File.separatorChar) + '.' + "class");

        if (!file.exists()) {
            file = new File(
                    path.toString() + File.separator + name.replace('.', File.separatorChar) + '.' + "properties");
        }
        if (file.exists()) {
            dis = new DataInputStream(new FileInputStream(file));
        }
        return dis;
    }
}