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.faces.context.ExternalContext;
24  import javax.faces.context.FacesContext;
25  import javax.faces.event.PreDestroyCustomScopeEvent;
26  import javax.faces.event.PreDestroyViewMapEvent;
27  import javax.servlet.ServletContext;
28  import javax.servlet.ServletContextAttributeEvent;
29  import javax.servlet.ServletContextAttributeListener;
30  import javax.servlet.ServletContextEvent;
31  import javax.servlet.ServletContextListener;
32  import javax.servlet.ServletRequest;
33  import javax.servlet.ServletRequestAttributeEvent;
34  import javax.servlet.ServletRequestAttributeListener;
35  import javax.servlet.ServletRequestEvent;
36  import javax.servlet.ServletRequestListener;
37  import javax.servlet.http.HttpSession;
38  import javax.servlet.http.HttpSessionAttributeListener;
39  import javax.servlet.http.HttpSessionBindingEvent;
40  import javax.servlet.http.HttpSessionEvent;
41  import javax.servlet.http.HttpSessionListener;
42  
43  import org.apache.myfaces.config.ManagedBeanDestroyer;
44  import org.apache.myfaces.config.RuntimeConfig;
45  import org.apache.myfaces.config.annotation.LifecycleProvider;
46  
47  /**
48   * Listens to
49   *   - removing, replacing of attributes in context, session and request
50   *   - destroying of context, session and request
51   * for the ManagedBeanDestroyer to assure right destruction of managed beans in those scopes.
52   * 
53   * This listener is not registered in a tld or web.xml, but will be called by StartupServletContextListener.
54   * 
55   * @author Jakob Korherr (latest modification by $Author: bommel $)
56   * @version $Revision: 1187700 $ $Date: 2011-10-22 07:19:37 -0500 (Sat, 22 Oct 2011) $
57   * @since 2.0
58   */
59  public class ManagedBeanDestroyerListener implements 
60          HttpSessionAttributeListener, HttpSessionListener,
61          ServletContextListener, ServletContextAttributeListener,
62          ServletRequestListener, ServletRequestAttributeListener
63  {
64  
65      /**
66       * The instance of the ManagedBeanDestroyerListener created by
67       * StartupServletContextListener is stored under this key in the
68       * ApplicationMap.
69       */
70      public static final String APPLICATION_MAP_KEY = "org.apache.myfaces.ManagedBeanDestroyerListener";
71  
72      private ManagedBeanDestroyer _destroyer = null;
73  
74      /**
75       * Sets the ManagedBeanDestroyer instance to use.
76       *  
77       * @param destroyer
78       */
79      public void setManagedBeanDestroyer(ManagedBeanDestroyer destroyer)
80      {
81          _destroyer = destroyer;
82      }
83  
84      /* Session related methods ***********************************************/
85      
86      public void attributeAdded(HttpSessionBindingEvent event)
87      {
88          // noop
89      }
90  
91      public void attributeRemoved(HttpSessionBindingEvent event)
92      {
93          if (_destroyer != null)
94          {
95              _destroyer.destroy(event.getName(), event.getValue());
96          }
97      }
98  
99      public void attributeReplaced(HttpSessionBindingEvent event)
100     {
101         if (_destroyer != null)
102         {
103             _destroyer.destroy(event.getName(), event.getValue());
104         }
105     }
106 
107     public void sessionCreated(HttpSessionEvent event)
108     {
109         // noop
110     }
111 
112     @SuppressWarnings("unchecked")
113     public void sessionDestroyed(HttpSessionEvent event)
114     {
115         // MYFACES-3040 @PreDestroy Has Called 2 times
116         // attributeRemoved receives the event too, so it does not 
117         // have sense to handle it here. Unfortunately, it is not possible to 
118         // handle it first and then on attributeRemoved, so the best bet is
119         // let the code in just one place.
120         /*
121         if (_destroyer != null)
122         {
123             HttpSession session = event.getSession();
124             Enumeration<String> attributes = session.getAttributeNames();
125             if (!attributes.hasMoreElements())
126             {
127                 // nothing to do
128                 return;
129             }
130 
131             while (attributes.hasMoreElements())
132             {
133                 String name = attributes.nextElement();
134                 Object value = session.getAttribute(name);
135                 _destroyer.destroy(name, value);
136             }
137         }*/
138     }
139     
140     /* Context related methods ***********************************************/
141     
142     public void attributeAdded(ServletContextAttributeEvent event)
143     {
144         // noop
145     }
146 
147     public void attributeRemoved(ServletContextAttributeEvent event)
148     {
149         if (_destroyer != null)
150         {
151             _destroyer.destroy(event.getName(), event.getValue());
152         }
153     }
154 
155     public void attributeReplaced(ServletContextAttributeEvent event)
156     {
157         if (_destroyer != null)
158         {
159             _destroyer.destroy(event.getName(), event.getValue());
160         }
161     }
162 
163     public void contextInitialized(ServletContextEvent event)
164     {
165         // noop
166     }
167     
168     @SuppressWarnings("unchecked")
169     public void contextDestroyed(ServletContextEvent event)
170     {
171         if (_destroyer != null)
172         {
173             ServletContext ctx = event.getServletContext();
174             Enumeration<String> attributes = ctx.getAttributeNames();
175             if (!attributes.hasMoreElements())
176             {
177                 // nothing to do
178                 return;
179             }
180 
181             while (attributes.hasMoreElements())
182             {
183                 String name = attributes.nextElement();
184                 Object value = ctx.getAttribute(name);
185                 _destroyer.destroy(name, value);
186             }
187         }
188     }
189     
190     /* Request related methods ***********************************************/
191     
192     public void attributeAdded(ServletRequestAttributeEvent event)
193     {
194         // noop
195     }
196 
197     public void attributeRemoved(ServletRequestAttributeEvent event)
198     {
199         if (_destroyer != null)
200         {
201             _destroyer.destroy(event.getName(), event.getValue());
202         }
203     }
204 
205     public void attributeReplaced(ServletRequestAttributeEvent event)
206     {
207         if (_destroyer != null)
208         {
209             _destroyer.destroy(event.getName(), event.getValue());
210         }
211     }
212 
213     public void requestInitialized(ServletRequestEvent event)
214     {
215         // noop
216     }
217     
218     @SuppressWarnings("unchecked")
219     public void requestDestroyed(ServletRequestEvent event)
220     {
221         if (_destroyer != null)
222         {
223             ServletRequest request = event.getServletRequest();
224             Enumeration<String> attributes = request.getAttributeNames();
225             if (!attributes.hasMoreElements())
226             {
227                 // nothing to do
228                 return;
229             }
230             
231             while (attributes.hasMoreElements())
232             {
233                 String name = attributes.nextElement();
234                 Object value = request.getAttribute(name);
235                 _destroyer.destroy(name, value);
236             }
237         }
238     }
239 
240 }