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