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 }