KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > reflect > ClassInfoRepository


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.aspectwerkz.reflect;
5
6 import java.lang.ref.WeakReference JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Map JavaDoc;
9 import java.util.WeakHashMap JavaDoc;
10
11 /**
12  * A repository for the class info hierarchy. Is class loader aware.
13  *
14  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
15  */

16 public class ClassInfoRepository {
17   /**
18    * Map with all the class info repositories mapped to their class loader.
19    */

20   private static final HashMap JavaDoc s_repositories = new HashMap JavaDoc();
21
22   /**
23    * Map with all the class info mapped to their class names.
24    */

25   private final Map JavaDoc m_repository = new WeakHashMap JavaDoc();
26
27   /**
28    * Class loader for the class repository.
29    */

30   private transient final WeakReference JavaDoc m_loaderRef;
31
32   /**
33    * Creates a new repository.
34    *
35    * @param loader
36    */

37   private ClassInfoRepository(final ClassLoader JavaDoc loader) {
38     m_loaderRef = new WeakReference JavaDoc(loader);
39   }
40
41   /**
42    * Returns the class info repository for the specific class loader
43    *
44    * @param loader
45    * @return
46    */

47   public static synchronized ClassInfoRepository getRepository(final ClassLoader JavaDoc loader) {
48     Integer JavaDoc hash = new Integer JavaDoc(loader == null ? 0 : loader.hashCode()); // boot cl
49
WeakReference JavaDoc repositoryRef = (WeakReference JavaDoc) s_repositories.get(hash);
50     ClassInfoRepository repository = repositoryRef == null ? null : (ClassInfoRepository) repositoryRef.get();
51     if (repository != null) {
52       return repository;
53     } else {
54       ClassInfoRepository repo = new ClassInfoRepository(loader);
55       s_repositories.put(hash, new WeakReference JavaDoc(repo));
56       return repo;
57     }
58   }
59
60   /**
61    * Remove a class from the repository.
62    *
63    * @param className the name of the class
64    */

65   public static void removeClassInfoFromAllClassLoaders(final String JavaDoc className) {
66     //TODO - fix algorithm
67
throw new UnsupportedOperationException JavaDoc("fix algorithm");
68   }
69
70   /**
71    * Returns the class info.
72    *
73    * @param className
74    * @return
75    */

76   public ClassInfo getClassInfo(final String JavaDoc className) {
77     ClassInfo info = (ClassInfo) m_repository.get(className);
78     if (info == null) {
79       return checkParentClassRepository(className, (ClassLoader JavaDoc) m_loaderRef.get());
80     }
81     return (ClassInfo) m_repository.get(className);
82   }
83
84   /**
85    * Adds a new class info.
86    *
87    * @param classInfo
88    */

89   public void addClassInfo(final ClassInfo classInfo) {
90     // is the class loaded by a class loader higher up in the hierarchy?
91
if (checkParentClassRepository(classInfo.getName(), (ClassLoader JavaDoc) m_loaderRef.get()) == null) {
92       // need to create new String instance to avoid using the original reference
93
m_repository.put(new String JavaDoc(classInfo.getName()), classInfo);
94     } else {
95       // TODO: remove class in child class repository and add it for the current (parent) CL
96
}
97   }
98
99   /**
100    * Checks if the class info for a specific class exists.
101    *
102    * @param name
103    * @return
104    */

105   public boolean hasClassInfo(final String JavaDoc name) {
106     return m_repository.containsKey(name);
107   }
108
109   /**
110    * Searches for a class info up in the class loader hierarchy.
111    *
112    * @param className
113    * @param loader
114    * @return the class info
115    * @TODO might clash for specific class loader lookup algorithms, user need to override this class and implement
116    * this method
117    */

118   public ClassInfo checkParentClassRepository(final String JavaDoc className, final ClassLoader JavaDoc loader) {
119     if (loader == null) {
120       return null;
121     }
122     ClassInfo info;
123     ClassLoader JavaDoc parent = loader.getParent();
124     if (parent == null) {
125       return null;
126     } else {
127       info = ClassInfoRepository.getRepository(parent).getClassInfo(className);
128       if (info != null) {
129         return info;
130       } else {
131         return checkParentClassRepository(className, parent);
132       }
133     }
134   }
135 }
Popular Tags