View Javadoc

1   /*
2    * Copyright (C) 2004 TiongHiang Lee
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not,  write to the Free Software
16   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17   *
18   * Email: thlee@onemindsoft.org
19   */
20  
21  package org.onemind.commons.java.lang.reflect;
22  
23  import java.util.*;
24  import java.util.logging.Level;
25  import java.util.logging.Logger;
26  import org.onemind.commons.java.datastructure.LookupCache;
27  /***
28   * A class lookup cache can lookup non-fully-qualified name classes for a given set 
29   * of packages and will cache the lookup for later use. For example, <br>
30   * 
31   * <pre>
32   *      ClassLookupCache cache = new ClassLookupCache();
33   *      cache.addPackage("*"); //default package
34   *      cache.addPackage("java.io.*");
35   *  
36   *      Class c = cache.getClass("File"); //c = java.io.File
37   *      c = cache.getClass("File1"); //c = null
38   * </pre>
39   * 
40   * NOTE: 
41   * 1. The cache is static for all instances of the lookup cache. 
42   * 2. The packages is instance specific 
43   * 3. It will cache only positive and negative response of fully qualified name thus 
44   * lookup of non-fully-qualified has some performance hit, but for the sake of correctness
45   * 
46   * 
47   * @author TiongHiang Lee (thlee@onemindsoft.org)
48   * @version $Id: ClassLookupCache.java,v 1.6 2006/10/29 17:02:38 thlee Exp $ $Name:  $
49   */
50  public class ClassLookupCache extends LookupCache
51  {
52  
53      /**</package-summary/html">the packages * *//package-summary.html">em>* the packages * */
54      privateong> final HashSet _packages = new LinkedHashSet();
55  
56      /*** the logger * */
57      private static final Logger _logger = Logger.getLogger(ClassLookupCache.class.getName());
58  
59      /***
60       * {@inheritDoc}
61       */
62      public ClassLookupCache()
63      {
64      }
65  
66      /***
67       * Add a new package.
68       * @param packageName the package name
69       */
70      public void addImport(String importName)
71      {
72          if (importName==null){
73              throw new IllegalArgumentException("Package name must not be null");
74          }
75          _packages.add(importName);
76          clearNegCache();
77      }
78  
79      /***
80       * Get the class given by the fully-qualified or non-fully qualified java class name
81       * @param className the class name
82       * @return the class or null
83       */
84      public Class getClass(String className)
85      {
86          if (className.indexOf('.') == -1)
87          { //not fully qualified name
88              Iterator it = _packages.iterator();
89              Class c = null;
90              while (it.hasNext())
91              {
92                  String importName = (String) it.next();
93                  String fullName = null;
94                  int idx = importName.indexOf("*");
95                  if (idx==-1){ //importName is a class name
96                      if (importName.endsWith("." + className) || importName.equals(className)){
97                          fullName = importName;
98                      } else { //don't bother
99                          continue;
100                     }
101                 } else {
102                     fullName = importName.substring(0, idx) + className;
103                 }
104                 if (_logger.isLoggable(Level.FINEST))
105                 {
106                     _logger.finest("Looking up class " + fullName);
107                 }
108                 c = (Class) lookup(fullName);
109                 if (c != null)
110                 {
111                     return c;
112                 }
113             }
114             return null;
115         } else
116         {
117             return (Class) lookup(className);
118         }
119     }
120 
121     /***
122      * Produce the class given the key {@inheritDoc}
123      */
124     public Object produce(Object key)
125     {
126         String className = (String) key;
127         Class c = null;
128         //first trial
129         try
130         {
131             c = Class.forName(className);
132             if (_logger.isLoggable(Level.FINEST))
133             {
134                 _logger.finest("Lookup class " + key + " successful");
135                 //otherwise the ClassNotFoundException must have been throwned
136             }
137         } catch (Exception e)
138         {
139             if (_logger.isLoggable(Level.FINEST))
140             {
141                 _logger.finest("Lookup class " + key + " failed");
142             }
143         }
144         return c;
145     }
146 
147     /***
148      * Get all the import packages in this lookup cache.
149      * @return the packages
150      */
151     public Set getPackages()
152     {
153         return</strong> Collections.unmodifiableSet(_packages);
154     }
155 
156     /***
157      * {@inheritDoc}
158      */
159     protected void clearNegCache()
160     {
161         super.clearNegCache();
162     }
163 
164     /***
165      * {@inheritDoc}
166      */
167     protected boolean isInCache(Object o)
168     {
169         return super.isInCache(o);
170     }
171 
172     /*** 
173      * {@inheritDoc}
174      */
175     protected boolean isInNegCache(Object o)
176     {
177         return super.isInNegCache(o);
178     }
179 
180     /*** 
181      * {@inheritDoc}
182      */
183     protected void setDoNegativeCache(boolean b)
184     {
185         super.setDoNegativeCache(b);
186     }
187 }