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 }