Source Code Cross Referenced for ClassLoading.java in  » EJB-Server-geronimo » kernel » org » apache » geronimo » kernel » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server geronimo » kernel » org.apache.geronimo.kernel 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:         */package org.apache.geronimo.kernel;
017:
018:        import java.lang.reflect.Array;
019:        import java.util.HashMap;
020:        import java.util.Set;
021:        import java.util.LinkedHashSet;
022:        import java.util.LinkedList;
023:        import java.util.Arrays;
024:        import java.util.List;
025:        import java.util.ArrayList;
026:
027:        import org.apache.geronimo.kernel.config.MultiParentClassLoader;
028:
029:        /**
030:         * Utility class for loading classes by a variety of name variations.
031:         * <p/>
032:         * Supported names types are:
033:         * <p/>
034:         * 1)  Fully qualified class name (e.g., "java.lang.String", "org.apache.geronimo.kernel.ClassLoading"
035:         * 2)  Method signature encoding ("Ljava.lang.String;", "J", "I", etc.)
036:         * 3)  Primitive type names ("int", "boolean", etc.)
037:         * 4)  Method array signature strings ("[I", "[Ljava.lang.String")
038:         * 5)  Arrays using Java code format ("int[]", "java.lang.String[][]")
039:         * <p/>
040:         * The classes are loaded using the provided class loader.  For the basic types, the primitive
041:         * reflection types are returned.
042:         *
043:         * @version $Rev: 476049 $
044:         */
045:        public class ClassLoading {
046:
047:            /**
048:             * Table for mapping primitive class names/signatures to the implementing
049:             * class object
050:             */
051:            private static final HashMap PRIMITIVE_CLASS_MAP = new HashMap();
052:
053:            /**
054:             * Table for mapping primitive classes back to their name signature type, which
055:             * allows a reverse mapping to be performed from a class object into a resolvable
056:             * signature.
057:             */
058:            private static final HashMap CLASS_TO_SIGNATURE_MAP = new HashMap();
059:
060:            /**
061:             * Setup the primitives map.  We make any entry for each primitive class using both the
062:             * human readable name and the method signature shorthand type.
063:             */
064:            static {
065:                PRIMITIVE_CLASS_MAP.put("boolean", boolean.class);
066:                PRIMITIVE_CLASS_MAP.put("Z", boolean.class);
067:                PRIMITIVE_CLASS_MAP.put("byte", byte.class);
068:                PRIMITIVE_CLASS_MAP.put("B", byte.class);
069:                PRIMITIVE_CLASS_MAP.put("char", char.class);
070:                PRIMITIVE_CLASS_MAP.put("C", char.class);
071:                PRIMITIVE_CLASS_MAP.put("short", short.class);
072:                PRIMITIVE_CLASS_MAP.put("S", short.class);
073:                PRIMITIVE_CLASS_MAP.put("int", int.class);
074:                PRIMITIVE_CLASS_MAP.put("I", int.class);
075:                PRIMITIVE_CLASS_MAP.put("long", long.class);
076:                PRIMITIVE_CLASS_MAP.put("J", long.class);
077:                PRIMITIVE_CLASS_MAP.put("float", float.class);
078:                PRIMITIVE_CLASS_MAP.put("F", float.class);
079:                PRIMITIVE_CLASS_MAP.put("double", double.class);
080:                PRIMITIVE_CLASS_MAP.put("D", double.class);
081:                PRIMITIVE_CLASS_MAP.put("void", void.class);
082:                PRIMITIVE_CLASS_MAP.put("V", void.class);
083:
084:                // Now build a reverse mapping table.  The table above has a many-to-one mapping for
085:                // class names.  To do the reverse, we need to pick just one.  As long as the
086:                // returned name supports "round tripping" of the requests, this will work fine.
087:
088:                CLASS_TO_SIGNATURE_MAP.put(boolean.class, "Z");
089:                CLASS_TO_SIGNATURE_MAP.put(byte.class, "B");
090:                CLASS_TO_SIGNATURE_MAP.put(char.class, "C");
091:                CLASS_TO_SIGNATURE_MAP.put(short.class, "S");
092:                CLASS_TO_SIGNATURE_MAP.put(int.class, "I");
093:                CLASS_TO_SIGNATURE_MAP.put(long.class, "J");
094:                CLASS_TO_SIGNATURE_MAP.put(float.class, "F");
095:                CLASS_TO_SIGNATURE_MAP.put(double.class, "D");
096:                CLASS_TO_SIGNATURE_MAP.put(void.class, "V");
097:            }
098:
099:            /**
100:             * Load a class that matches the requested name, using the provided class loader context.
101:             * <p/>
102:             * The class name may be a standard class name, the name of a primitive type Java
103:             * reflection class (e.g., "boolean" or "int"), or a type in method type signature
104:             * encoding.  Array classes in either encoding form are also processed.
105:             *
106:             * @param className The name of the required class.
107:             * @param classLoader The class loader used to resolve the class object.
108:             * @return The Class object resolved from "className".
109:             * @throws ClassNotFoundException When unable to resolve the class object.
110:             * @throws IllegalArgumentException If either argument is null.
111:             */
112:            public static Class loadClass(String className,
113:                    ClassLoader classLoader) throws ClassNotFoundException {
114:
115:                // the tests require IllegalArgumentExceptions for null values on either of these.
116:                if (className == null) {
117:                    throw new IllegalArgumentException("className is null");
118:                }
119:
120:                if (classLoader == null) {
121:                    throw new IllegalArgumentException("classLoader is null");
122:                }
123:                // The easiest case is a proper class name.  We just have the class loader resolve this.
124:                // If the class loader throws a ClassNotFoundException, then we need to check each of the
125:                // special name encodings we support.
126:                try {
127:                    return classLoader.loadClass(className);
128:                } catch (ClassNotFoundException ignore) {
129:                    // if not found, continue on to the other name forms.
130:                }
131:
132:                // The second easiest version to resolve is a direct map to a primitive type name
133:                // or method signature.  Check our name-to-class map for one of those.
134:                Class resolvedClass = (Class) PRIMITIVE_CLASS_MAP
135:                        .get(className);
136:                if (resolvedClass != null) {
137:                    return resolvedClass;
138:                }
139:
140:                // Class names in method signature have the format "Lfully.resolved.name;",
141:                // so if it ends in a semicolon and begins with an "L", this must be in
142:                // this format.  Have the class loader try to load this.  There are no other
143:                // options if this fails, so just allow the class loader to throw the
144:                // ClassNotFoundException.
145:                if (className.endsWith(";") && className.startsWith("L")) {
146:                    // pick out the name portion
147:                    String typeName = className.substring(1,
148:                            className.length() - 1);
149:                    // and delegate the loading to the class loader.
150:                    return classLoader.loadClass(typeName);
151:                }
152:
153:                // All we have left now are the array types.  Method signature array types
154:                // have a series of leading "[" characters to specify the number of dimensions.
155:                // The other array type we handle uses trailing "[]" for the dimensions, just
156:                // like the Java language syntax.
157:
158:                // first check for the signature form ([[[[type).
159:                if (className.charAt(0) == '[') {
160:                    // we have at least one array marker, now count how many leading '['s we have
161:                    // to get the dimension count.
162:                    int count = 0;
163:                    int nameLen = className.length();
164:
165:                    while (count < nameLen && className.charAt(count) == '[') {
166:                        count++;
167:                    }
168:
169:                    // pull of the name subtype, which is everything after the last '['
170:                    String arrayTypeName = className.substring(count, className
171:                            .length());
172:                    // resolve the type using a recursive call, which will load any of the primitive signature
173:                    // types as well as class names.
174:                    Class arrayType = loadClass(arrayTypeName, classLoader);
175:
176:                    // Resolving array types require a little more work.  The array classes are
177:                    // created dynamically when the first instance of a given dimension and type is
178:                    // created.  We need to create one using reflection to do this.
179:                    return getArrayClass(arrayType, count);
180:                }
181:
182:                // ok, last chance.  Now check for an array specification in Java language
183:                // syntax.  This will be a type name followed by pairs of "[]" to indicate
184:                // the number of dimensions.
185:                if (className.endsWith("[]")) {
186:                    // get the base component class name and the arrayDimensions
187:                    int count = 0;
188:                    int position = className.length();
189:
190:                    while (position > 1
191:                            && className.substring(position - 2, position)
192:                                    .equals("[]")) {
193:                        // count this dimension
194:                        count++;
195:                        // and step back the probe position.
196:                        position -= 2;
197:                    }
198:
199:                    // position now points at the location of the last successful test.  This makes it
200:                    // easy to pick off the class name.
201:
202:                    String typeName = className.substring(0, position);
203:
204:                    // load the base type, again, doing this recursively
205:                    Class arrayType = loadClass(typeName, classLoader);
206:                    // and turn this into the class object
207:                    return getArrayClass(arrayType, count);
208:                }
209:
210:                // We're out of options, just toss an exception over the wall.
211:                if (classLoader instanceof  MultiParentClassLoader) {
212:                    MultiParentClassLoader cl = (MultiParentClassLoader) classLoader;
213:                    throw new ClassNotFoundException("Could not load class "
214:                            + className + " from classloader: " + cl.getId()
215:                            + ", destroyed state: " + cl.isDestroyed());
216:                }
217:                throw new ClassNotFoundException("Could not load class "
218:                        + className + " from unknown classloader; "
219:                        + classLoader);
220:            }
221:
222:            /**
223:             * Map a class object back to a class name.  The returned class object
224:             * must be "round trippable", which means
225:             * <p/>
226:             * type == ClassLoading.loadClass(ClassLoading.getClassName(type), classLoader)
227:             * <p/>
228:             * must be true.  To ensure this, the class name is always returned in
229:             * method signature format.
230:             *
231:             * @param type The class object we convert into name form.
232:             * @return A string representation of the class name, in method signature
233:             *         format.
234:             */
235:            public static String getClassName(Class type) {
236:                StringBuffer name = new StringBuffer();
237:
238:                // we test these in reverse order from the resolution steps,
239:                // first handling arrays, then primitive types, and finally
240:                // "normal" class objects.
241:
242:                // First handle arrays.  If a class is an array, the type is
243:                // element stored at that level.  So, for a 2-dimensional array
244:                // of ints, the top-level type will be "[I".  We need to loop
245:                // down the hierarchy until we hit a non-array type.
246:                while (type.isArray()) {
247:                    // add another array indicator at the front of the name,
248:                    // and continue with the next type.
249:                    name.append('[');
250:                    type = type.getComponentType();
251:                }
252:
253:                // we're down to the base type.  If this is a primitive, then
254:                // we poke in the single-character type specifier.
255:                if (type.isPrimitive()) {
256:                    name.append((String) CLASS_TO_SIGNATURE_MAP.get(type));
257:                }
258:                // a "normal" class.  This gets expressing using the "Lmy.class.name;" syntax.
259:                else {
260:                    name.append('L');
261:                    name.append(type.getName());
262:                    name.append(';');
263:                }
264:                return name.toString();
265:            }
266:
267:            private static Class getArrayClass(Class type, int dimension) {
268:                // Array.newInstance() requires an array of the requested number of dimensions
269:                // that gives the size for each dimension.  We just request 0 in each of the
270:                // dimentions, which is not unlike a black hole sigularity.
271:                int dimensions[] = new int[dimension];
272:                // create an instance and return the associated class object.
273:                return Array.newInstance(type, dimensions).getClass();
274:            }
275:
276:            public static Set getAllTypes(Class type) {
277:                Set allTypes = new LinkedHashSet();
278:                allTypes.add(type);
279:                allTypes.addAll(getAllSuperClasses(type));
280:                allTypes.addAll(getAllInterfaces(type));
281:                return allTypes;
282:            }
283:
284:            private static Set getAllSuperClasses(Class clazz) {
285:                Set allSuperClasses = new LinkedHashSet();
286:                for (Class super Class = clazz.getSuperclass(); super Class != null; super Class = super Class
287:                        .getSuperclass()) {
288:                    allSuperClasses.add(super Class);
289:                }
290:                return allSuperClasses;
291:            }
292:
293:            private static Set getAllInterfaces(Class clazz) {
294:                Set allInterfaces = new LinkedHashSet();
295:                LinkedList stack = new LinkedList();
296:                stack.addAll(Arrays.asList(clazz.getInterfaces()));
297:                while (!stack.isEmpty()) {
298:                    Class intf = (Class) stack.removeFirst();
299:                    if (!allInterfaces.contains(intf)) {
300:                        allInterfaces.add(intf);
301:                        stack.addAll(Arrays.asList(intf.getInterfaces()));
302:                    }
303:                }
304:                return allInterfaces;
305:            }
306:
307:            public static Set reduceInterfaces(Set source) {
308:                Class[] classes = (Class[]) source.toArray(new Class[source
309:                        .size()]);
310:                classes = reduceInterfaces(classes);
311:                return new LinkedHashSet(Arrays.asList(classes));
312:            }
313:
314:            /**
315:             * If there are multiple interfaces, and some of them extend each other,
316:             * eliminate the superclass in favor of the subclasses that extend them.
317:             *
318:             * If one of the entries is a class (not an interface), make sure it's
319:             * the first one in the array.  If more than one of the entries is a
320:             * class, throws an IllegalArgumentException
321:             *
322:             * @param source the original list of interfaces
323:             * @return the equal or smaller list of interfaces
324:             */
325:            public static Class[] reduceInterfaces(Class[] source) {
326:                // use a copy of the sorce array
327:                source = (Class[]) source.clone();
328:
329:                for (int leftIndex = 0; leftIndex < source.length - 1; leftIndex++) {
330:                    Class left = source[leftIndex];
331:                    if (left == null) {
332:                        continue;
333:                    }
334:
335:                    for (int rightIndex = leftIndex + 1; rightIndex < source.length; rightIndex++) {
336:                        Class right = source[rightIndex];
337:                        if (right == null) {
338:                            continue;
339:                        }
340:
341:                        if (left == right || right.isAssignableFrom(left)) {
342:                            // right is the same as class or a sub class of left
343:                            source[rightIndex] = null;
344:                        } else if (left.isAssignableFrom(right)) {
345:                            // left is the same as class or a sub class of right
346:                            source[leftIndex] = null;
347:
348:                            // the left has been eliminated; move on to the next left
349:                            break;
350:                        }
351:                    }
352:                }
353:
354:                Class clazz = null;
355:                for (int i = 0; i < source.length; i++) {
356:                    if (source[i] != null && !source[i].isInterface()) {
357:                        if (clazz != null) {
358:                            throw new IllegalArgumentException(
359:                                    "Source contains two classes which are not subclasses of each other: "
360:                                            + clazz.getName() + ", "
361:                                            + source[i].getName());
362:                        }
363:                        clazz = source[i];
364:                        source[i] = null;
365:                    }
366:                }
367:
368:                List list = new ArrayList(source.length);
369:                if (clazz != null)
370:                    list.add(clazz);
371:                for (int i = 0; i < source.length; i++) {
372:                    if (source[i] != null) {
373:                        list.add(source[i]);
374:                    }
375:                }
376:                return (Class[]) list.toArray(new Class[list.size()]);
377:            }
378:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.