1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.openjpa.util;
20
21 import java.security.AccessController;
22 import java.security.PrivilegedActionException;
23 import java.lang.reflect.Constructor;
24
25 import org.apache.openjpa.lib.util.J2DoPrivHelper;
26 import org.apache.openjpa.lib.util.Localizer;
27 import serp.bytecode.BCClass;
28 import serp.bytecode.BCClassLoader;
29
30 /**
31 * Utility methods when generating classes, including at runtime.
32 *
33 * @since 1.0.0
34 */
35 public class GeneratedClasses {
36
37 /**
38 * Return the more derived loader of the class laoders for the given
39 * classes.
40 */
41 public static ClassLoader getMostDerivedLoader(Class c1, Class c2) {
42 ClassLoader l1 = (ClassLoader) AccessController.doPrivileged(
43 J2DoPrivHelper.getClassLoaderAction(c1));
44 ClassLoader l2 = (ClassLoader) AccessController.doPrivileged(
45 J2DoPrivHelper.getClassLoaderAction(c2));
46 if (l1 == l2)
47 return l1;
48 if (l1 == null)
49 return l2;
50 if (l2 == null)
51 return l1;
52
53 if(canLoad(l1, c2)) {
54 return l1;
55 }
56 return l2;
57 }
58
59 /**
60 * Load the class represented by the given bytecode.
61 */
62 public static Class loadBCClass(BCClass bc, ClassLoader loader) {
63 BCClassLoader bcloader = (BCClassLoader) AccessController
64 .doPrivileged(J2DoPrivHelper.newBCClassLoaderAction(bc
65 .getProject(), loader));
66 try {
67 Class c = Class.forName(bc.getName(), true, bcloader);
68 bc.getProject().clear();
69 return c;
70 } catch (Throwable t) {
71 throw new GeneralException(bc.getName()).setCause(t);
72 }
73 }
74
75 /**
76 * Return true if the given loader will load the same version of a given
77 * class.
78 *
79 * @param loader Classloader to use.
80 * @param clazz Expected class.
81 * @return true if loader.load(clazz.getName()) == clazz. Otherwise false.
82 */
83 private static boolean canLoad(ClassLoader loader, Class clazz) {
84 Class loaded = null;
85 try {
86 loaded = loader.loadClass(clazz.getName());
87 } catch (ClassNotFoundException e) {
88 // Rely on caller to handle return value = false.
89 }
90 return clazz == loaded;
91 }
92 }