View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.plus.annotation;
20  
21  import java.lang.reflect.InvocationTargetException;
22  import java.lang.reflect.Method;
23  import java.lang.reflect.Modifier;
24  
25  import org.eclipse.jetty.util.IntrospectionUtil;
26  import org.eclipse.jetty.util.Loader;
27  
28  
29  
30  /**
31   * LifeCycleCallback
32   *
33   *
34   */
35  public abstract class LifeCycleCallback
36  {
37      public static final Object[] __EMPTY_ARGS = new Object[] {};
38      private Method _target;
39      private Class<?> _targetClass;
40      private String _className;
41      private String _methodName;
42      
43      
44      public LifeCycleCallback()
45      {
46      }
47  
48  
49      /**
50       * @return the _targetClass
51       */
52      public Class<?> getTargetClass()
53      {
54          return _targetClass;
55      }
56      
57      public String getTargetClassName()
58      {
59          return _className;
60      }
61      
62      public String getMethodName()
63      {
64          return _methodName;
65      }
66      
67      /**
68       * @return the target
69       */
70      public Method getTarget()
71      {
72          return _target;
73      }
74      
75      
76      public void setTarget (String className, String methodName)
77      {
78          _className = className;
79          _methodName = methodName;
80      }
81  
82      public void setTarget (Class<?> clazz, String methodName)
83      {
84          try
85          {
86              Method method = IntrospectionUtil.findMethod(clazz, methodName, null, true, true);
87              validate(clazz, method);
88              _target = method;
89              _targetClass = clazz;
90              _className = clazz.getCanonicalName();
91              _methodName = methodName;
92          }
93          catch (NoSuchMethodException e)
94          {
95              throw new IllegalArgumentException ("Method "+methodName+" not found on class "+clazz.getName());
96          }
97      }
98  
99  
100     
101     
102     public void callback (Object instance) 
103     throws SecurityException, NoSuchMethodException, ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
104     {
105         if (_target == null)
106         {
107             if (_targetClass == null)
108                 _targetClass = Loader.loadClass(null, _className);
109             _target = _targetClass.getDeclaredMethod(_methodName, new Class[]{}); //TODO
110         }
111         
112         if (_target != null)
113         {
114             boolean accessibility = getTarget().isAccessible();
115             getTarget().setAccessible(true);
116             getTarget().invoke(instance, __EMPTY_ARGS);
117             getTarget().setAccessible(accessibility);
118         }
119     }
120 
121     
122 
123     /**
124      * Find a method of the given name either directly in the given
125      * class, or inherited.
126      * 
127      * @param pack the package of the class under inspection
128      * @param clazz the class under inspection
129      * @param methodName the method to find 
130      * @param checkInheritance false on first entry, true if a superclass is being introspected
131      * @return the method
132      */
133     public Method findMethod (Package pack, Class<?> clazz, String methodName, boolean checkInheritance)
134     {
135         if (clazz == null)
136             return null;
137 
138         try
139         {
140             Method method = clazz.getDeclaredMethod(methodName, null);
141             if (checkInheritance)
142             {
143                 int modifiers = method.getModifiers();
144                 if (Modifier.isProtected(modifiers) || Modifier.isPublic(modifiers) || (!Modifier.isPrivate(modifiers)&&(pack.equals(clazz.getPackage()))))
145                     return method;
146                 else
147                     return findMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, true);
148             }
149             return method;
150         }
151         catch (NoSuchMethodException e)
152         {
153             return findMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, true);
154         }
155     }
156 
157     public boolean equals (Object o)
158     {
159         if (o==null)
160             return false;
161         if (!(o instanceof LifeCycleCallback))
162             return false;
163         LifeCycleCallback callback = (LifeCycleCallback)o;
164         
165         if (callback.getTargetClass()==null)
166         {
167             if (getTargetClass() != null)
168                 return false;
169         }
170         else if(!callback.getTargetClass().equals(getTargetClass()))
171            return false;
172         if (callback.getTarget()==null)
173         {
174             if (getTarget() != null)
175                 return false;
176         }
177         else if (!callback.getTarget().equals(getTarget()))
178             return false;
179         
180         return true;
181     }
182     
183     public abstract void validate (Class<?> clazz, Method m);
184 }