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

com.github.xpenatan.gdx.backends.teavm.TeaClassLoader Maven / Gradle / Ivy

There is a newer version: 1.0.4
Show newest version
package com.github.xpenatan.gdx.backends.teavm;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

/**
 * @author xpenatan
 */
public class TeaClassLoader extends URLClassLoader {

    private URL[] jarFiles;
    private HashMap> fileMap = new HashMap<>();

    private final ArrayList skipClasses = new ArrayList<>();

    public TeaClassLoader(URL[] classPaths, ClassLoader parent, ArrayList skipClasses) {
        super(classPaths, parent);
        this.jarFiles = classPaths;
        this.skipClasses.addAll(skipClasses);
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        String fixName = name.replace(";.class", ".class");
        fixName = fixName.replace("[L", "");
        fixName = fixName.replace("[", "");

        String toPackage = fixName.replace("/", ".");
        if(containsSkipClass(toPackage)) {
            return null;
        }

        for(int i = 0; i < jarFiles.length; i++) {
            URL url = jarFiles[i];
            String path = url.getPath();
            File file = new File(path);
            if(file.exists()) {
                if(!file.isDirectory()) {
                    try {
                        JarFile jarFile = new JarFile(file);
                        ZipEntry entry = jarFile.getEntry(fixName);
                        if(entry != null) {
                            return jarFile.getInputStream(entry);
                        }
                    }
                    catch(Exception e) {
                        e.printStackTrace();
                    }
                }
                else {
                    // This probably not working and need to remove.
                    ArrayList allClasses = getAllFiles(path);
                    String resName = fixName.replace("\\", "/");
                    for(int j = 0; j < allClasses.size(); j++) {
                        String className = allClasses.get(j);
                        if(className.contains(resName)) {
                            return super.getResourceAsStream(name);
                        }
                    }
                }
            }
        }

        return super.getResourceAsStream(name);
    }

    private boolean containsSkipClass(String clazz) {
        for(int i = 0; i < skipClasses.size(); i++) {
            String name = skipClasses.get(i);
            if(clazz.contains(name)) {
                return true;
            }
        }
        return false;
    }

    private ArrayList getAllFiles(String path) {
        ArrayList paths = fileMap.get(path);
        if(paths == null) {
            File rootFile = new File(path);
            paths = new ArrayList<>();
            getAllFiles(rootFile, paths, "");
            fileMap.put(path, paths);
        }
        return paths;
    }

    private void getAllFiles(File rootFile, ArrayList out, String packageName) {
        String[] list = rootFile.list();
        if(list != null) {
            for(int i = 0; i < list.length; i++) {
                String subFileStr = list[i];
                File subFile = new File(rootFile, subFileStr);
                if(subFile.isDirectory()) {
                    String newPackage = packageName + subFileStr + "/";
                    getAllFiles(subFile, out, newPackage);
                }
                else {
                    String path = packageName + subFileStr;
                    path = path.replace("\\", "/");
                    out.add(path);
                }
            }
        }
    }

    /**
     * Convert packages to individual classes
     */
    public ArrayList getAllClasses(ArrayList classOrPackage) {
        // TeaVM only accept individual classes. We need to obtain all classes from package (if its set).
        // If it's not a package just add the class.
        ArrayList array = new ArrayList<>();

        for(int i = 0; i < classOrPackage.size(); i++) {
            String className = classOrPackage.get(i);
            String packagePath = className.replace(".", "/");
            URL resource = getResource(packagePath + ".class");
            if(resource == null) {
                // Should be a package
                addClasses(array, packagePath);
            }
            else {
                array.add(className);
            }
        }
        return array;
    }

    private void addClasses(ArrayList array, String packagePath) {
        for(int i = 0; i < jarFiles.length; i++) {
            URL url = jarFiles[i];
            String path = url.getPath();
            File file = new File(path);
            if(file.exists()) {
                if(!file.isDirectory()) {
                    try {
                        JarFile jarFile = new JarFile(file);
                        Enumeration entries = jarFile.entries();
                        while(entries.hasMoreElements()) {
                            JarEntry jarEntry = entries.nextElement();
                            String name = jarEntry.getName();
                            if(name.startsWith(packagePath)) {
                                if(name.endsWith(".class")) {
                                    String className = name.replace("\\", ".").replace("/", ".").replace(".class", "");
                                    array.add(className);
                                }
                            }
                        }
                    }
                    catch(Exception e) {
                        e.printStackTrace();
                    }
                }
                else {
                    ArrayList allClasses = getAllFiles(path);
                    for(int j = 0; j < allClasses.size(); j++) {
                        String name = allClasses.get(j);
                        if(name.startsWith(packagePath)) {
                            if(name.endsWith(".class")) {
                                String className = name.replace("\\", ".").replace("/", ".").replace(".class", "");
                                array.add(className);
                            }
                        }
                    }
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy