/*
 * 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.*;
import java.net.URISyntaxException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.*;
import java.util.zip.*;

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


/**
 * 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 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 e) {
        throw new RuntimeException(e);
    } catch (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 = (String) 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) {
        Object[] args = {jarFileName, url};
        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 stream = this.buildJARFile(jarFileName).entries();
    while (stream.hasMoreElements()) {
        String entryName = ((ZipEntry) 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 {
        ClassLoader cl = null;
        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
            try{
                cl = AccessController.doPrivileged(new PrivilegedGetClassLoaderForClass(this.getClass()));
            }catch (PrivilegedActionException ex){
                throw (RuntimeException)ex.getCause();
            }
        }else{
             cl = 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));
}
}
