Commit 618516d9fd1d194bec64fd5c2ec97a8860773742

Authored by Ednara Oliveira
1 parent e2cc082c
Exists in master

Implementação de shutdown para desativar os contextos

impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/CoreBootstrap.java
@@ -86,9 +86,9 @@ public class CoreBootstrap implements Extension { @@ -86,9 +86,9 @@ public class CoreBootstrap implements Extension {
86 } 86 }
87 87
88 public void initializeCustomContexts(@Observes final AfterBeanDiscovery event) { 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 ContextManager.initialize(event); 90 ContextManager.initialize(event);
91 - 91 +
92 ContextManager.activate(StaticContext.class, StaticScoped.class); 92 ContextManager.activate(StaticContext.class, StaticScoped.class);
93 } 93 }
94 94
@@ -97,7 +97,7 @@ public class CoreBootstrap implements Extension { @@ -97,7 +97,7 @@ public class CoreBootstrap implements Extension {
97 } 97 }
98 98
99 public void engineOff(@Observes final BeforeShutdown event) { 99 public void engineOff(@Observes final BeforeShutdown event) {
100 - ContextManager.deactivate(StaticContext.class, StaticScoped.class); 100 + ContextManager.shutdown();
101 getLogger().info(getBundle().getString("engine-off")); 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,6 +9,7 @@ import java.util.Locale;
9 import javax.enterprise.context.ContextNotActiveException; 9 import javax.enterprise.context.ContextNotActiveException;
10 import javax.enterprise.context.spi.Context; 10 import javax.enterprise.context.spi.Context;
11 import javax.enterprise.inject.spi.AfterBeanDiscovery; 11 import javax.enterprise.inject.spi.AfterBeanDiscovery;
  12 +import javax.enterprise.inject.spi.BeanManager;
12 13
13 import org.slf4j.Logger; 14 import org.slf4j.Logger;
14 15
@@ -20,62 +21,82 @@ import br.gov.frameworkdemoiselle.util.Beans; @@ -20,62 +21,82 @@ import br.gov.frameworkdemoiselle.util.Beans;
20 import br.gov.frameworkdemoiselle.util.ResourceBundle; 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 * @author serpro 41 * @author serpro
36 - *  
37 */ 42 */
38 public class ContextManager { 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 private static boolean initialized = false; 48 private static boolean initialized = false;
43 - 49 +
44 private static ResourceBundle bundle; 50 private static ResourceBundle bundle;
45 - 51 +
46 private static Logger logger; 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 return; 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 return; 100 return;
80 } 101 }
81 } 102 }
@@ -84,154 +105,172 @@ public class ContextManager { @@ -84,154 +105,172 @@ public class ContextManager {
84 event.addContext(context); 105 event.addContext(context);
85 contexts.add(new CustomContextCounter(context)); 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 * <ul> 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 * <li>Must be of a scope not already attached to another active context</li> 118 * <li>Must be of a scope not already attached to another active context</li>
96 - *  
97 * </ul> 119 * </ul>
98 * </p> 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 throw new DemoiselleException(getBundle().getString("custom-context-manager-not-initialized")); 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 context.activate(); 140 context.activate();
115 return; 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 * <ul> 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 * <li>Must have been activated by a previous call to {@link #activate(Class customContextClass, Class scope)}</li> 158 * <li>Must have been activated by a previous call to {@link #activate(Class customContextClass, Class scope)}</li>
130 * <li>This previous call must have returned <code>true</code>. 159 * <li>This previous call must have returned <code>true</code>.
131 - *  
132 * </ul> 160 * </ul>
133 * </p> 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 throw new DemoiselleException(getBundle().getString("custom-context-manager-not-initialized")); 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 context.deactivate(); 180 context.deactivate();
150 return; 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 logger = LoggerProducer.create(ContextManager.class); 200 logger = LoggerProducer.create(ContextManager.class);
160 } 201 }
161 - 202 +
162 return logger; 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 return bundle; 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 * @author serpro 220 * @author serpro
179 - *  
180 */ 221 */
181 -class CustomContextCounter{ 222 +class CustomContextCounter {
  223 +
182 private CustomContext context; 224 private CustomContext context;
  225 +
183 private int activationCounter = 0; 226 private int activationCounter = 0;
184 - 227 +
185 public CustomContextCounter(CustomContext customContext) { 228 public CustomContextCounter(CustomContext customContext) {
186 this.context = customContext; 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 return true; 235 return true;
193 } 236 }
194 - 237 +
195 return false; 238 return false;
196 } 239 }
197 -  
198 - public CustomContext getInternalContext(){ 240 +
  241 + public CustomContext getInternalContext() {
199 return this.context; 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 activationCounter++; 250 activationCounter++;
207 } 251 }
208 - }  
209 - catch(ContextNotActiveException ce){ 252 + } catch (ContextNotActiveException ce) {
210 context.setActive(true); 253 context.setActive(true);
211 activationCounter++; 254 activationCounter++;
212 ContextManager.getLogger().trace( 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 Context c = Beans.getBeanManager().getContext(context.getScope()); 263 Context c = Beans.getBeanManager().getContext(context.getScope());
223 - if (c==context){ 264 + if (c == context) {
224 activationCounter--; 265 activationCounter--;
225 - if (activationCounter==0){ 266 + if (activationCounter == 0) {
226 context.setActive(false); 267 context.setActive(false);
227 ContextManager.getLogger().trace( 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,6 +53,7 @@ transaction-commited=Transa\u00E7\u00E3o finalizada com sucesso
53 transaction-rolledback=Transa\u00E7\u00E3o finalizada com rollback 53 transaction-rolledback=Transa\u00E7\u00E3o finalizada com rollback
54 54
55 bootstrap.configuration.processing=Processando {0} 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 loading-configuration-class=Carregando a classe de configura\u00E7\u00E3o {0} 58 loading-configuration-class=Carregando a classe de configura\u00E7\u00E3o {0}
58 configuration-field-loaded=Configura\u00E7\u00E3o {0} atribu\u00EDda a {1} com o valor {2} 59 configuration-field-loaded=Configura\u00E7\u00E3o {0} atribu\u00EDda a {1} com o valor {2}