View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.webapp;
20  
21  import java.util.Enumeration;
22  
23  import javax.servlet.ServletContext;
24  import javax.servlet.ServletContextAttributeEvent;
25  import javax.servlet.ServletContextAttributeListener;
26  import javax.servlet.ServletContextEvent;
27  import javax.servlet.ServletContextListener;
28  import javax.servlet.ServletRequest;
29  import javax.servlet.ServletRequestAttributeEvent;
30  import javax.servlet.ServletRequestAttributeListener;
31  import javax.servlet.ServletRequestEvent;
32  import javax.servlet.ServletRequestListener;
33  import javax.servlet.http.HttpSessionAttributeListener;
34  import javax.servlet.http.HttpSessionBindingEvent;
35  import javax.servlet.http.HttpSessionEvent;
36  import javax.servlet.http.HttpSessionListener;
37  
38  import org.apache.myfaces.config.ManagedBeanDestroyer;
39  
40  /**
41   * Listens to
42   *   - removing, replacing of attributes in context, session and request
43   *   - destroying of context, session and request
44   * for the ManagedBeanDestroyer to assure right destruction of managed beans in those scopes.
45   * 
46   * This listener is not registered in a tld or web.xml, but will be called by StartupServletContextListener.
47   * 
48   * @author Jakob Korherr (latest modification by $Author: struberg $)
49   * @version $Revision: 1188694 $ $Date: 2011-10-25 10:07:44 -0500 (Tue, 25 Oct 2011) $
50   * @since 2.0
51   */
52  public class ManagedBeanDestroyerListener implements 
53          HttpSessionAttributeListener, HttpSessionListener,
54          ServletContextListener, ServletContextAttributeListener,
55          ServletRequestListener, ServletRequestAttributeListener
56  {
57  
58      /**
59       * The instance of the ManagedBeanDestroyerListener created by
60       * StartupServletContextListener is stored under this key in the
61       * ApplicationMap.
62       */
63      public static final String APPLICATION_MAP_KEY = "org.apache.myfaces.ManagedBeanDestroyerListener";
64  
65      private ManagedBeanDestroyer _destroyer = null;
66  
67      /**
68       * Sets the ManagedBeanDestroyer instance to use.
69       *  
70       * @param destroyer
71       */
72      public void setManagedBeanDestroyer(ManagedBeanDestroyer destroyer)
73      {
74          _destroyer = destroyer;
75      }
76  
77      /* Session related methods ***********************************************/
78      
79      public void attributeAdded(HttpSessionBindingEvent event)
80      {
81          // noop
82      }
83  
84      public void attributeRemoved(HttpSessionBindingEvent event)
85      {
86          if (_destroyer != null)
87          {
88              _destroyer.destroy(event.getName(), event.getValue());
89          }
90      }
91  
92      public void attributeReplaced(HttpSessionBindingEvent event)
93      {
94          if (_destroyer != null)
95          {
96              _destroyer.destroy(event.getName(), event.getValue());
97          }
98      }
99  
100     public void sessionCreated(HttpSessionEvent event)
101     {
102         // noop
103     }
104 
105     @SuppressWarnings("unchecked")
106     public void sessionDestroyed(HttpSessionEvent event)
107     {
108         // MYFACES-3040 @PreDestroy Has Called 2 times
109         // attributeRemoved receives the event too, so it does not 
110         // have sense to handle it here. Unfortunately, it is not possible to 
111         // handle it first and then on attributeRemoved, so the best bet is
112         // let the code in just one place.
113         /*
114         if (_destroyer != null)
115         {
116             HttpSession session = event.getSession();
117             Enumeration<String> attributes = session.getAttributeNames();
118             if (!attributes.hasMoreElements())
119             {
120                 // nothing to do
121                 return;
122             }
123 
124             while (attributes.hasMoreElements())
125             {
126                 String name = attributes.nextElement();
127                 Object value = session.getAttribute(name);
128                 _destroyer.destroy(name, value);
129             }
130         }*/
131     }
132     
133     /* Context related methods ***********************************************/
134     
135     public void attributeAdded(ServletContextAttributeEvent event)
136     {
137         // noop
138     }
139 
140     public void attributeRemoved(ServletContextAttributeEvent event)
141     {
142         if (_destroyer != null)
143         {
144             _destroyer.destroy(event.getName(), event.getValue());
145         }
146     }
147 
148     public void attributeReplaced(ServletContextAttributeEvent event)
149     {
150         if (_destroyer != null)
151         {
152             _destroyer.destroy(event.getName(), event.getValue());
153         }
154     }
155 
156     public void contextInitialized(ServletContextEvent event)
157     {
158         // noop
159     }
160     
161     @SuppressWarnings("unchecked")
162     public void contextDestroyed(ServletContextEvent event)
163     {
164         if (_destroyer != null)
165         {
166             ServletContext ctx = event.getServletContext();
167             Enumeration<String> attributes = ctx.getAttributeNames();
168             if (!attributes.hasMoreElements())
169             {
170                 // nothing to do
171                 return;
172             }
173 
174             while (attributes.hasMoreElements())
175             {
176                 String name = attributes.nextElement();
177                 Object value = ctx.getAttribute(name);
178                 _destroyer.destroy(name, value);
179             }
180         }
181     }
182     
183     /* Request related methods ***********************************************/
184     
185     public void attributeAdded(ServletRequestAttributeEvent event)
186     {
187         // noop
188     }
189 
190     public void attributeRemoved(ServletRequestAttributeEvent event)
191     {
192         if (_destroyer != null)
193         {
194             _destroyer.destroy(event.getName(), event.getValue());
195         }
196     }
197 
198     public void attributeReplaced(ServletRequestAttributeEvent event)
199     {
200         if (_destroyer != null)
201         {
202             _destroyer.destroy(event.getName(), event.getValue());
203         }
204     }
205 
206     public void requestInitialized(ServletRequestEvent event)
207     {
208         // noop
209     }
210     
211     @SuppressWarnings("unchecked")
212     public void requestDestroyed(ServletRequestEvent event)
213     {
214         if (_destroyer != null)
215         {
216             ServletRequest request = event.getServletRequest();
217             Enumeration<String> attributes = request.getAttributeNames();
218             if (!attributes.hasMoreElements())
219             {
220                 // nothing to do
221                 return;
222             }
223             
224             while (attributes.hasMoreElements())
225             {
226                 String name = attributes.nextElement();
227                 Object value = request.getAttribute(name);
228                 _destroyer.destroy(name, value);
229             }
230         }
231     }
232 
233 }