diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextManager.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextManager.java index 923894f..2e940f8 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextManager.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextManager.java @@ -10,6 +10,7 @@ import javax.enterprise.context.ContextNotActiveException; import javax.enterprise.context.spi.Context; import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.BeforeShutdown; import org.slf4j.Logger; @@ -103,6 +104,10 @@ public class ContextManager { } } + ContextManager.getLogger().trace( + ContextManager.getBundle().getString("bootstrap-context-added", + context.getClass().getCanonicalName(), context.getScope().getCanonicalName())); + context.setActive(false); event.addContext(context); contexts.add(new CustomContextCounter(context)); @@ -188,9 +193,13 @@ public class ContextManager { customContextClass.getCanonicalName(), scope.getSimpleName())); } + /** + *

This method should be called when the application is shutting down, usually by observing + * the {@link BeforeShutdown} event.

+ */ public static synchronized void shutdown() { for (CustomContextCounter context : contexts) { - context.deactivate(); + context.shutdown(); } contexts.clear(); @@ -243,14 +252,29 @@ class CustomContextCounter { public CustomContext getInternalContext() { return this.context; } + + public void setInternalContext(CustomContext context) { + this.context = context; + } public synchronized void activate() { try { BeanManager beanManager = Beans.getReference(BeanManager.class); Context c = beanManager.getContext(context.getScope()); + + if (c == context) { activationCounter++; } + else{ + ContextManager.getLogger().trace( + ContextManager.getBundle().getString("custom-context-already-activated", + context.getClass().getCanonicalName() + ,c.getScope().getCanonicalName() + ,c.getClass().getCanonicalName() + ) + ); + } } catch (ContextNotActiveException ce) { context.setActive(true); activationCounter++; @@ -275,4 +299,10 @@ class CustomContextCounter { } catch (ContextNotActiveException ce) { } } + + public synchronized void shutdown() { + context.setActive(false); + context=null; + activationCounter=0; + } } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java index c25dd6b..ae77808 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java @@ -67,8 +67,8 @@ import br.gov.frameworkdemoiselle.util.Beans; import br.gov.frameworkdemoiselle.util.ResourceBundle; /** - * Central class used by management extensions to obtain information, access properties and call operations - * over discovered {@link ManagementController} classes. + * Central class used by management extensions to obtain information, access properties and call operations over + * discovered {@link ManagementController} classes. * * @author serpro */ @@ -83,20 +83,18 @@ public class Management { private ResourceBundle bundle; private final List managedTypes = new ArrayList(); - + private Validator validator; public void addManagedType(ManagedType managedType) { managedTypes.add(managedType); - logger.debug(bundle.getString("management-debug-registering-managed-type",managedType.getType().getCanonicalName())); + logger.debug(bundle.getString("management-debug-registering-managed-type", managedType.getType() + .getCanonicalName())); } /** - * @return List all discovered {@link ManagementController} classes. - * The returned list is a shallow copy of the internal list, so you - * are free to modify it. - * - * TODO precisamos desse clone na lista? + * @return List all discovered {@link ManagementController} classes. The returned list is a shallow copy of the + * internal list, so you are free to modify it. TODO precisamos desse clone na lista? */ public List getManagedTypes() { ArrayList cloneList = new ArrayList(); @@ -105,77 +103,78 @@ public class Management { } /** - *

Invoke an operation over a {@link ManagementController}.

- * - *

This method is not thread-safe, it's the user's responsibility to - * make the operations of the managed type synchronized if necessary.

+ *

+ * Invoke an operation over a {@link ManagementController}. + *

+ *

+ * This method is not thread-safe, it's the user's responsibility to make the operations of the managed type + * synchronized if necessary. + *

* * @param managedType - * A type annotated with {@link ManagementController}. This method will create - * an (or obtain an already created) instance of this type and - * invoke the operation over it. + * A type annotated with {@link ManagementController}. This method will create an (or obtain an already + * created) instance of this type and invoke the operation over it. * @param actionName - * Name of method to be invoked, the type must have this - * operation on it's list + * Name of method to be invoked, the type must have this operation on it's list * @param params - * List of values for the operation parameters. Can be - * null if the operation require no parameters. - * @return The return value of the original invoked operation. Methods of - * return type void will return the {@link Void} type. + * List of values for the operation parameters. Can be null if the operation require no + * parameters. + * @return The return value of the original invoked operation. Methods of return type void will return + * the {@link Void} type. * @throws ReflectionException - * In case the operation doesn't exist or have a different - * signature + * In case the operation doesn't exist or have a different signature */ - public Object invoke(ManagedType managedType, String actionName, - Object[] params) { - if ( managedTypes.contains(managedType) ) { + public Object invoke(ManagedType managedType, String actionName, Object[] params) { + if (managedTypes.contains(managedType)) { activateContexts(managedType.getType()); - Object delegate = Beans.getReference(managedType.getType()); - - MethodDetail method = managedType.getOperationMethods().get(actionName); - - if (method != null) { - try { - logger.debug(bundle - .getString("management-debug-invoking-operation",actionName,managedType.getType().getCanonicalName())); - return method.getMethod().invoke(delegate, params); - } catch (Exception e) { - throw new DemoiselleException(bundle.getString( - "management-invoke-error", actionName), e); - } finally { - deactivateContexts(managedType.getType()); + try { + Object delegate = Beans.getReference(managedType.getType()); + MethodDetail method = managedType.getOperationMethods().get(actionName); + + if (method != null) { + try { + logger.debug(bundle.getString("management-debug-invoking-operation", actionName, managedType + .getType().getCanonicalName())); + return method.getMethod().invoke(delegate, params); + } catch (Exception e) { + throw new DemoiselleException(bundle.getString("management-invoke-error", actionName), e); + } + } else { + throw new DemoiselleException(bundle.getString("management-invoke-error", actionName)); } - } else { - throw new DemoiselleException(bundle.getString( - "management-invoke-error", actionName)); + } finally { + deactivateContexts(managedType.getType()); } } else { - throw new DemoiselleException( - bundle.getString("management-type-not-found")); + throw new DemoiselleException(bundle.getString("management-type-not-found")); } } /** - *

Retrieve the current value of a property from a managed type. Properties - * are attributes annotated with {@link ManagedProperty}.

+ *

+ * Retrieve the current value of a property from a managed type. Properties are attributes annotated with + * {@link ManagedProperty}. + *

+ *

+ * This method is not thread-safe, it's the user's responsibility to create the property's access methods from the + * managed type synchronized if necessary. + *

* - *

This method is not thread-safe, it's the user's responsibility to - * create the property's access methods from the managed type synchronized if necessary.

- * - * @param managedType The type that has the property the client wants to know the value of. - * @param propertyName The name of the property + * @param managedType + * The type that has the property the client wants to know the value of. + * @param propertyName + * The name of the property * @return The current value of the property */ public Object getProperty(ManagedType managedType, String propertyName) { - - if ( managedTypes.contains(managedType) ) { + + if (managedTypes.contains(managedType)) { Method getterMethod = managedType.getFields().get(propertyName).getGetterMethod(); if (getterMethod != null) { - logger.debug(bundle.getString( - "management-debug-acessing-property", getterMethod - .getName(), managedType.getType().getCanonicalName())); + logger.debug(bundle.getString("management-debug-acessing-property", getterMethod.getName(), managedType + .getType().getCanonicalName())); activateContexts(managedType.getType()); @@ -184,43 +183,44 @@ public class Management { return getterMethod.invoke(delegate, (Object[]) null); } catch (Exception e) { - throw new DemoiselleException(bundle.getString( - "management-invoke-error", getterMethod.getName()), + throw new DemoiselleException(bundle.getString("management-invoke-error", getterMethod.getName()), e); } finally { deactivateContexts(managedType.getType()); } } else { - throw new DemoiselleException(bundle.getString( - "management-invoke-error", propertyName)); + throw new DemoiselleException(bundle.getString("management-invoke-error", propertyName)); } } else { - throw new DemoiselleException( - bundle.getString("management-type-not-found")); + throw new DemoiselleException(bundle.getString("management-type-not-found")); } } - + /** - *

Sets a new value for a property contained inside a managed type. A property - * is an attribute annotated with {@link ManagedProperty}.

+ *

+ * Sets a new value for a property contained inside a managed type. A property is an attribute annotated with + * {@link ManagedProperty}. + *

+ *

+ * This method is not thread-safe, it's the user's responsibility to create the property's access methods from the + * managed type synchronized if necessary. + *

* - *

This method is not thread-safe, it's the user's responsibility to - * create the property's access methods from the managed type synchronized if necessary.

- * - * @param managedType The type that has access to the property - * @param propertyName The name of the property - * @param newValue The new value of the property + * @param managedType + * The type that has access to the property + * @param propertyName + * The name of the property + * @param newValue + * The new value of the property */ - public void setProperty(ManagedType managedType, String propertyName, - Object newValue) { + public void setProperty(ManagedType managedType, String propertyName, Object newValue) { - if ( managedTypes.contains(managedType) ) { + if (managedTypes.contains(managedType)) { // Procura o método set do atributo em questão Method method = managedType.getFields().get(propertyName).getSetterMethod(); if (method != null) { - logger.debug(bundle.getString( - "management-debug-setting-property", method.getName(), - managedType.getType().getCanonicalName())); + logger.debug(bundle.getString("management-debug-setting-property", method.getName(), managedType + .getType().getCanonicalName())); activateContexts(managedType.getType()); try { @@ -228,93 +228,80 @@ public class Management { // classes // anotadas com @ManagementController são sempre singletons. Object delegate = Beans.getReference(managedType.getType()); - - //Se houver um validador anexado à propriedade alterada, executa o validador sobre - //o novo valor. + + // Se houver um validador anexado à propriedade alterada, executa o validador sobre + // o novo valor. Validator validator = getDefaultValidator(); - if (validator!=null){ + if (validator != null) { Set violations = validator.validateValue(managedType.getType(), propertyName, newValue); - if (violations.size()>0){ + if (violations.size() > 0) { StringBuffer errorBuffer = new StringBuffer(); - for (Object objectViolation : violations){ + for (Object objectViolation : violations) { ConstraintViolation violation = (ConstraintViolation) objectViolation; errorBuffer.append(violation.getMessage()).append('\r').append('\n'); } - - if (errorBuffer.length()>0){ + + if (errorBuffer.length() > 0) { errorBuffer.insert(0, "\r\n"); errorBuffer.insert(errorBuffer.length(), "\r\n"); } - - throw new DemoiselleException( - bundle.getString( - "management-validation-constraint-violation" - ,managedType.getType().getCanonicalName() - ,propertyName,errorBuffer.toString() - ) - ); + + throw new DemoiselleException(bundle.getString( + "management-validation-constraint-violation", managedType.getType() + .getCanonicalName(), propertyName, errorBuffer.toString())); } - } - else{ + } else { logger.warn(bundle.getString("management-validation-validator-not-found")); } Method getterMethod = managedType.getFields().get(propertyName).getGetterMethod(); Object oldValue; - try{ - oldValue = getterMethod.invoke(delegate, (Object[])null); - } - catch(Exception e){ + try { + oldValue = getterMethod.invoke(delegate, (Object[]) null); + } catch (Exception e) { oldValue = null; } method.invoke(delegate, new Object[] { newValue }); - //Manda uma notificação de mudança de atributo + // Manda uma notificação de mudança de atributo NotificationManager notificationManager = Beans.getReference(NotificationManager.class); - Class attributeType = newValue!=null ? newValue.getClass() : null; - - AttributeChangeNotification notification = new AttributeChangeNotification(bundle.getString("management-notification-attribute-changed",propertyName,managedType.getType().getCanonicalName()) - , propertyName - , attributeType - , oldValue - , newValue); + Class attributeType = newValue != null ? newValue.getClass() : null; + + AttributeChangeNotification notification = new AttributeChangeNotification(bundle.getString( + "management-notification-attribute-changed", propertyName, managedType.getType() + .getCanonicalName()), propertyName, attributeType, oldValue, newValue); notificationManager.sendNotification(notification); - } catch (DemoiselleException de){ + } catch (DemoiselleException de) { throw de; } catch (Exception e) { - throw new DemoiselleException(bundle.getString( - "management-invoke-error", method.getName()), e); + throw new DemoiselleException(bundle.getString("management-invoke-error", method.getName()), e); } finally { deactivateContexts(managedType.getType()); } } else { - throw new DemoiselleException(bundle.getString( - "management-invoke-error", propertyName)); + throw new DemoiselleException(bundle.getString("management-invoke-error", propertyName)); } } else { - throw new DemoiselleException( - bundle.getString("management-type-not-found")); + throw new DemoiselleException(bundle.getString("management-type-not-found")); } } private void activateContexts(Class managedType) { logger.debug(bundle.getString("management-debug-starting-custom-context", - ManagedContext.class.getCanonicalName(), - managedType.getCanonicalName())); - - ContextManager.activate(ManagedContext.class,RequestScoped.class); + ManagedContext.class.getCanonicalName(), managedType.getCanonicalName())); + + ContextManager.activate(ManagedContext.class, RequestScoped.class); } private void deactivateContexts(Class managedType) { logger.debug(bundle.getString("management-debug-stoping-custom-context", - ManagedContext.class.getCanonicalName(), - managedType.getCanonicalName())); - - ContextManager.deactivate(ManagedContext.class,RequestScoped.class); + ManagedContext.class.getCanonicalName(), managedType.getCanonicalName())); + + ContextManager.deactivate(ManagedContext.class, RequestScoped.class); } public void shutdown(Collection> monitoringExtensions) { @@ -324,8 +311,9 @@ public class Management { ManagementExtension monitoringExtension = Beans.getReference(monitoringExtensionClass); monitoringExtension.shutdown(this.getManagedTypes()); - - logger.debug( bundle.getString("management-debug-removing-management-extension",monitoringExtension.getClass().getCanonicalName()) ); + + logger.debug(bundle.getString("management-debug-removing-management-extension", monitoringExtension + .getClass().getCanonicalName())); } @@ -335,27 +323,26 @@ public class Management { for (Class monitoringExtensionClass : monitoringExtensions) { - ManagementExtension monitoringExtension = Beans - .getReference(monitoringExtensionClass); + ManagementExtension monitoringExtension = Beans.getReference(monitoringExtensionClass); monitoringExtension.initialize(this.getManagedTypes()); - - logger.debug( bundle.getString("management-debug-processing-management-extension",monitoringExtension.getClass().getCanonicalName()) ); + + logger.debug(bundle.getString("management-debug-processing-management-extension", monitoringExtension + .getClass().getCanonicalName())); } } - - private Validator getDefaultValidator(){ - if (validator == null){ - try{ + + private Validator getDefaultValidator() { + if (validator == null) { + try { this.validator = Validation.buildDefaultValidatorFactory().getValidator(); - } - catch(ValidationException e){ + } catch (ValidationException e) { this.validator = null; } } - + return this.validator; } diff --git a/impl/core/src/main/resources/demoiselle-core-bundle.properties b/impl/core/src/main/resources/demoiselle-core-bundle.properties index 8e604b9..6984a5f 100644 --- a/impl/core/src/main/resources/demoiselle-core-bundle.properties +++ b/impl/core/src/main/resources/demoiselle-core-bundle.properties @@ -53,7 +53,8 @@ transaction-commited=Transa\u00E7\u00E3o finalizada com sucesso transaction-rolledback=Transa\u00E7\u00E3o finalizada com rollback bootstrap.configuration.processing=Processando {0} -bootstrap-context-already-managed=O contexto {0} para o escopo {1} j\u00E1 \u00E9 gerenciado +bootstrap-context-already-managed=O contexto {0} para o escopo {1} j\u00E1 foi adicionado +bootstrap-context-added=Adicionando o contexto {0} para o escopo {1} loading-configuration-class=Carregando a classe de configura\u00E7\u00E3o {0} configuration-field-loaded=Configura\u00E7\u00E3o {0} atribu\u00EDda a {1} com o valor {2} @@ -69,6 +70,7 @@ custom-context-was-registered=O contexto {0} foi registrado custom-context-was-unregistered=O contexto {0} foi removido custom-context-was-activated=O contexto {0} foi ativado para o escopo {1} custom-context-was-deactivated=O contexto {0} foi desativado para o escopo {1} +custom-context-already-activated=N\u00E3o foi poss\u00EDvel ativar o contexto {0}, o escopo {1} j\u00E1 est\u00E1 ativo no contexto {2} custom-context-not-found=N\u00E3o foi encontrado um contexto gerenciado do tipo [{0}] para o escopo [{1}] custom-context-manager-not-initialized=ContextManager n\u00E3o foi inicializado. Chame [initialize] ao capturar o evento [AfterBeanDiscovery] em uma extens\u00E3o CDI diff --git a/impl/core/src/test/java/security/athentication/custom/CustomAuthenticatorTest.java b/impl/core/src/test/java/security/athentication/custom/CustomAuthenticatorTest.java index 320d1eb..c95437f 100644 --- a/impl/core/src/test/java/security/athentication/custom/CustomAuthenticatorTest.java +++ b/impl/core/src/test/java/security/athentication/custom/CustomAuthenticatorTest.java @@ -42,6 +42,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import org.jboss.arquillian.container.test.api.Deployment; @@ -51,6 +52,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import test.Tests; +import br.gov.frameworkdemoiselle.internal.context.ContextManager; +import br.gov.frameworkdemoiselle.internal.context.ThreadLocalContext; import br.gov.frameworkdemoiselle.security.SecurityContext; import configuration.resource.ConfigurationResourceTest; @@ -79,17 +82,25 @@ public class CustomAuthenticatorTest { @Test public void loginProcess() { + ContextManager.activate(ThreadLocalContext.class, RequestScoped.class); + context.login(); assertTrue(context.isLoggedIn()); assertNotNull(observer.getEvent()); assertEquals("demoiselle", context.getCurrentUser().getName()); + + ContextManager.deactivate(ThreadLocalContext.class, RequestScoped.class); } @Test public void logoutProcess() { + ContextManager.activate(ThreadLocalContext.class, RequestScoped.class); + context.login(); context.logout(); assertFalse(context.isLoggedIn()); assertNull(context.getCurrentUser()); + + ContextManager.deactivate(ThreadLocalContext.class, RequestScoped.class); } } -- libgit2 0.21.2