From 1d2356dd44536bc01eed1e8f029d4e26a8a5d496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Tue, 16 Mar 2010 13:04:35 +0100 Subject: [PATCH] ItEr51S04ValidacionEProbasFuncionaisItEr50S04: Intercepting OptimistLockingFailureException. Using an aspect to intercept when an OptimistLockingFailureException happens and redirect to special purpose page. --- .../ConcurrentModificationHandling.java | 71 +++++++++++++++++++ .../OnConcurrentModification.java | 43 +++++++++++ .../web/resources/worker/WorkerModel.java | 2 + .../navalplanner-webapp-spring-config.xml | 4 ++ 4 files changed, 120 insertions(+) create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/ConcurrentModificationHandling.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/OnConcurrentModification.java diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/ConcurrentModificationHandling.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/ConcurrentModificationHandling.java new file mode 100644 index 000000000..69174ccca --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/ConcurrentModificationHandling.java @@ -0,0 +1,71 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.concurrentdetection; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.core.annotation.Order; +import org.springframework.dao.OptimisticLockingFailureException; + +/** + * Responsible of handling {@link OptimisticLockingFailureException} on Spring + * beans marked with {@link OnConcurrentModification} + * @author Óscar González Fernández + */ +@Aspect +@Order(0) +public class ConcurrentModificationHandling { + + public ConcurrentModificationHandling() { + } + + @SuppressWarnings("unused") + @Pointcut("@within(onConcurrentModification))") + private void methodWithinConcurrentModificationMarkedType( + OnConcurrentModification onConcurrentModification) { + } + + /** + * It intercepts the calls to public methods of Spring beans marked with + * {@link OnConcurrentModification}. When an + * {@link OptimisticLockingFailureException} happens the page for concurrent + * modification is shown and the user is returned to the page specified by + * {@link OnConcurrentModification} + * @param jointPoint + * @param onConcurrentModification + * the annotation applied to object's type + * @return the object that would be originally returned + */ + @Around("methodWithinConcurrentModificationMarkedType(onConcurrentModification)" + + " && execution(public * * (..))") + public Object whenConcurrentModification(ProceedingJoinPoint jointPoint, + OnConcurrentModification onConcurrentModification) throws Throwable { + try { + return jointPoint.proceed(jointPoint.getArgs()); + } catch (OptimisticLockingFailureException e) { + ConcurrentModificationController.showException(e, + onConcurrentModification.goToPage()); + throw e; + } + } +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/OnConcurrentModification.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/OnConcurrentModification.java new file mode 100644 index 000000000..3093c03b3 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/OnConcurrentModification.java @@ -0,0 +1,43 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.navalplanner.web.common.concurrentdetection; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.dao.OptimisticLockingFailureException; + +/** + * This annotation must be applied on spring beans that want to inform the user + * that an {@link OptimisticLockingFailureException} has happened. After showing + * it, the user can go back to the page supplied on this annotation + * @author Óscar González Fernández + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OnConcurrentModification { + + public String goToPage(); + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java index 8ccb2293d..664c802bc 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java @@ -54,6 +54,7 @@ import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.VirtualWorker; import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.web.calendars.IBaseCalendarModel; +import org.navalplanner.web.common.concurrentdetection.OnConcurrentModification; import org.navalplanner.web.resources.search.ResourcePredicate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -69,6 +70,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) +@OnConcurrentModification(goToPage = "/resources/worker/worker.zul") public class WorkerModel implements IWorkerModel { @Autowired diff --git a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml index 28ee981cd..ad9656f0d 100644 --- a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml +++ b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml @@ -21,6 +21,10 @@ required for "@Autowired") --> + + + +