View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 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.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.eclipse.jetty.util.log.Log;
29  import org.eclipse.jetty.util.log.Logger;
30  
31  
32  /**
33   * LifeCycleCallbackCollection
34   *
35   *
36   */
37  public class LifeCycleCallbackCollection
38  {
39      private static final Logger LOG = Log.getLogger(LifeCycleCallbackCollection.class);
40  
41      public static final String LIFECYCLE_CALLBACK_COLLECTION = "org.eclipse.jetty.lifecyleCallbackCollection";
42  
43      private HashMap<String, List<LifeCycleCallback>> postConstructCallbacksMap = new HashMap<String, List<LifeCycleCallback>>();
44      private HashMap<String, List<LifeCycleCallback>> preDestroyCallbacksMap = new HashMap<String, List<LifeCycleCallback>>();
45      
46      /**
47       * Add a Callback to the list of callbacks.
48       * 
49       * @param callback
50       */
51      public void add (LifeCycleCallback callback)
52      {
53          if ((callback==null) || (callback.getTargetClassName()==null))
54              return;
55  
56          if (LOG.isDebugEnabled())
57              LOG.debug("Adding callback for class="+callback.getTargetClass()+ " on "+callback.getTarget());
58          Map<String, List<LifeCycleCallback>> map = null;
59          if (callback instanceof PreDestroyCallback)
60              map = preDestroyCallbacksMap;
61          if (callback instanceof PostConstructCallback)
62              map = postConstructCallbacksMap;
63  
64          if (map == null)
65              throw new IllegalArgumentException ("Unsupported lifecycle callback type: "+callback);
66       
67          List<LifeCycleCallback> callbacks = map.get(callback.getTargetClassName());
68          if (callbacks==null)
69          {
70              callbacks = new ArrayList<LifeCycleCallback>();
71              map.put(callback.getTargetClassName(), callbacks);
72          }
73         
74          //don't add another callback for exactly the same method
75          if (!callbacks.contains(callback))
76              callbacks.add(callback);
77      }
78  
79      public List<LifeCycleCallback> getPreDestroyCallbacks (Object o)
80      {
81          if (o == null)
82              return null;
83          
84          Class<? extends Object> clazz = o.getClass();
85          return preDestroyCallbacksMap.get(clazz.getName());
86      }
87      
88      public List<LifeCycleCallback> getPostConstructCallbacks (Object o)
89      {
90          if (o == null)
91              return null;
92          
93          Class<? extends Object> clazz = o.getClass();
94          return postConstructCallbacksMap.get(clazz.getName());
95      }
96      
97      /**
98       * Call the method, if one exists, that is annotated with PostConstruct
99       * or with &lt;post-construct&gt; in web.xml
100      * @param o the object on which to attempt the callback
101      * @throws Exception
102      */
103     public void callPostConstructCallback (Object o)
104     throws Exception
105     {
106         if (o == null)
107             return;
108         
109         Class<? extends Object> clazz = o.getClass();
110         List<LifeCycleCallback> callbacks = postConstructCallbacksMap.get(clazz.getName());
111 
112         if (callbacks == null)
113             return;
114 
115         for (int i=0;i<callbacks.size();i++)
116         {
117             ((LifeCycleCallback)callbacks.get(i)).callback(o);
118         }
119     }
120 
121     
122     /**
123      * Call the method, if one exists, that is annotated with PreDestroy
124      * or with &lt;pre-destroy&gt; in web.xml
125      * @param o the object on which to attempt the callback
126      */
127     public void callPreDestroyCallback (Object o)
128     throws Exception
129     {
130         if (o == null)
131             return;
132         
133         Class<? extends Object> clazz = o.getClass();
134         List<LifeCycleCallback> callbacks = preDestroyCallbacksMap.get(clazz.getName());
135         if (callbacks == null)
136             return;
137         
138         for (int i=0;i<callbacks.size();i++)
139             ((LifeCycleCallback)callbacks.get(i)).callback(o);
140     }
141     
142     /**
143      * Generate a read-only view of the post-construct callbacks
144      * @return
145      */
146     public Map<String, List<LifeCycleCallback>> getPostConstructCallbackMap()
147     {
148         return Collections.unmodifiableMap(postConstructCallbacksMap);
149     }
150     
151     /**
152      * Generate a read-only view of the pre-destroy callbacks
153      * @return
154      */
155     public Map<String, List<LifeCycleCallback>> getPreDestroyCallbackMap()
156     {
157         return Collections.unmodifiableMap(preDestroyCallbacksMap);
158     }
159     
160     /**
161      * Amalgamate all post-construct callbacks and return a read only list
162      * @return
163      */
164     public Collection<LifeCycleCallback> getPostConstructCallbacks()
165     {
166         List<LifeCycleCallback> list = new ArrayList<LifeCycleCallback>();
167         for (String s:postConstructCallbacksMap.keySet())
168         {
169             list.addAll(postConstructCallbacksMap.get(s));
170         }
171         return Collections.unmodifiableCollection(list);
172     }
173     
174     /**
175      * Amalgamate all pre-destroy callbacks and return a read only list
176      * @return
177      */
178     public Collection<LifeCycleCallback> getPreDestroyCallbacks()
179     {
180         List<LifeCycleCallback> list = new ArrayList<LifeCycleCallback>();
181         for (String s:preDestroyCallbacksMap.keySet())
182         {
183             list.addAll(preDestroyCallbacksMap.get(s));
184         }
185         return Collections.unmodifiableCollection(list);
186     }
187     
188 }