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.config;
20  
21  import java.lang.reflect.InvocationTargetException;
22  import java.util.Map;
23  import java.util.logging.Level;
24  import java.util.logging.Logger;
25  
26  import javax.faces.component.UIViewRoot;
27  import javax.faces.event.PreDestroyCustomScopeEvent;
28  import javax.faces.event.PreDestroyViewMapEvent;
29  import javax.faces.event.ScopeContext;
30  import javax.faces.event.SystemEvent;
31  import javax.faces.event.SystemEventListener;
32  
33  import org.apache.myfaces.config.annotation.LifecycleProvider;
34  
35  /**
36   * Destroyes managed beans with the current LifecycleProvider.
37   * This guarantees the invocation of the @PreDestroy methods.
38   * @author Jakob Korherr (latest modification by $Author: struberg $)
39   * @version $Revision: 1188694 $ $Date: 2011-10-25 10:07:44 -0500 (Tue, 25 Oct 2011) $
40   * @since 2.0
41   */
42  public class ManagedBeanDestroyer implements SystemEventListener
43  {
44      
45      private static Logger log = Logger.getLogger(ManagedBeanDestroyer.class.getName());
46      
47      private RuntimeConfig _runtimeConfig;
48      private LifecycleProvider _lifecycleProvider;
49  
50      /**
51       * Creates the ManagedBeanDestroyer for the given RuntimeConfig
52       * and LifecycleProvider.
53       * 
54       * @param lifecycleProvider
55       * @param runtimeConfig
56       */
57      public ManagedBeanDestroyer(LifecycleProvider lifecycleProvider,
58                                  RuntimeConfig runtimeConfig)
59      {
60          _lifecycleProvider = lifecycleProvider;
61          _runtimeConfig = runtimeConfig;
62      }
63  
64      public boolean isListenerForSource(Object source)
65      {
66          // source of PreDestroyCustomScopeEvent is ScopeContext
67          // and source of PreDestroyViewMapEvent is UIViewRoot
68          return (source instanceof ScopeContext) || (source instanceof UIViewRoot);
69      }
70  
71      /**
72       * Listens to PreDestroyCustomScopeEvent and PreDestroyViewMapEvent
73       * and invokes destroy() for every managed bean in the associated scope.
74       */
75      public void processEvent(SystemEvent event)
76      {
77          Map<String, Object> scope = null;
78          
79          if (event instanceof PreDestroyViewMapEvent)
80          {
81              UIViewRoot viewRoot = (UIViewRoot) ((PreDestroyViewMapEvent) event).getComponent();
82              scope = viewRoot.getViewMap(false);
83              if (scope == null)
84              {
85                  // view map does not exist --> nothing to destroy
86                  return;
87              }
88          }
89          else if (event instanceof PreDestroyCustomScopeEvent)
90          {
91              ScopeContext scopeContext = ((PreDestroyCustomScopeEvent) event).getContext();
92              scope = scopeContext.getScope();
93          }
94          else
95          {
96              // wrong event
97              return;
98          }
99          
100         for (String key : scope.keySet())
101         {
102             Object value = scope.get(key);
103             this.destroy(key, value);
104         }
105     }
106     
107     /**
108      * Checks if the given managed bean exists in the RuntimeConfig.
109      * @param name
110      * @return
111      */
112     public boolean isManagedBean(String name)
113     {
114         return (_runtimeConfig.getManagedBean(name) != null);
115     }
116     
117     /**
118      * Destroys the given managed bean.
119      * @param name
120      * @param instance
121      */
122     public void destroy(String name, Object instance)
123     {
124         if (instance != null && isManagedBean(name))
125         {
126             try
127             {
128                 _lifecycleProvider.destroyInstance(instance);
129             } 
130             catch (IllegalAccessException e)
131             {
132                 log.log(Level.SEVERE, "Could not access @PreDestroy method of managed bean " + name, e);
133             } 
134             catch (InvocationTargetException e)
135             {
136                 log.log(Level.SEVERE, "An Exception occured while invoking " +
137                         "@PreDestroy method of managed bean " + name, e);
138             }
139         }
140     }
141 
142 }