KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > reflect > ClassInfoRepository


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;
9
10 import gnu.trove.TIntObjectHashMap;
11
12 import java.lang.ref.WeakReference JavaDoc;
13 import java.util.Map JavaDoc;
14 import java.util.WeakHashMap JavaDoc;
15
16 /**
17  * A repository for the class info hierarchy. Is class loader aware.
18  *
19  * @author <a HREF="mailto:jboner@codehaus.org">Jonas Bonér </a>
20  */

21 public class ClassInfoRepository {
22     /**
23      * Map with all the class info repositories mapped to their class loader.
24      */

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

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

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

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

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

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

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

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

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

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