001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.engine.util;
029:
030: import java.io.ByteArrayOutputStream;
031: import java.io.File;
032: import java.io.FileInputStream;
033: import java.io.IOException;
034: import java.security.ProtectionDomain;
035:
036: /**
037: * @author Teodor Danciu (teodord@users.sourceforge.net)
038: * @version $Id: JRClassLoader.java 1750 2007-06-11 16:29:42Z teodord $
039: */
040: public class JRClassLoader extends ClassLoader {
041:
042: private static ProtectionDomain protectionDomain = null;
043:
044: /**
045: *
046: */
047: public static ProtectionDomain getProtectionDomain() {
048: if (protectionDomain == null) {
049: protectionDomain = JRClassLoader.class
050: .getProtectionDomain();
051: }
052:
053: return protectionDomain;
054: }
055:
056: /**
057: * Sets the protection to be used for classes loaded via
058: * the {@link #loadClassFromBytes(String, byte[]) loadClassFromBytes} method.
059: *
060: * By default, the protection domain of this class is used for the loaded classes.
061: *
062: * @param protectionDomain the protection domain to be used
063: * @see #loadClassFromBytes(String, byte[])
064: */
065: public static void setProtectionDomain(
066: ProtectionDomain protectionDomain) {
067: JRClassLoader.protectionDomain = protectionDomain;
068: }
069:
070: /**
071: *
072: */
073: protected JRClassLoader() {
074: super ();
075: }
076:
077: /**
078: *
079: */
080: protected JRClassLoader(ClassLoader parent) {
081: super (parent);
082: }
083:
084: /**
085: *
086: */
087: public static Class loadClassForName(String className)
088: throws ClassNotFoundException {
089: Class clazz = null;
090:
091: String classRealName = className;
092: ClassNotFoundException initialEx = null;
093:
094: try {
095: clazz = loadClassForRealName(classRealName);
096: } catch (ClassNotFoundException e) {
097: initialEx = e;
098: }
099:
100: int lastDotIndex = 0;
101: while (clazz == null
102: && (lastDotIndex = classRealName.lastIndexOf('.')) > 0) {
103: classRealName = classRealName.substring(0, lastDotIndex)
104: + "$" + classRealName.substring(lastDotIndex + 1);
105: try {
106: clazz = loadClassForRealName(classRealName);
107: } catch (ClassNotFoundException e) {
108: }
109: }
110:
111: if (clazz == null) {
112: throw initialEx;
113: }
114:
115: return clazz;
116: }
117:
118: /**
119: *
120: */
121: public static Class loadClassForRealName(String className)
122: throws ClassNotFoundException {
123: Class clazz = null;
124:
125: ClassLoader classLoader = Thread.currentThread()
126: .getContextClassLoader();
127: if (classLoader != null) {
128: try {
129: clazz = Class.forName(className, true, classLoader);
130: } catch (ClassNotFoundException e) {
131: //if (log.isWarnEnabled())
132: // log.warn("Failure using Thread.currentThread().getContextClassLoader() in JRClassLoader class. Using JRClassLoader.class.getClassLoader() instead.");
133: }
134: }
135:
136: if (clazz == null) {
137: classLoader = JRClassLoader.class.getClassLoader();
138: if (classLoader == null) {
139: clazz = Class.forName(className);
140: } else {
141: clazz = Class.forName(className, true, classLoader);
142: }
143: }
144:
145: return clazz;
146: }
147:
148: /**
149: * @deprecated To be removed in future versions.
150: */
151: public static Class loadClassFromFile(String className, File file)
152: throws IOException {
153: Class clazz = null;
154:
155: ClassLoader classLoader = Thread.currentThread()
156: .getContextClassLoader();
157: if (classLoader != null) {
158: try {
159: clazz = (new JRClassLoader(classLoader)).loadClass(
160: className, file);
161: } catch (NoClassDefFoundError e) {
162: //if (log.isWarnEnabled())
163: // log.warn("Failure using Thread.currentThread().getContextClassLoader() in JRClassLoader class. Using JRClassLoader.class.getClassLoader() instead.");
164: }
165: }
166:
167: if (clazz == null) {
168: classLoader = JRClassLoader.class.getClassLoader();
169: if (classLoader == null) {
170: clazz = (new JRClassLoader())
171: .loadClass(className, file);
172: } else {
173: clazz = (new JRClassLoader(classLoader)).loadClass(
174: className, file);
175: }
176: }
177:
178: return clazz;
179: }
180:
181: /**
182: *
183: */
184: public static Class loadClassFromBytes(String className,
185: byte[] bytecodes) {
186: Class clazz = null;
187:
188: ClassLoader classLoader = Thread.currentThread()
189: .getContextClassLoader();
190: if (classLoader != null) {
191: try {
192: clazz = (new JRClassLoader(classLoader)).loadClass(
193: className, bytecodes);
194: } catch (NoClassDefFoundError e) {
195: //if (log.isWarnEnabled())
196: // log.warn("Failure using Thread.currentThread().getContextClassLoader() in JRClassLoader class. Using JRClassLoader.class.getClassLoader() instead.");
197: }
198: }
199:
200: if (clazz == null) {
201: classLoader = JRClassLoader.class.getClassLoader();
202: if (classLoader == null) {
203: clazz = (new JRClassLoader()).loadClass(className,
204: bytecodes);
205: } else {
206: clazz = (new JRClassLoader(classLoader)).loadClass(
207: className, bytecodes);
208: }
209: }
210:
211: return clazz;
212: }
213:
214: /**
215: * @deprecated To be removed in future versions.
216: */
217: protected Class loadClass(String className, File file)
218: throws IOException {
219: FileInputStream fis = null;
220: ByteArrayOutputStream baos = null;
221:
222: byte[] bytecodes = new byte[10000];
223: int ln = 0;
224:
225: try {
226: fis = new FileInputStream(file);
227: baos = new ByteArrayOutputStream();
228:
229: while ((ln = fis.read(bytecodes)) > 0) {
230: baos.write(bytecodes, 0, ln);
231: }
232:
233: baos.flush();
234: } finally {
235: if (baos != null) {
236: try {
237: baos.close();
238: } catch (IOException e) {
239: }
240: }
241:
242: if (fis != null) {
243: try {
244: fis.close();
245: } catch (IOException e) {
246: }
247: }
248: }
249:
250: return loadClass(className, baos.toByteArray());
251: }
252:
253: /**
254: *
255: */
256: protected Class loadClass(String className, byte[] bytecodes) {
257: Class clazz = null;
258:
259: clazz = defineClass(className, bytecodes, 0, bytecodes.length,
260: getProtectionDomain());
261:
262: return clazz;
263: }
264:
265: /**
266: *
267: */
268: public static String getClassRealName(String className) {
269: if (className == null) {
270: return null;
271: }
272:
273: int arrayDimension = 0;
274: int classNameEnd = className.length();
275: int index = 0;
276: int pos = 0;
277: while (index < classNameEnd
278: && (pos = className.indexOf('[', index)) >= 0) {
279: if (index == 0) {
280: classNameEnd = pos;
281: }
282: index = pos;
283: arrayDimension++;
284: }
285:
286: if (arrayDimension > 0) {
287: StringBuffer sbuffer = new StringBuffer();
288:
289: for (int i = 0; i < arrayDimension; i++) {
290: sbuffer.append('[');
291: }
292:
293: sbuffer.append('L');
294: sbuffer.append(className.substring(0, classNameEnd));
295: sbuffer.append(';');
296:
297: return sbuffer.toString();
298: }
299:
300: return className;
301: }
302:
303: }
|