1 /* 2 * Copyright (c) 2005, 2006 Imola Informatica. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the LGPL License v2.1 5 * which accompanies this distribution, and is available at 6 * http://www.gnu.org/licenses/lgpl.html 7 */ 8 9 10 package it.imolinfo.jbi4cics.jbi; 11 12 import it.imolinfo.jbi4cics.Logger; 13 import it.imolinfo.jbi4cics.LoggerFactory; 14 import java.util.HashMap; 15 import java.util.Map; 16 17 /** 18 * A class loader implementation able to receive class definition that will be 19 * found and defined on request. 20 * 21 * @author <a href="mailto:rspazzoli@imolinfo.it">Raffaele Spazzoli</a> 22 * @author <a href="mailto:mcimatti@imolinfo.it">Marco Cimatti</a> 23 */ 24 public final class BCELClassLoader extends ClassLoader { 25 26 /** 27 * The logger for this class and its instances. 28 */ 29 private static final Logger LOG 30 = LoggerFactory.getLogger(BCELClassLoader.class); 31 32 /** 33 * The responsible to translate localized messages. 34 */ 35 private static final Messages MESSAGES 36 = Messages.getMessages(BCELClassLoader.class); 37 38 /** 39 * The bytecode of the classes added to (and loaded by) this 40 * <code>ClassLoader</code>, indexed by their name. 41 * 42 * @see #addClass(String, byte[]) 43 */ 44 private Map<String, byte[]> classesCode = new HashMap<String, byte[]>(); 45 46 /** 47 * Creates a new class loader using the specified parent class loader for 48 * delegation. 49 * 50 * @param parent the parent class loader. 51 */ 52 public BCELClassLoader(final ClassLoader parent) { 53 super(parent); 54 } 55 56 /** 57 * Adds a new class data to this class loader. After a call to this method, 58 * this class loader is able to find and define the new specified class, if 59 * parameters are valid. 60 * 61 * @param className the complete class name. Must be not 62 * <code>null</code>. 63 * @param bytecode the bytecode of the new class. Must be not 64 * <code>null</code> and it is considered all its 65 * content, starting from offset 0 and ending at offset 66 * <code>bytecode.length</code> - 1. It is recommended 67 * that the caller doesn't modify its content, because 68 * this array is cached <i>as is</i>, without cloning it. 69 */ 70 public void addClass(final String className, final byte[] bytecode) { 71 classesCode.put(className, bytecode); 72 } 73 74 /** 75 * Finds the class with the specified binary name, searching in the pool of 76 * classes added by the {@link #addClass(String, byte[])} method. 77 * 78 * @param name the binary name of the class. 79 * @return the resulting <code>Class</code> object. 80 * @throws ClassNotFoundException if the class could not be found, because 81 * it's not been added to this class 82 * loader. 83 * @see #addClass(String, byte[]) 84 */ 85 @Override 86 protected Class<?> findClass(final String name) // Overridden 87 throws ClassNotFoundException { 88 byte[] bytecode = classesCode.get(name); 89 90 if (LOG.isDebugEnabled()) { 91 LOG.debug("findClass(" + name + ")"); 92 } 93 94 if (bytecode == null) { // Should never happen 95 throw new ClassNotFoundException( 96 MESSAGES.getString("CIC001042_Class_not_found", name)); 97 } 98 return defineClass(name, bytecode, 0, bytecode.length); 99 } 100 }