001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.harmony.lang.reflect.support;
018:
019: import java.security.AccessController;
020: import java.security.PrivilegedAction;
021: import java.lang.reflect.Member;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.InvocationTargetException;
024:
025: /**
026: * @author Serguei S. Zapreyev
027: * @version $Revision: 1.1.2.1 $
028: */
029:
030: /**
031: * Loader provides access to some of finding.
032: *
033: * (This should be considered as a temporary decision. A correct approach
034: * in using loader facilities should be implemented later.)
035: */
036: public final class AuxiliaryLoader {
037:
038: public static Class<?> findClass(final String classTypeName,
039: Object startPoint) throws ClassNotFoundException {
040: if (classTypeName.equals("byte")) {
041: return byte.class;
042: } else if (classTypeName.equals("char")) {
043: return char.class;
044: } else if (classTypeName.equals("double")) {
045: return double.class;
046: } else if (classTypeName.equals("float")) {
047: return float.class;
048: } else if (classTypeName.equals("int")) {
049: return int.class;
050: } else if (classTypeName.equals("long")) {
051: return long.class;
052: } else if (classTypeName.equals("short")) {
053: return short.class;
054: } else if (classTypeName.equals("boolean")) {
055: return boolean.class;
056: } else if (classTypeName.equals("void")) {
057: return void.class;
058: }
059: final ClassLoader loader = getClassLoader(startPoint);
060: Class c = (Class) AccessController
061: .doPrivileged(new PrivilegedAction<Object>() {
062: public Object run() {
063: try {
064: Method loadClassMethod = findLoadClassMethod(loader
065: .getClass());
066: loadClassMethod.setAccessible(true);
067: return (Object) loadClassMethod
068: .invoke(
069: (Object) loader,
070: new Object[] {
071: (Object) AuxiliaryFinder
072: .transform(classTypeName),
073: new Boolean(false) });
074: } catch (IllegalAccessException e) {
075: System.err
076: .println("Error: AuxiliaryLoader.findClass("
077: + classTypeName
078: + "): "
079: + e.toString());
080: e.printStackTrace();
081: } catch (InvocationTargetException e) {
082: System.err
083: .println("Error: AuxiliaryLoader.findClass("
084: + classTypeName
085: + "): "
086: + e.getTargetException());
087: e.getTargetException().printStackTrace();
088: } catch (Exception e) {
089: System.err
090: .println("Error: AuxiliaryLoader.findClass("
091: + classTypeName
092: + "): "
093: + e.toString());
094: e.printStackTrace();
095: }
096: return null;
097: }
098: });
099:
100: if (c == null) {
101: throw new ClassNotFoundException(classTypeName);
102: }
103: return c;
104: }
105:
106: /**
107: * @param startPoint an instance of the Class, Method, Constructor or Field
108: * type to start the search of a type variable declaration place.
109: */
110: private static ClassLoader getClassLoader(Object startPoint) {
111: ClassLoader res = null;
112:
113: if (startPoint instanceof Class) {
114: res = ((Class) startPoint).getClassLoader();
115: } else if (startPoint instanceof Member) {
116: res = ((Member) startPoint).getDeclaringClass()
117: .getClassLoader();
118: } else {
119: res = startPoint.getClass().getClassLoader();
120: }
121:
122: if (res == null) {
123: res = ClassLoader.getSystemClassLoader();
124: }
125: return res;
126: }
127:
128: /**
129: * Looks for loadClass(String name, boolean resolve) Method in the
130: * specified 'loader' class (of the type ClassLoader) or its super class.
131: */
132: private static Method findLoadClassMethod(Class loaderClass) {
133: Method res = null;
134: Method[] ms = loaderClass.getDeclaredMethods();
135:
136: for (int i = 0; i < ms.length; i++) {
137: if (!ms[i].getName().equals("loadClass")) {
138: continue;
139: }
140:
141: if (ms[i].getParameterTypes().length != 2) {
142: continue;
143: }
144:
145: if (!ms[i].getParameterTypes()[0].getName().equals(
146: "java.lang.String")) {
147: continue;
148: }
149:
150: if (!ms[i].getParameterTypes()[1].getName().equals(
151: "boolean")) {
152: continue;
153: }
154: res = ms[i];
155: break;
156: }
157:
158: // no null check is required - at leas this methopd will be found in
159: // java.lang.ClassLoader
160: return res != null ? res : findLoadClassMethod(loaderClass
161: .getSuperclass());
162: }
163:
164: public static void resolve(final Class c) {
165: AccessController
166: .doPrivileged(new java.security.PrivilegedAction<Object>() {
167: public Object run() {
168: ClassLoader loader = getClassLoader(c);
169:
170: try {
171: Method loadClassMethod = findLoadClassMethod(loader
172: .getClass());
173: loadClassMethod.setAccessible(true);
174: loadClassMethod
175: .invoke(
176: (Object) loader,
177: new Object[] {
178: (Object) c
179: .getCanonicalName(),
180: (Object) true });
181: } catch (java.lang.IllegalAccessException _) {
182: } catch (java.lang.reflect.InvocationTargetException _) {
183: }
184: return null;
185: }
186: });
187: }
188: }
|