1   //========================================================================
2   //$Id: LifeCycleCallbackCollection.java 3353 2008-07-22 10:39:41Z janb $
3   //Copyright 2006 Mort Bay Consulting Pty. Ltd.
4   //------------------------------------------------------------------------
5   //Licensed under the Apache License, Version 2.0 (the "License");
6   //you may not use this file except in compliance with the License.
7   //You may obtain a copy of the License at 
8   //http://www.apache.org/licenses/LICENSE-2.0
9   //Unless required by applicable law or agreed to in writing, software
10  //distributed under the License is distributed on an "AS IS" BASIS,
11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  //See the License for the specific language governing permissions and
13  //limitations under the License.
14  //========================================================================
15  
16  package org.mortbay.jetty.plus.annotation;
17  
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Map;
23  
24  import org.mortbay.log.Log;
25  
26  
27  /**
28   * LifeCycleCallbackCollection
29   *
30   *
31   */
32  public class LifeCycleCallbackCollection
33  {
34      private HashMap postConstructCallbacksMap = new HashMap();
35      private HashMap preDestroyCallbacksMap = new HashMap();
36      
37      
38   
39      
40      
41      /**
42       * Add a Callback to the list of callbacks.
43       * 
44       * @param callback
45       */
46      public void add (LifeCycleCallback callback)
47      {
48          if ((callback==null) || (callback.getTargetClass()==null) || (callback.getTarget()==null))
49              return;
50  
51          if (Log.isDebugEnabled())
52              Log.debug("Adding callback for class="+callback.getTargetClass()+ " on "+callback.getTarget());
53          Map map = null;
54          if (callback instanceof PreDestroyCallback)
55              map = preDestroyCallbacksMap;
56          if (callback instanceof PostConstructCallback)
57              map = postConstructCallbacksMap;
58  
59          if (map == null)
60              throw new IllegalArgumentException ("Unsupported lifecycle callback type: "+callback);
61  
62       
63          List callbacks = (List)map.get(callback.getTargetClass());
64          if (callbacks==null)
65          {
66              callbacks = new ArrayList();
67              map.put(callback.getTargetClass(), callbacks);
68          }
69         
70          //don't add another callback for exactly the same method
71          if (!callbacks.contains(callback))
72              callbacks.add(callback);
73      }
74  
75      public List getPreDestroyCallbacks (Object o)
76      {
77          if (o == null)
78              return null;
79          
80          Class clazz = o.getClass();
81          
82          if (o instanceof PojoWrapper)
83          {
84              o = ((PojoWrapper)o).getPojo();
85              clazz = o.getClass();
86          }
87      
88          return (List)preDestroyCallbacksMap.get(clazz);
89      }
90      
91      public List getPostConstructCallbacks (Object o)
92      {
93          if (o == null)
94              return null;
95          
96          Class clazz = o.getClass();
97          
98          if (o instanceof PojoWrapper)
99          {
100             o = ((PojoWrapper)o).getPojo();
101             clazz = o.getClass();
102         }
103     
104         return (List)postConstructCallbacksMap.get(clazz);
105     }
106     
107     /**
108      * Call the method, if one exists, that is annotated with PostConstruct
109      * or with <post-construct> in web.xml
110      * @param o the object on which to attempt the callback
111      * @throws Exception
112      */
113     public void callPostConstructCallback (Object o)
114     throws Exception
115     {
116         if (o == null)
117             return;
118         
119         Class clazz = o.getClass();
120         
121         if (o instanceof PojoWrapper)
122         {
123             o = ((PojoWrapper)o).getPojo();
124             clazz = o.getClass();
125         }
126         List callbacks = (List)postConstructCallbacksMap.get(clazz);
127         
128         if (callbacks == null)
129             return;
130         
131         for (int i=0;i<callbacks.size();i++)
132             ((LifeCycleCallback)callbacks.get(i)).callback(o);
133     }
134     
135     
136     /**
137      * Call the method, if one exists, that is annotated with PreDestroy
138      * or with &lt;pre-destroy&gt; in web.xml
139      * @param o the object on which to attempt the callback
140      */
141     public void callPreDestroyCallback (Object o)
142     throws Exception
143     {
144         if (o == null)
145             return;
146         
147         Class clazz = o.getClass();
148         
149         if (o instanceof PojoWrapper)
150         {
151             o = ((PojoWrapper)o).getPojo();
152             clazz = o.getClass();
153         }
154     
155         List callbacks = (List)preDestroyCallbacksMap.get(clazz);
156         if (callbacks == null)
157             return;
158         
159         for (int i=0;i<callbacks.size();i++)
160             ((LifeCycleCallback)callbacks.get(i)).callback(o);
161     }
162 }