1   package com.atlassian.bonnie.search;
2   
3   import java.lang.reflect.Method;
4   
5   /**
6    * Unwraps Hibernate proxies reflectively, without adding a compile-time
7    * dependency on Hibernate itself.
8    */
9   public class HibernateUnwrapper
10  {
11      private static Method getClassMethod = null;
12  
13      static
14      {
15         ClassLoader classLoader = HibernateUnwrapper.class.getClassLoader();
16         try
17         {
18             Class hibernateClass = classLoader.loadClass("net.sf.hibernate.Hibernate");
19             getClassMethod = hibernateClass.getMethod("getClass", Object.class);
20         }
21         catch (Exception e)
22         {
23             // ignore, Hibernate is not on the classpath
24         }
25      }
26  
27      /**
28       * Gets the true class of an object, trying to use Hibernate's proxy unwrapping
29       * tools if available on the classpath.
30       * <p/>
31       * Otherwise simply returns the class of the object passed in if Hibernate not
32       * on the classpath.
33       *
34       * @param o The object to examine
35       * @return The true class of the object (unwrapping Hibernate proxies etc)
36       */
37      public static Class<?> getUnderlyingClass(Object o)
38      {
39          if (getClassMethod == null)
40              return o.getClass();
41          
42          try
43          {
44              return (Class) getClassMethod.invoke(null, o);
45          }
46          catch (Exception e)
47          {
48              return o.getClass();
49          }
50      }
51  }