/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.oxm.classloader;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;


/**
 * This class is an implementation of the <code>ClassLoader</code> abstract class.
 * Its purpose is to allow the ability to load a class from
 * a particular JAR file without regard to the system class path.
 *
 * @author Big Country
 * @since TOPLink/Java 3.0
 */
public class JARClassLoader extends ClassLoader {
    /** Map each package name to the appropriate JAR file. */
    private Hashtable<String, String> overridePackageNames;

/**
 * Default constructor - initialize the new instance.
 */
protected JARClassLoader() {
    super();
    this.initialize();
}
/**
 * Construct a file loader for the JAR files.
 */
public JARClassLoader (String[] jarFileNames) {
    this();
    this.initialize(jarFileNames);
}
/**
 * Construct a file loader for the JAR file.
 */
public JARClassLoader (String jarFileName) {
    this();
    this.initialize(jarFileName);
}
/**
 * Build and return a ZIP file for the specified JAR file name.
 */
protected ZipFile buildJARFile(String jarFileName) {
    try {
        return new ZipFile(new File(Thread.currentThread().getContextClassLoader().getResource(jarFileName).toURI()));
    } catch (IOException | URISyntaxException e) {
        throw new RuntimeException(e);
    }
}
/**
 * Return the package name for the specified class.
 */
protected String buildPackageName(String className) {
    return className.substring(0, className.lastIndexOf("."));
}
/**
 * Return the class for the specified name, leaving it "unresolved".
 */
protected Class<?> customLoadUnresolvedClass(String className) throws ClassNotFoundException {
    String jarFileName = overridePackageNames.get(this.buildPackageName(className));
    ZipFile jarFile = this.buildJARFile(jarFileName);

    String url = className.replace('.', '/').concat(".class");
    ZipEntry jarEntry = jarFile.getEntry(url);
  if(jarEntry == null){
    return this.getParent().loadClass(className);
  }
    byte[] data;
    try {
        data = this.loadData(jarFile, jarEntry);
        jarFile.close();
    } catch (IOException e) {
        throw new ClassNotFoundException();
    }
    return this.defineClass(className, data, 0, data.length);
}
/**
 * Extract the package names from the specified JAR file
 * and store them in the hashtable.
 */
protected void extractPackageNames(String jarFileName) {
    Enumeration<? extends ZipEntry> stream = this.buildJARFile(jarFileName).entries();
    while (stream.hasMoreElements()) {
        String entryName = stream.nextElement().getName();
        int endIndex = entryName.lastIndexOf("/");
        // skip over entries for files in the root directory and directories
        if ((endIndex != -1) && (endIndex != (entryName.length() - 1))) {
            String packageName = (entryName.substring(0, endIndex)).replace('/', '.');
            // skip over JAR META-INF directory
            if (! packageName.equals("META-INF")) {
                overridePackageNames.put(packageName, jarFileName);
            }
        }
    }
}
/**
 * Initialize the newly-created instance.
 */
protected void initialize() {
    this.overridePackageNames = new Hashtable<>();
}
/**
 * Initialize
 */
protected void initialize(String[] jarFileNames) {
    if (jarFileNames == null) {
        throw new IllegalArgumentException();
    }
    // go backwards to maintain search order (earlier packages will overlay later ones)
    for (int i = jarFileNames.length - 1; i >= 0; i--) {
        this.extractPackageNames(jarFileNames[i]);
    }
}
/**
 * Initialize
 */
protected void initialize(String jarFileName) {
    if (jarFileName == null) {
        throw new IllegalArgumentException();
    }
    this.initialize(new String[] {jarFileName});
}
/**
 * Return the class for the specified name, resolving it if necessary.
 */
@Override
protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
    Class<?> c = this.loadUnresolvedClass(className);
    if (resolve) {
        this.resolveClass(c);
    }
    return c;
}
/**
 * Return a byte array holding the contents of the specified file.
 */
protected byte[] loadData(ZipFile jarFile, ZipEntry jarEntry) throws IOException {

    int size = (int) jarEntry.getSize();
    byte[] buffer = new byte[size];

    DataInputStream stream = new DataInputStream(jarFile.getInputStream(jarEntry));
    stream.readFully(buffer);
    stream.close();

    return buffer;
}
/**
 * Return the class for the specified name.
 */
protected Class<?> loadUnresolvedClass(String className) throws ClassNotFoundException {
    // check whether we already loaded the class
    Class<?> c = this.findLoadedClass(className);
    if (c != null) {
        return c;
    }
    // check whether we should custom load the class
    if (this.shouldCustomLoad(className)) {
        return this.customLoadUnresolvedClass(className);
    } else {
        final ClassLoader cl = PrivilegedAccessHelper.callDoPrivileged(
                () -> PrivilegedAccessHelper.getClassLoaderForClass(this.getClass())
        );
        if (cl == null) {
            // this should only occur under jdk1.1.x
            return this.findSystemClass(className);
        } else {
            return cl.loadClass(className);
        }
    }
}
/**
 * Return whether the specified class should be custom loaded.
 * If it is a member of one of the override packages, it should be
 * custom loaded.
 */
protected boolean shouldCustomLoad(String className) {
    return overridePackageNames.containsKey(this.buildPackageName(className));
}
}
