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 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}
... ...