View Javadoc

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