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

com.adobe.campaign.tests.bridge.service.IntegroBridgeClassLoader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2022 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it.
 */
package com.adobe.campaign.tests.bridge.service;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class IntegroBridgeClassLoader extends ClassLoader {
    private static final Logger log = LogManager.getLogger();
    private Set secretSet;
    private Set headerSet;
    private Map callResultCache;

    private Set packagePaths;

    /**
     * Parent ClassLoader passed to this constructor
     * will be used if this ClassLoader can not resolve a
     * particular class.
     */
    public IntegroBridgeClassLoader() {
        super(IntegroBridgeClassLoader.class.getClassLoader());
        setPackagePaths(ConfigValueHandlerIBS.STATIC_INTEGRITY_PACKAGES.fetchValue());
        this.setCallResultCache(new HashMap<>());
        this.setHeaderSet(new HashSet<>());
        this.setSecretSet(new HashSet<>());
    }

    /**
     * Loads a given class from .class file just like
     * the default ClassLoader. This method could be
     * changed to load the class over network from some
     * other server or from the database.
     *
     * @param in_classPath Full class name
     */
    private synchronized  Class getClass(String in_classPath) throws ClassNotFoundException {

        // is this class already loaded?
            Class cls = super.findLoadedClass(in_classPath);
        if (cls != null) {
            log.trace("Class {} has already been loaded.",in_classPath);
            return cls;
        } else {
            log.trace("Class {} has not been loaded. Loading now.", in_classPath);
        }


        // We are getting a name that looks like
        // javablogging.package.ClassToLoad
        // and we have to convert it into the .class file name
        // like javablogging/package/ClassToLoad.class
        String file = in_classPath.replace('.', '/')
                + ".class";

        try {
            // This loads the byte code data from the file
            byte[] b = loadClassData(file);
            // defineClass is inherited from the ClassLoader class
            // and converts the byte array into a Class
            cls = defineClass(in_classPath, b, 0, b.length);
            resolveClass(cls);
            return cls;
        } catch (IOException e) {
            log.error("Encountered IOException ",e);
            return null;
        }
    }

    /**
     * Every request for a class passes through this method. We have three rules that apply here:
     * 
    *
  1. In automatic integrity management, we load the accessed classes when needed.
  2. *
  3. In manual/semi-manual integrity management, we load the class if it is part of the defined packages
  4. *
  5. Otherwise, and when the class is in the "java" package, we load it using the system class loader
  6. *
* If not, it will use the super.loadClass() method * which in turn will pass the request to the parent. * * @param in_classFullPath * Full class name */ @Override public Class loadClass(String in_classFullPath) throws ClassNotFoundException { log.trace("Preparing class {}", in_classFullPath); if (ConfigValueHandlerIBS.INTEGRITY_PACKAGE_INJECTION_MODE.is("manual", "semi-manual")) { if (isClassAmongPackagePaths(in_classFullPath)) { return getClass(in_classFullPath); } } /* Removing until issue #45 is resolved else if (!in_classFullPath.startsWith("java")) { return getClass(in_classFullPath); } */ return super.loadClass(in_classFullPath); } /** * Loads a given file (presumably .class) into a byte array. The file should be accessible as a resource, for * example it could be located on the classpath. * * @param name File name to load * @return Byte array read from the file * @throws IOException Is thrown when there was some problem reading the file */ private byte[] loadClassData(String name) throws IOException, ClassNotFoundException { // Opening the file InputStream stream = getClass().getClassLoader() .getResourceAsStream(name); if (stream == null) { throw new ClassNotFoundException("The given class path " + name + " could not be found."); } int size = stream.available(); byte buff[] = new byte[size]; DataInputStream in = new DataInputStream(stream); // Reading the binary data in.readFully(buff); in.close(); return buff; } public Map getCallResultCache() { return callResultCache; } public void setCallResultCache(Map callResultCache) { this.callResultCache = callResultCache; } public Set getPackagePaths() { return packagePaths; } public void setPackagePaths(Set packagePaths) { this.packagePaths = packagePaths; } public void setPackagePaths(String in_packagePaths) { setPackagePaths(in_packagePaths.isEmpty() ? new HashSet<>() : new HashSet<>( Arrays.asList(in_packagePaths.split(",")))); } /** * Lets us know if the given class path is included in the classes that are to be managed by the class loader * @param in_classFullPath A full class path (package + Class name) * @return true if the given class path is among the stored package paths */ public boolean isClassAmongPackagePaths(String in_classFullPath) { return getPackagePaths().stream().anyMatch(in_classFullPath::startsWith); } /** * Checks if a class is loaded by the class loader * @param typeName Is the full name of the class that we want to see if it is loaded * @return true if the class has been loaded by the IBSClassLoader */ public boolean isClassLoaded(String typeName) { return !(findLoadedClass(typeName)==null); } public Set getHeaderSet() { return headerSet; } public void setHeaderSet(Set headerSet) { this.headerSet = headerSet; } public Set getSecretSet() { return secretSet; } public void setSecretSet(Set secretSet) { this.secretSet = secretSet; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy