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

com.epam.deltix.util.lang.MultiByteArrayClassLoader Maven / Gradle / Ivy

/*
 * Copyright 2021 EPAM Systems, Inc
 *
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. Licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.epam.deltix.util.lang;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;

import com.epam.deltix.util.io.IOUtil;

/**  
 * Variation of SingleByteArrayClassLoader that supports nested classes.
 * 
 * It is used by JavaCompilationWorkspace to load auto-generated cursor classes.
 * 
 * NOTE: Only classes that belong to default package are supported ! 
 */
public class MultiByteArrayClassLoader extends ClassLoader {
	
	private final String [] classNames;
	private final byte [] [] classBytes;
	
	public MultiByteArrayClassLoader (File rootDir, final String className) 
		throws ClassNotFoundException 
	{
		final File[] classFiles = rootDir.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				if (name.startsWith(className) && name.endsWith(".class")) {
					char ch = name.charAt(className.length()); 
					return ch == '.' || ch == '$';
				}
				return false;
			}
		});
		
		final int numClasses = classFiles.length;
		classNames = new String [numClasses];
		classBytes = new byte [numClasses][];
		for (int i=0; i < numClasses; i++) {
			File classFile = classFiles [i];
			String fileName = classFile.getName();
			classNames [i] = fileName.substring(0, fileName.length() - 6); // cut ".class"
			classBytes [i] = loadClassBytes (classFile);
		}
		
		for (int i=0; i < numClasses; i++) 
			classFiles [i].delete();
	}

	@Override
    public InputStream      getResourceAsStream (String name) {
		final int numClasses = classNames.length;
		for (int i=0; i < numClasses; i++) 
			if (classNames[i].equals(name))
				return new ByteArrayInputStream (classBytes[i]);
		
		return null;
    }

	@Override
    protected Class              findClass (String name)
	    throws ClassNotFoundException
	{
		final int numClasses = classNames.length;
		for (int i=0; i < numClasses; i++) { 
			if (classNames[i].equals(name)) {
				byte [] b = classBytes[i];
				return defineClass (name, b, 0, b.length);
			}
		}
		throw new ClassNotFoundException (name);
	}
	
    private static byte [] loadClassBytes (File classFile)
	    throws ClassNotFoundException 
	{
	    try {
	        return (IOUtil.readBytes (classFile));
	    } catch (IOException iox) {
	        throw new ClassNotFoundException (
	            "Failed to read file: " + classFile + " due to: " + iox, 
	            iox
	        );
	    }
	}
	
	public static Class loadClass(File workingDir, String className) 
		throws ClassNotFoundException
	{
		return new MultiByteArrayClassLoader (workingDir, className).loadClass (className);
	}
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy