KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > reflect > impl > asm > AsmClassInfoRepository


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.asm;
9
10 import gnu.trove.TIntObjectHashMap;
11 import org.codehaus.aspectwerkz.reflect.ClassInfo;
12 import org.codehaus.aspectwerkz.exception.DefinitionException;
13
14 import java.lang.ref.WeakReference JavaDoc;
15 import java.lang.ref.SoftReference JavaDoc;
16 import java.lang.ref.Reference JavaDoc;
17 import java.util.Properties JavaDoc;
18 import java.io.InputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20
21 /**
22  * A repository for the class info hierarchy. Is class loader aware.
23  *
24  * @author <a HREF="mailto:jboner@codehaus.org">Jonas Bonér </a>
25  */

26 public class AsmClassInfoRepository {
27     /**
28      * Map with all the class info repositories mapped to their class loader.
29      */

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

35     private final TIntObjectHashMap m_repository = new TIntObjectHashMap();
36
37     /**
38      * Class loader for the class repository.
39      */

40     private transient final WeakReference JavaDoc m_loaderRef;
41
42     /**
43      * The annotation properties file.
44      */

45     private final Properties JavaDoc m_annotationProperties;
46
47     /**
48      * Creates a new repository.
49      *
50      * @param loader
51      */

52     private AsmClassInfoRepository(final ClassLoader JavaDoc loader) {
53         m_loaderRef = new WeakReference JavaDoc(loader);
54         m_annotationProperties = new Properties JavaDoc();
55         if (loader != null) {
56             try {
57                 InputStream JavaDoc stream = loader.getResourceAsStream("annotation.properties");
58                 if (stream != null) {
59                     try {
60                         m_annotationProperties.load(stream);
61                     } finally {
62                         try {
63                             stream.close();
64                         } catch (Exception JavaDoc e) {
65                             ;
66                         }
67                     }
68                 }
69             } catch (IOException JavaDoc e) {
70                 throw new DefinitionException("could not find resource [annotation.properties] on classpath");
71             }
72         }
73     }
74
75     /**
76      * Returns the class info repository for the specific class loader
77      *
78      * @param loader
79      * @return
80      */

81     public static synchronized AsmClassInfoRepository getRepository(final ClassLoader JavaDoc loader) {
82         int hash;
83         if (loader == null) { // boot cl
84
hash = 0;
85         } else {
86             hash = loader.hashCode();
87         }
88         Reference JavaDoc repositoryRef = (Reference JavaDoc) s_repositories.get(hash);
89         AsmClassInfoRepository repository = ((repositoryRef == null) ? null : (AsmClassInfoRepository) repositoryRef
90                 .get());
91         if (repository != null) {
92             return repository;
93         } else {
94             AsmClassInfoRepository repo = new AsmClassInfoRepository(loader);
95             s_repositories.put(hash, new SoftReference JavaDoc(repo));
96             return repo;
97         }
98     }
99
100     /**
101      * Remove a class from the repository.
102      *
103      * @param className the name of the class
104      */

105     public static void removeClassInfoFromAllClassLoaders(final String JavaDoc className) {
106         //TODO - fix algorithm
107
throw new UnsupportedOperationException JavaDoc("fix algorithm");
108     }
109
110     /**
111      * Returns the class info.
112      *
113      * @param className
114      * @return
115      */

116     public ClassInfo getClassInfo(final String JavaDoc className) {
117         Reference JavaDoc classInfoRef = ((Reference JavaDoc) m_repository.get(className.hashCode()));
118         ClassInfo info = (classInfoRef == null) ? null : (ClassInfo) (classInfoRef.get());
119         if (info == null) {
120             return checkParentClassRepository(className, (ClassLoader JavaDoc) m_loaderRef.get());
121         }
122         return info;
123     }
124
125     /**
126      * Adds a new class info.
127      *
128      * @param classInfo
129      */

130     public void addClassInfo(final ClassInfo classInfo) {
131         // is the class loaded by a class loader higher up in the hierarchy?
132
if (checkParentClassRepository(classInfo.getName(), (ClassLoader JavaDoc) m_loaderRef.get()) == null) {
133             m_repository.put(classInfo.getName().hashCode(), new SoftReference JavaDoc(classInfo));
134         } else {
135             // TODO: remove class in child class repository and add it for the
136
// current (parent) CL
137
}
138     }
139
140     /**
141      * Checks if the class info for a specific class exists.
142      *
143      * @param name
144      * @return
145      */

146     public boolean hasClassInfo(final String JavaDoc name) {
147         Reference JavaDoc classInfoRef = (Reference JavaDoc) m_repository.get(name.hashCode());
148         return (classInfoRef == null) ? false : (classInfoRef.get() != null);
149     }
150
151     /**
152      * Removes the class from the repository (since it has been modified and needs to be rebuild).
153      *
154      * @param className
155      */

156     public void removeClassInfo(final String JavaDoc className) {
157         m_repository.remove(className.hashCode());
158     }
159
160     /**
161      * Returns the annotation properties for the specific class loader.
162      *
163      * @return the annotation properties
164      */

165     public Properties JavaDoc getAnnotationProperties() {
166         return m_annotationProperties;
167     }
168
169     /**
170      * Searches for a class info up in the class loader hierarchy.
171      *
172      * @param className
173      * @param loader
174      * @return the class info
175      * @TODO might clash for specific class loader lookup algorithms, user need to override this class and implement
176      * this method
177      */

178     public ClassInfo checkParentClassRepository(final String JavaDoc className, final ClassLoader JavaDoc loader) {
179         if (loader == null) {
180             return null;
181         }
182         ClassInfo info;
183         ClassLoader JavaDoc parent = loader.getParent();
184         if (parent == null) {
185             return null;
186         } else {
187             info = AsmClassInfoRepository.getRepository(parent).getClassInfo(className);
188             if (info != null) {
189                 return info;
190             } else {
191                 return checkParentClassRepository(className, parent);
192             }
193         }
194     }
195 }
Popular Tags