KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > reflect > impl > java > JavaClassInfoRepository


1 /**************************************************************************************
2  * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
3  * http://aspectwerkz.codehaus.org *
4  * ---------------------------------------------------------------------------------- *
5  * The software in this package is published under the terms of the LGPL license *
6  * a copy of which has been included with this distribution in the license.txt file. *
7  **************************************************************************************/

8 package org.codehaus.aspectwerkz.reflect.impl.java;
9
10 import gnu.trove.TIntObjectHashMap;
11 import org.codehaus.aspectwerkz.reflect.ClassInfo;
12
13 import java.lang.ref.WeakReference JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.WeakHashMap JavaDoc;
16
17 /**
18  * A repository for the class info hierarchy. Is class loader aware. <p/>TODO refactor some with
19  * ASMClassInfoRepository but keep em separate for system runtime sake in AOPC (WLS)
20  *
21  * @author <a HREF="mailto:jboner@codehaus.org">Jonas Bonér </a>
22  */

23 public class JavaClassInfoRepository {
24     /**
25      * Map with all the class info repositories mapped to their class loader.
26      */

27     private static final TIntObjectHashMap s_repositories = new TIntObjectHashMap();
28
29     /**
30      * Map with all the class info mapped to their class names.
31      */

32     private final Map m_repository = new WeakHashMap JavaDoc();
33
34     /**
35      * Class loader for the class repository.
36      */

37     private transient final WeakReference JavaDoc m_loaderRef;
38
39     /**
40      * Creates a new repository.
41      *
42      * @param loader
43      */

44     private JavaClassInfoRepository(final ClassLoader JavaDoc loader) {
45         m_loaderRef = new WeakReference JavaDoc(loader);
46     }
47
48     /**
49      * Returns the class info repository for the specific class loader
50      *
51      * @param loader
52      * @return
53      */

54     public static synchronized JavaClassInfoRepository getRepository(final ClassLoader JavaDoc loader) {
55         int hash;
56         if (loader == null) { // boot cl
57
hash = 0;
58         } else {
59             hash = loader.hashCode();
60         }
61         WeakReference JavaDoc repositoryRef = (WeakReference JavaDoc) s_repositories.get(hash);
62         JavaClassInfoRepository repository = ((repositoryRef == null) ? null : (JavaClassInfoRepository) repositoryRef
63                 .get());
64         if (repository != null) {
65             return repository;
66         } else {
67             JavaClassInfoRepository repo = new JavaClassInfoRepository(loader);
68             s_repositories.put(hash, new WeakReference JavaDoc(repo));
69             return repo;
70         }
71     }
72
73     /**
74      * Remove a class from the repository.
75      *
76      * @param className the name of the class
77      */

78     public static void removeClassInfoFromAllClassLoaders(final String JavaDoc className) {
79         //TODO - fix algorithm
80
throw new UnsupportedOperationException JavaDoc("fix algorithm");
81     }
82
83     /**
84      * Returns the class info.
85      *
86      * @param className
87      * @return
88      */

89     public ClassInfo getClassInfo(final String JavaDoc className) {
90         ClassInfo info = (ClassInfo) m_repository.get(className);
91         if (info == null) {
92             return checkParentClassRepository(className, (ClassLoader JavaDoc) m_loaderRef.get());
93         }
94         return (ClassInfo) m_repository.get(className);
95     }
96
97     /**
98      * Adds a new class info.
99      *
100      * @param classInfo
101      */

102     public void addClassInfo(final ClassInfo classInfo) {
103         // is the class loaded by a class loader higher up in the hierarchy?
104
if (checkParentClassRepository(classInfo.getName(), (ClassLoader JavaDoc) m_loaderRef.get()) == null) {
105             m_repository.put(new String JavaDoc(classInfo.getName()), classInfo);
106         } else {
107             // TODO: remove class in child class repository and add it for the current (parent) CL
108
}
109     }
110
111     /**
112      * Checks if the class info for a specific class exists.
113      *
114      * @param name
115      * @return
116      */

117     public boolean hasClassInfo(final String JavaDoc name) {
118         return m_repository.containsKey(name);
119     }
120
121     /**
122      * Searches for a class info up in the class loader hierarchy.
123      *
124      * @param className
125      * @param loader
126      * @return the class info
127      * @TODO might clash for specific class loader lookup algorithms, user need to override this class and implement
128      * this method
129      */

130     public ClassInfo checkParentClassRepository(final String JavaDoc className, final ClassLoader JavaDoc loader) {
131         if (loader == null) {
132             return null;
133         }
134         ClassInfo info;
135         ClassLoader JavaDoc parent = loader.getParent();
136         if (parent == null) {
137             return null;
138         } else {
139             info = JavaClassInfoRepository.getRepository(parent).getClassInfo(className);
140             if (info != null) {
141                 return info;
142             } else {
143                 return checkParentClassRepository(className, parent);
144             }
145         }
146     }
147 }
Popular Tags