Commit 618516d9fd1d194bec64fd5c2ec97a8860773742
1 parent
e2cc082c
Exists in
master
Implementação de shutdown para desativar os contextos
Showing
3 changed files
with
163 additions
and
123 deletions
Show diff stats
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/CoreBootstrap.java
... | ... | @@ -86,9 +86,9 @@ public class CoreBootstrap implements Extension { |
86 | 86 | } |
87 | 87 | |
88 | 88 | public void initializeCustomContexts(@Observes final AfterBeanDiscovery event) { |
89 | - //StaticContext já é criado e gerenciado por esta chamada | |
89 | + // StaticContext já é criado e gerenciado por esta chamada | |
90 | 90 | ContextManager.initialize(event); |
91 | - | |
91 | + | |
92 | 92 | ContextManager.activate(StaticContext.class, StaticScoped.class); |
93 | 93 | } |
94 | 94 | |
... | ... | @@ -97,7 +97,7 @@ public class CoreBootstrap implements Extension { |
97 | 97 | } |
98 | 98 | |
99 | 99 | public void engineOff(@Observes final BeforeShutdown event) { |
100 | - ContextManager.deactivate(StaticContext.class, StaticScoped.class); | |
100 | + ContextManager.shutdown(); | |
101 | 101 | getLogger().info(getBundle().getString("engine-off")); |
102 | 102 | } |
103 | 103 | } | ... | ... |
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextManager.java
... | ... | @@ -9,6 +9,7 @@ import java.util.Locale; |
9 | 9 | import javax.enterprise.context.ContextNotActiveException; |
10 | 10 | import javax.enterprise.context.spi.Context; |
11 | 11 | import javax.enterprise.inject.spi.AfterBeanDiscovery; |
12 | +import javax.enterprise.inject.spi.BeanManager; | |
12 | 13 | |
13 | 14 | import org.slf4j.Logger; |
14 | 15 | |
... | ... | @@ -20,62 +21,82 @@ import br.gov.frameworkdemoiselle.util.Beans; |
20 | 21 | import br.gov.frameworkdemoiselle.util.ResourceBundle; |
21 | 22 | |
22 | 23 | /** |
23 | - * <p>Manage custom contexts relevant to Demoiselle operations.</p> | |
24 | - * | |
25 | - * <p>When starting, the ContextManager must be initialized by calling {@link #initialize(AfterBeanDiscovery event)} | |
26 | - * inside any methods observing the {@link AfterBeanDiscovery} event. Upon initialization a {@link StaticContext} will be | |
27 | - * created to handle {@link StaticScoped} beans (but not activated, you must call {@link #activate(Class customContextClass, Class scope)} | |
28 | - * to activate this context).</p> | |
29 | - * | |
30 | - * <p>If an extension wants to manage another custom context, it must first call {@link #add(CustomContext context, AfterBeanDiscovery event)} | |
31 | - * to add it's context to the list of managed contexts and then call {@link #activate(Class customContextClass, Class scope)} whenever | |
32 | - * it wants to activate this added context (contexts added through the {@link #add(CustomContext context, AfterBeanDiscovery event)} method are also | |
33 | - * not activated upon adding).</p> | |
24 | + * <p> | |
25 | + * Manage custom contexts relevant to Demoiselle operations. | |
26 | + * </p> | |
27 | + * <p> | |
28 | + * When starting, the ContextManager must be initialized by calling {@link #initialize(AfterBeanDiscovery event)} inside | |
29 | + * any methods observing the {@link AfterBeanDiscovery} event. Upon initialization a {@link StaticContext} will be | |
30 | + * created to handle {@link StaticScoped} beans (but not activated, you must call | |
31 | + * {@link #activate(Class customContextClass, Class scope)} to activate this context). | |
32 | + * </p> | |
33 | + * <p> | |
34 | + * If an extension wants to manage another custom context, it must first call | |
35 | + * {@link #add(CustomContext context, AfterBeanDiscovery event)} to add it's context to the list of managed contexts and | |
36 | + * then call {@link #activate(Class customContextClass, Class scope)} whenever it wants to activate this added context | |
37 | + * (contexts added through the {@link #add(CustomContext context, AfterBeanDiscovery event)} method are also not | |
38 | + * activated upon adding). | |
39 | + * </p> | |
34 | 40 | * |
35 | 41 | * @author serpro |
36 | - * | |
37 | 42 | */ |
38 | 43 | public class ContextManager { |
39 | - | |
40 | - private static List<CustomContextCounter> contexts = Collections.synchronizedList(new ArrayList<CustomContextCounter>()); | |
41 | - | |
44 | + | |
45 | + private static List<CustomContextCounter> contexts = Collections | |
46 | + .synchronizedList(new ArrayList<CustomContextCounter>()); | |
47 | + | |
42 | 48 | private static boolean initialized = false; |
43 | - | |
49 | + | |
44 | 50 | private static ResourceBundle bundle; |
45 | - | |
51 | + | |
46 | 52 | private static Logger logger; |
47 | - | |
53 | + | |
48 | 54 | /** |
49 | - * <p>Initializes this manager and adds the {@link StaticContext} context to the list of managed contexts. Other | |
50 | - * contexts must be added before they can be activated.</p> | |
51 | - * | |
52 | - * <p>It's OK to call this method multiple times, it will be initialized only once.</p> | |
55 | + * <p> | |
56 | + * Initializes this manager and adds the {@link StaticContext} context to the list of managed contexts. Other | |
57 | + * contexts must be added before they can be activated. | |
58 | + * </p> | |
59 | + * <p> | |
60 | + * It's OK to call this method multiple times, it will be initialized only once. | |
61 | + * </p> | |
53 | 62 | * |
54 | - * @param event The CDI event indicating all beans have been discovered. | |
63 | + * @param event | |
64 | + * The CDI event indicating all beans have been discovered. | |
55 | 65 | */ |
56 | - public static void initialize(AfterBeanDiscovery event){ | |
57 | - if (initialized){ | |
66 | + public static void initialize(AfterBeanDiscovery event) { | |
67 | + if (initialized) { | |
58 | 68 | return; |
59 | 69 | } |
60 | - | |
61 | - add(new StaticContext(),event); | |
62 | - initialized=true; | |
70 | + | |
71 | + add(new StaticContext(), event); | |
72 | + initialized = true; | |
63 | 73 | } |
64 | - | |
74 | + | |
65 | 75 | /** |
66 | - * <p>Adds a context to the list of managed contexts.</p> | |
67 | - * | |
68 | - * <p>A context added through this method will be deactivated before management can start. Only after calling | |
69 | - * {@link #activate(Class customContextClass, Class scope)} the context will be activated.</p> | |
70 | - * | |
71 | - * <p>Trying to add a context already managed will result in this method call being ignored.</p> | |
76 | + * <p> | |
77 | + * Adds a context to the list of managed contexts. | |
78 | + * </p> | |
79 | + * <p> | |
80 | + * A context added through this method will be deactivated before management can start. Only after calling | |
81 | + * {@link #activate(Class customContextClass, Class scope)} the context will be activated. | |
82 | + * </p> | |
83 | + * <p> | |
84 | + * Trying to add a context already managed will result in this method call being ignored. | |
85 | + * </p> | |
72 | 86 | * |
73 | - * @param context The context to be added | |
74 | - * @param event The CDI event indicating all beans have been discovered. | |
87 | + * @param context | |
88 | + * The context to be added | |
89 | + * @param event | |
90 | + * The CDI event indicating all beans have been discovered. | |
75 | 91 | */ |
76 | - public static void add(CustomContext context,AfterBeanDiscovery event){ | |
77 | - for (CustomContextCounter contextCounter : contexts){ | |
78 | - if (contextCounter.isSame(context.getClass(), context.getScope())){ | |
92 | + public static void add(CustomContext context, AfterBeanDiscovery event) { | |
93 | + for (CustomContextCounter contextCounter : contexts) { | |
94 | + if (contextCounter.isSame(context.getClass(), context.getScope())) { | |
95 | + | |
96 | + ContextManager.getLogger().trace( | |
97 | + ContextManager.getBundle().getString("bootstrap-context-already-managed", | |
98 | + context.getClass().getCanonicalName(), context.getScope().getCanonicalName())); | |
99 | + | |
79 | 100 | return; |
80 | 101 | } |
81 | 102 | } |
... | ... | @@ -84,154 +105,172 @@ public class ContextManager { |
84 | 105 | event.addContext(context); |
85 | 106 | contexts.add(new CustomContextCounter(context)); |
86 | 107 | } |
87 | - | |
108 | + | |
88 | 109 | /** |
89 | - * <p>Activates a managed context.</p> | |
90 | - * | |
91 | - * <p>To be activated, a context must fulfill the following requisites: | |
110 | + * <p> | |
111 | + * Activates a managed context. | |
112 | + * </p> | |
113 | + * <p> | |
114 | + * To be activated, a context must fulfill the following requisites: | |
92 | 115 | * <ul> |
93 | - * | |
94 | - * <li>Must be managed by this class (be of type {@link StaticScoped} or be added with {@link #add(CustomContext context, AfterBeanDiscovery event)})</li> | |
116 | + * <li>Must be managed by this class (be of type {@link StaticScoped} or be added with | |
117 | + * {@link #add(CustomContext context, AfterBeanDiscovery event)})</li> | |
95 | 118 | * <li>Must be of a scope not already attached to another active context</li> |
96 | - * | |
97 | 119 | * </ul> |
98 | 120 | * </p> |
99 | 121 | * |
100 | - * @param customContextClass Type of context to activate | |
101 | - * @param scope The scope to activate this context for | |
102 | - * @return <code>true</code> if there is a managed context of the provided type and scope and no other context is active for the provided scope, | |
103 | - * <code>false</code> if there is a managed context of the provided type and scope but another context is active for the provided scope. | |
104 | - * | |
105 | - * @throws DemoiselleException if there is no managed context of the provided type and scope. | |
122 | + * @param customContextClass | |
123 | + * Type of context to activate | |
124 | + * @param scope | |
125 | + * The scope to activate this context for | |
126 | + * @return <code>true</code> if there is a managed context of the provided type and scope and no other context is | |
127 | + * active for the provided scope, <code>false</code> if there is a managed context of the provided type and | |
128 | + * scope but another context is active for the provided scope. | |
129 | + * @throws DemoiselleException | |
130 | + * if there is no managed context of the provided type and scope. | |
106 | 131 | */ |
107 | - public static synchronized void activate(Class<? extends CustomContext> customContextClass , Class<? extends Annotation> scope){ | |
108 | - if (!initialized){ | |
132 | + public static synchronized void activate(Class<? extends CustomContext> customContextClass, | |
133 | + Class<? extends Annotation> scope) { | |
134 | + if (!initialized) { | |
109 | 135 | throw new DemoiselleException(getBundle().getString("custom-context-manager-not-initialized")); |
110 | 136 | } |
111 | - | |
112 | - for (CustomContextCounter context : contexts){ | |
113 | - if ( context.isSame(customContextClass, scope) ){ | |
137 | + | |
138 | + for (CustomContextCounter context : contexts) { | |
139 | + if (context.isSame(customContextClass, scope)) { | |
114 | 140 | context.activate(); |
115 | 141 | return; |
116 | 142 | } |
117 | 143 | } |
118 | 144 | |
119 | - throw new DemoiselleException(getBundle().getString("custom-context-not-found",customContextClass.getCanonicalName(),scope.getSimpleName())); | |
145 | + throw new DemoiselleException(getBundle().getString("custom-context-not-found", | |
146 | + customContextClass.getCanonicalName(), scope.getSimpleName())); | |
120 | 147 | } |
121 | - | |
148 | + | |
122 | 149 | /** |
123 | - * <p>Deactivates a managed context.</p> | |
124 | - * | |
125 | - * <p>To be deactivated, a context must fulfill the following requisites: | |
150 | + * <p> | |
151 | + * Deactivates a managed context. | |
152 | + * </p> | |
153 | + * <p> | |
154 | + * To be deactivated, a context must fulfill the following requisites: | |
126 | 155 | * <ul> |
127 | - * | |
128 | - * <li>Must be managed by this class (be of type {@link StaticScoped} or be added with {@link #add(CustomContext context, AfterBeanDiscovery event)})</li> | |
156 | + * <li>Must be managed by this class (be of type {@link StaticScoped} or be added with | |
157 | + * {@link #add(CustomContext context, AfterBeanDiscovery event)})</li> | |
129 | 158 | * <li>Must have been activated by a previous call to {@link #activate(Class customContextClass, Class scope)}</li> |
130 | 159 | * <li>This previous call must have returned <code>true</code>. |
131 | - * | |
132 | 160 | * </ul> |
133 | 161 | * </p> |
134 | 162 | * |
135 | - * @param customContextClass Type of context to deactivate | |
136 | - * @param scope The scope the context controled when it was active | |
137 | - * @return <code>true</code> if there was an active context of this type and scope and it was activated by a previous | |
138 | - * call to {@link #activate(Class customContextClass, Class scope)} | |
139 | - * | |
140 | - * @throws DemoiselleException if there is no managed context of the provided type and scope. | |
163 | + * @param customContextClass | |
164 | + * Type of context to deactivate | |
165 | + * @param scope | |
166 | + * The scope the context controled when it was active | |
167 | + * @return <code>true</code> if there was an active context of this type and scope and it was activated by a | |
168 | + * previous call to {@link #activate(Class customContextClass, Class scope)} | |
169 | + * @throws DemoiselleException | |
170 | + * if there is no managed context of the provided type and scope. | |
141 | 171 | */ |
142 | - public static synchronized void deactivate(Class<? extends CustomContext> customContextClass,Class<? extends Annotation> scope){ | |
143 | - if (!initialized){ | |
172 | + public static synchronized void deactivate(Class<? extends CustomContext> customContextClass, | |
173 | + Class<? extends Annotation> scope) { | |
174 | + if (!initialized) { | |
144 | 175 | throw new DemoiselleException(getBundle().getString("custom-context-manager-not-initialized")); |
145 | 176 | } |
146 | - | |
147 | - for (CustomContextCounter context : contexts){ | |
148 | - if (context.isSame(customContextClass, scope)){ | |
177 | + | |
178 | + for (CustomContextCounter context : contexts) { | |
179 | + if (context.isSame(customContextClass, scope)) { | |
149 | 180 | context.deactivate(); |
150 | 181 | return; |
151 | 182 | } |
152 | 183 | } |
153 | 184 | |
154 | - throw new DemoiselleException(getBundle().getString("custom-context-not-found",customContextClass.getCanonicalName(),scope.getSimpleName())); | |
185 | + throw new DemoiselleException(getBundle().getString("custom-context-not-found", | |
186 | + customContextClass.getCanonicalName(), scope.getSimpleName())); | |
155 | 187 | } |
156 | 188 | |
157 | - static Logger getLogger(){ | |
158 | - if (logger==null){ | |
189 | + public static synchronized void shutdown() { | |
190 | + for (CustomContextCounter context : contexts) { | |
191 | + context.deactivate(); | |
192 | + } | |
193 | + | |
194 | + contexts.clear(); | |
195 | + initialized = false; | |
196 | + } | |
197 | + | |
198 | + static Logger getLogger() { | |
199 | + if (logger == null) { | |
159 | 200 | logger = LoggerProducer.create(ContextManager.class); |
160 | 201 | } |
161 | - | |
202 | + | |
162 | 203 | return logger; |
163 | 204 | } |
164 | - | |
165 | - static ResourceBundle getBundle(){ | |
166 | - if (bundle==null){ | |
167 | - bundle = ResourceBundleProducer.create("demoiselle-core-bundle",Locale.getDefault()); | |
205 | + | |
206 | + static ResourceBundle getBundle() { | |
207 | + if (bundle == null) { | |
208 | + bundle = ResourceBundleProducer.create("demoiselle-core-bundle", Locale.getDefault()); | |
168 | 209 | } |
169 | - | |
210 | + | |
170 | 211 | return bundle; |
171 | 212 | } |
172 | 213 | } |
214 | + | |
173 | 215 | /** |
174 | - * Class that counts how many attemps to activate and deactivate this context received, avoiding cases | |
175 | - * where one client activates given context and another one deactivates it, leaving the first client | |
176 | - * with no active context before completion. | |
216 | + * Class that counts how many attemps to activate and deactivate this context received, avoiding cases where one client | |
217 | + * activates given context and another one deactivates it, leaving the first client with no active context before | |
218 | + * completion. | |
177 | 219 | * |
178 | 220 | * @author serpro |
179 | - * | |
180 | 221 | */ |
181 | -class CustomContextCounter{ | |
222 | +class CustomContextCounter { | |
223 | + | |
182 | 224 | private CustomContext context; |
225 | + | |
183 | 226 | private int activationCounter = 0; |
184 | - | |
227 | + | |
185 | 228 | public CustomContextCounter(CustomContext customContext) { |
186 | 229 | this.context = customContext; |
187 | 230 | } |
188 | - | |
189 | - public boolean isSame(Class<? extends CustomContext> customContextClass,Class<? extends Annotation> scope){ | |
190 | - if (context.getClass().getCanonicalName().equals( customContextClass.getCanonicalName() ) | |
191 | - && context.getScope().equals(scope)){ | |
231 | + | |
232 | + public boolean isSame(Class<? extends CustomContext> customContextClass, Class<? extends Annotation> scope) { | |
233 | + if (context.getClass().getCanonicalName().equals(customContextClass.getCanonicalName()) | |
234 | + && context.getScope().equals(scope)) { | |
192 | 235 | return true; |
193 | 236 | } |
194 | - | |
237 | + | |
195 | 238 | return false; |
196 | 239 | } |
197 | - | |
198 | - public CustomContext getInternalContext(){ | |
240 | + | |
241 | + public CustomContext getInternalContext() { | |
199 | 242 | return this.context; |
200 | 243 | } |
201 | - | |
202 | - public synchronized void activate(){ | |
203 | - try{ | |
204 | - Context c = Beans.getBeanManager().getContext(context.getScope()); | |
205 | - if (c==context){ | |
244 | + | |
245 | + public synchronized void activate() { | |
246 | + try { | |
247 | + BeanManager beanManager = Beans.getReference(BeanManager.class); | |
248 | + Context c = beanManager.getContext(context.getScope()); | |
249 | + if (c == context) { | |
206 | 250 | activationCounter++; |
207 | 251 | } |
208 | - } | |
209 | - catch(ContextNotActiveException ce){ | |
252 | + } catch (ContextNotActiveException ce) { | |
210 | 253 | context.setActive(true); |
211 | 254 | activationCounter++; |
212 | 255 | ContextManager.getLogger().trace( |
213 | - ContextManager.getBundle().getString("custom-context-was-activated" | |
214 | - , context.getClass().getCanonicalName() | |
215 | - ,context.getScope().getCanonicalName() | |
216 | - )); | |
256 | + ContextManager.getBundle().getString("custom-context-was-activated", | |
257 | + context.getClass().getCanonicalName(), context.getScope().getCanonicalName())); | |
217 | 258 | } |
218 | 259 | } |
219 | - | |
220 | - public synchronized void deactivate(){ | |
221 | - try{ | |
260 | + | |
261 | + public synchronized void deactivate() { | |
262 | + try { | |
222 | 263 | Context c = Beans.getBeanManager().getContext(context.getScope()); |
223 | - if (c==context){ | |
264 | + if (c == context) { | |
224 | 265 | activationCounter--; |
225 | - if (activationCounter==0){ | |
266 | + if (activationCounter == 0) { | |
226 | 267 | context.setActive(false); |
227 | 268 | ContextManager.getLogger().trace( |
228 | - ContextManager.getBundle().getString("custom-context-was-deactivated" | |
229 | - , context.getClass().getCanonicalName() | |
230 | - ,context.getScope().getCanonicalName() | |
231 | - )); | |
269 | + ContextManager.getBundle().getString("custom-context-was-deactivated", | |
270 | + context.getClass().getCanonicalName(), context.getScope().getCanonicalName())); | |
232 | 271 | } |
233 | 272 | } |
273 | + } catch (ContextNotActiveException ce) { | |
234 | 274 | } |
235 | - catch(ContextNotActiveException ce){} | |
236 | 275 | } |
237 | 276 | } | ... | ... |
impl/core/src/main/resources/demoiselle-core-bundle.properties
... | ... | @@ -53,6 +53,7 @@ transaction-commited=Transa\u00E7\u00E3o finalizada com sucesso |
53 | 53 | transaction-rolledback=Transa\u00E7\u00E3o finalizada com rollback |
54 | 54 | |
55 | 55 | bootstrap.configuration.processing=Processando {0} |
56 | +bootstrap-context-already-managed=O contexto {0} para o escopo {1} j\u00E1 \u00E9 gerenciado | |
56 | 57 | |
57 | 58 | loading-configuration-class=Carregando a classe de configura\u00E7\u00E3o {0} |
58 | 59 | configuration-field-loaded=Configura\u00E7\u00E3o {0} atribu\u00EDda a {1} com o valor {2} | ... | ... |