View Javadoc

    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;
    14  import java.util.Map;
    15  import java.util.WeakHashMap;
    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();
    33
    34      /***
    35       * Class loader for the class repository.
    36       */
    37      private transient final WeakReference m_loaderRef;
    38
    39      /***
    40       * Creates a new repository.
    41       *
    42       * @param loader
    43       */
    44      private JavaClassInfoRepository(final ClassLoader loader) {
    45          m_loaderRef = new WeakReference(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 loader) {
    55          int hash;
    56          if (loader == null) { // boot cl
    57              hash = 0;
    58          } else {
    59              hash = loader.hashCode();
    60          }
    61          WeakReference repositoryRef = (WeakReference) 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(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 className) {
    79          //TODO - fix algorithm
    80          throw new UnsupportedOperationException("fix algorithm");
    81      }
    82
    83      /***
    84       * Returns the class info.
    85       *
    86       * @param className
    87       * @return
    88       */
    89      public ClassInfo getClassInfo(final String className) {
    90          ClassInfo info = (ClassInfo) m_repository.get(className);
    91          if (info == null) {
    92              return checkParentClassRepository(className, (ClassLoader) 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) m_loaderRef.get()) == null) {
    105             m_repository.put(new String(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 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 className, final ClassLoader loader) {
    131         if (loader == null) {
    132             return null;
    133         }
    134         ClassInfo info;
    135         ClassLoader 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 }