From 8d88d3da4e8147e77ada170acfc15ae2835f289b Mon Sep 17 00:00:00 2001 From: Manuel Rego Casasnovas Date: Tue, 11 Aug 2009 22:57:08 +0200 Subject: [PATCH] ItEr21S04ArquitecturaServidorItEr20S04: Removed use of CriterionService. --- .../bootstrap/CriterionsBootstrap.java | 18 +- .../business/resources/daos/CriterionDAO.java | 14 + .../resources/daos/ICriterionDAO.java | 3 + .../services/CriterionServiceImpl.java | 248 ---------- .../resources/services/ICriterionService.java | 59 --- .../bootstrap/CriterionsBootstrapTest.java | 37 +- .../test/resources/daos/CriterionDAOTest.java | 84 +++- .../services/CriterionServiceTest.java | 453 ------------------ .../services/ResourceServiceTest.java | 91 +++- .../navalplanner/web/orders/OrderModel.java | 7 +- .../resources/criterion/CriterionsModel.java | 78 ++- .../resources/criterion/ICriterionsModel.java | 2 + .../web/resources/worker/WorkerModel.java | 27 +- .../web/orders/OrderModelTest.java | 10 +- .../web/resources/CriterionModelTest.java | 323 +++++++++++++ .../web/resources/WorkerModelTest.java | 16 +- 16 files changed, 647 insertions(+), 823 deletions(-) delete mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionServiceImpl.java delete mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ICriterionService.java delete mode 100644 navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java create mode 100644 navalplanner-webapp/src/test/java/org/navalplanner/web/resources/CriterionModelTest.java diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java index 417a98f92..c354d6553 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java @@ -9,11 +9,10 @@ import java.util.Map.Entry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; -import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.daos.ICriterionTypeDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionType; -import org.navalplanner.business.resources.services.ICriterionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -32,7 +31,7 @@ public class CriterionsBootstrap implements ICriterionsBootstrap { private static final Log LOG = LogFactory.getLog(CriterionsBootstrap.class); @Autowired - private ICriterionService criterionService; + private ICriterionDAO criterionDAO; @Autowired private ICriterionTypeDAO criterionTypeDAO; @@ -61,11 +60,14 @@ public class CriterionsBootstrap implements ICriterionsBootstrap { private void ensureCriterionExists(String criterionName, CriterionType criterionType) { - try { - Criterion criterion = new Criterion(criterionName, criterionType); - criterionService.createIfNotExists(criterion); - } catch (ValidationException e) { - throw new RuntimeException(e); + Criterion criterion = new Criterion(criterionName, criterionType); + if (!(criterionDAO.exists(criterion.getId()) || criterionDAO + .existsByNameAndType(criterion))) { + if (!(criterionTypeDAO.exists(criterion.getType().getId()) || criterionTypeDAO + .existsByName(criterion.getType()))) { + criterionTypeDAO.save(criterion.getType()); + } + criterionDAO.save(criterion); } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java index 3d6f733fe..bd22096db 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java @@ -10,6 +10,7 @@ import org.hibernate.criterion.Restrictions; import org.navalplanner.business.common.daos.GenericDAOHibernate; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; @@ -76,4 +77,17 @@ public class CriterionDAO extends GenericDAOHibernate throw new RuntimeException(ex); } } + + @Override + public List findByType(ICriterionType type) { + List list = list(Criterion.class); + ArrayList result = new ArrayList(); + for (Criterion criterion : list) { + if (type.contains(criterion)) { + result.add(criterion); + } + } + return result; + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java index efebf11d5..633b129de 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java @@ -5,6 +5,7 @@ import java.util.List; import org.navalplanner.business.common.daos.IGenericDAO; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; /** * Contract for {@link CriterionDAO}
@@ -22,4 +23,6 @@ public interface ICriterionDAO extends IGenericDAO { Criterion find(Criterion criterion) throws InstanceNotFoundException; + List findByType(ICriterionType type); + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionServiceImpl.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionServiceImpl.java deleted file mode 100644 index ef4fb06dd..000000000 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionServiceImpl.java +++ /dev/null @@ -1,248 +0,0 @@ -package org.navalplanner.business.resources.services; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import org.apache.commons.lang.Validate; -import org.hibernate.validator.InvalidValue; -import org.navalplanner.business.common.exceptions.InstanceNotFoundException; -import org.navalplanner.business.common.exceptions.ValidationException; -import org.navalplanner.business.resources.daos.CriterionDAO; -import org.navalplanner.business.resources.daos.ICriterionDAO; -import org.navalplanner.business.resources.daos.ICriterionTypeDAO; -import org.navalplanner.business.resources.entities.Criterion; -import org.navalplanner.business.resources.entities.CriterionSatisfaction; -import org.navalplanner.business.resources.entities.CriterionType; -import org.navalplanner.business.resources.entities.ICriterion; -import org.navalplanner.business.resources.entities.ICriterionOnData; -import org.navalplanner.business.resources.entities.ICriterionType; -import org.navalplanner.business.resources.entities.Interval; -import org.navalplanner.business.resources.entities.Resource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Implementation of {@link ICriterionService} using {@link CriterionDAO}
- * @author Óscar González Fernández - * @author Fernando Bellas Permuy - * @author Diego Pino García - */ -@Service -@Scope(BeanDefinition.SCOPE_SINGLETON) -@Transactional -public class CriterionServiceImpl implements ICriterionService { - - @Autowired - private ICriterionDAO criterionDAO; - - @Autowired - private IResourceService resourceService; - - @Autowired - private ICriterionTypeDAO criterionTypeDAO; - - public boolean exists(Criterion criterion) { - return criterionDAO.exists(criterion.getId()) - || criterionDAO.existsByNameAndType(criterion); - } - - public Criterion find(Criterion criterion) throws InstanceNotFoundException { - return criterionDAO.find(criterion); - } - - public List list() { - return criterionDAO.list(Criterion.class); - } - - public void remove(Criterion criterion) throws InstanceNotFoundException { - if (criterion.getId() != null) { - criterionDAO.remove(criterion.getId()); - } else { - criterionDAO.removeByNameAndType(criterion); - } - } - - @Transactional(rollbackFor = ValidationException.class) - @Override - public void save(Criterion entity) throws ValidationException { - // Save criterion.type if it's new - CriterionType criterionType = entity.getType(); - if (criterionType.getId() == null) { - entity.setType(saveCriterionType(criterionType)); - } - if (threIsOtherWithSameNameAndType(entity)) { - InvalidValue[] invalidValues = { new InvalidValue(entity.getName() - + " already exists", Criterion.class, "name", entity - .getName(), entity) }; - throw new ValidationException(invalidValues, - "Couldn't save new criterion"); - } - criterionDAO.save(entity); - } - - private boolean threIsOtherWithSameNameAndType(Criterion toSave) { - List withSameNameAndType = criterionDAO - .findByNameAndType(toSave); - if (withSameNameAndType.isEmpty()) - return false; - if (withSameNameAndType.size() > 1) - return true; - return !areSameInDB(withSameNameAndType.get(0), toSave); - } - - private boolean areSameInDB(Criterion existentCriterion, Criterion other) { - return existentCriterion.getId().equals(other.getId()); - } - - private CriterionType saveCriterionType(CriterionType criterionType) - throws ValidationException { - if (criterionTypeDAO.exists(criterionType.getId()) - || criterionTypeDAO.existsByName(criterionType)) { - try { - criterionType = criterionTypeDAO.findUniqueByName(criterionType - .getName()); - } catch (InstanceNotFoundException e) { - throw new RuntimeException(e); - } - } else { - criterionTypeDAO.save(criterionType); - } - - return criterionType; - } - - @Override - public Collection getResourcesSatisfying(ICriterion criterion) { - List resources = resourceService.getResources(); - ArrayList result = new ArrayList(); - for (Resource resource : resources) { - if (criterion.isSatisfiedBy(resource)) { - result.add(resource); - } - } - return result; - } - - @Override - public Collection getResourcesSatisfying(ICriterion criterion, - Date start, Date end) { - Validate.isTrue(start.before(end), "start must be before than end"); - List resources = resourceService.getResources(); - ArrayList result = new ArrayList(); - for (Resource resource : resources) { - if (criterion.isSatisfiedBy(resource, start, end)) { - result.add(resource); - } - } - return result; - } - - @Override - public Collection getSatisfactionsFor( - ICriterionType criterionType) { - ArrayList result = new ArrayList(); - for (Resource resource : resourceService.getResources()) { - result.addAll(resource.getCurrentSatisfactionsFor(criterionType)); - } - return result; - } - - @Override - public Collection getSatisfactionsFor( - ICriterionType criterionType, Date start, Date end) { - ArrayList result = new ArrayList(); - for (Resource resource : resourceService.getResources()) { - result.addAll(resource.query().from(criterionType).enforcedInAll( - Interval.range(start, end)).result()); - } - return result; - } - - @Override - public void createIfNotExists(Criterion criterion) - throws ValidationException { - if (!exists(criterion)) - save(criterion); - } - - @Override - public ICriterionOnData empower(final ICriterion criterion) { - final ICriterionService criterionService = getProxifiedCriterionService(); - return new ICriterionOnData() { - @Override - public boolean isSatisfiedBy(Resource resource) { - return criterion.isSatisfiedBy(resource); - } - - @Override - public boolean isSatisfiedBy(Resource resource, Date start, Date end) { - return criterion.isSatisfiedBy(resource, start, end); - } - - @Override - public Collection getResourcesSatisfying() { - return criterionService.getResourcesSatisfying(criterion); - } - - @Override - public Collection getResourcesSatisfying(Date start, - Date end) throws IllegalArgumentException { - return criterionService.getResourcesSatisfying(criterion, - start, end); - } - }; - } - - @Autowired - private ApplicationContext applicationContext; - - // this is a hack to avoid using the this variable in empower method. The - // this instance is not proxified because spring uses an transparent proxy, - // so it doesn't open the transacion - private ICriterionService getProxifiedCriterionService() { - return (ICriterionService) applicationContext.getBeansOfType( - ICriterionService.class).values().iterator().next(); - } - - @Override - public Collection getCriterionsFor(ICriterionType type) { - List list = criterionDAO.list(Criterion.class); - ArrayList result = new ArrayList(); - for (Criterion criterion : list) { - if (type.contains(criterion)) { - result.add(criterion); - } - } - return result; - } - - @Override - public List getResourcesSatisfying( - Class resourceType, Criterion criterion) { - Validate.notNull(resourceType, "resourceType must be not null"); - Validate.notNull(criterion, "criterion must be not null"); - List result = new ArrayList(); - for (T r : resourceService.getResources(resourceType)) { - if (criterion.isSatisfiedBy(r)) { - result.add(r); - } - } - return result; - } - - @Override - public Criterion load(Criterion criterion) { - try { - return criterionDAO.find(criterion); - } catch (InstanceNotFoundException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ICriterionService.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ICriterionService.java deleted file mode 100644 index ab6ee405a..000000000 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ICriterionService.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.navalplanner.business.resources.services; - -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import org.navalplanner.business.common.exceptions.InstanceNotFoundException; -import org.navalplanner.business.common.exceptions.ValidationException; -import org.navalplanner.business.resources.entities.Criterion; -import org.navalplanner.business.resources.entities.CriterionSatisfaction; -import org.navalplanner.business.resources.entities.ICriterion; -import org.navalplanner.business.resources.entities.ICriterionOnData; -import org.navalplanner.business.resources.entities.ICriterionType; -import org.navalplanner.business.resources.entities.Resource; - -/** - * Services for {@link Criterion}
- * @author Óscar González Fernández - */ -public interface ICriterionService { - - List list(); - - void remove(Criterion criterion) throws InstanceNotFoundException; - - /** - * Save or update criterion - * - * "name" and "type" fields must be both unique - * - * @param entity - */ - void save(Criterion entity) throws ValidationException; - - Collection getResourcesSatisfying(ICriterion criterion); - - Collection getResourcesSatisfying(ICriterion criterion, - Date begin, Date end); - - Collection getSatisfactionsFor( - ICriterionType criterionType); - - Collection getSatisfactionsFor( - ICriterionType criterionType, Date begin, Date end); - - void createIfNotExists(Criterion criterion) throws ValidationException; - - boolean exists(Criterion criterion); - - ICriterionOnData empower(ICriterion criterion); - - Collection getCriterionsFor(ICriterionType type); - - List getResourcesSatisfying(Class resourceType, - Criterion criterion); - - Criterion load(Criterion criterion); - -} diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/bootstrap/CriterionsBootstrapTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/bootstrap/CriterionsBootstrapTest.java index 77ce938f0..0df748f5b 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/bootstrap/CriterionsBootstrapTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/bootstrap/CriterionsBootstrapTest.java @@ -7,8 +7,9 @@ import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING import org.junit.Test; import org.junit.runner.RunWith; import org.navalplanner.business.resources.bootstrap.ICriterionsBootstrap; +import org.navalplanner.business.resources.daos.ICriterionDAO; +import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.WorkingRelationship; -import org.navalplanner.business.resources.services.ICriterionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -24,21 +25,37 @@ public class CriterionsBootstrapTest { private ICriterionsBootstrap criterionsBootstrap; @Autowired - private ICriterionService criterionService; + private ICriterionDAO criterionDAO; @Test public void testBootstrap() throws Exception { - if (criterionService.exists(WorkingRelationship.FIRED.criterion())) { - criterionService.remove(WorkingRelationship.FIRED.criterion()); + Criterion criterion = WorkingRelationship.FIRED.criterion(); + if (criterionDAO.exists(criterion.getId()) + || criterionDAO.existsByNameAndType(criterion)) { + if (criterion.getId() != null) { + criterionDAO.remove(criterion.getId()); + } else { + criterionDAO.removeByNameAndType(criterion); + } } - if (criterionService.exists(WorkingRelationship.HIRED.criterion())) { - criterionService.remove(WorkingRelationship.HIRED.criterion()); + + criterion = WorkingRelationship.HIRED.criterion(); + if (criterionDAO.exists(criterion.getId()) + || criterionDAO.existsByNameAndType(criterion)) { + if (criterion.getId() != null) { + criterionDAO.remove(criterion.getId()); + } else { + criterionDAO.removeByNameAndType(criterion); + } } + criterionsBootstrap.loadRequiredData(); - assertTrue(criterionService.exists(WorkingRelationship.FIRED - .criterion())); - assertTrue(criterionService.exists(WorkingRelationship.HIRED - .criterion())); + criterion = WorkingRelationship.FIRED.criterion(); + assertTrue(criterionDAO.exists(criterion.getId()) + || criterionDAO.existsByNameAndType(criterion)); + criterion = WorkingRelationship.HIRED.criterion(); + assertTrue(criterionDAO.exists(criterion.getId()) + || criterionDAO.existsByNameAndType(criterion)); } } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionDAOTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionDAOTest.java index be45cd49f..c8f18e059 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionDAOTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionDAOTest.java @@ -7,6 +7,7 @@ import static junit.framework.Assert.assertTrue; import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; +import java.util.Collection; import java.util.List; import java.util.UUID; @@ -18,10 +19,12 @@ import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.daos.ICriterionTypeDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionType; +import org.navalplanner.business.resources.entities.ICriterion; +import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.entities.PredefinedCriterionTypes; +import org.navalplanner.business.resources.entities.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.test.annotation.NotTransactional; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; @@ -116,4 +119,83 @@ public class CriterionDAOTest { criterionDAO.save(criterion2); criterionDAO.flush(); } + + @Test + public void testCriterionsForType() throws Exception { + final Criterion one = CriterionDAOTest.createValidCriterion(); + Criterion other = CriterionDAOTest.createValidCriterion(); + save(one); + save(other); + ICriterionType type = createTypeThatMatches(one); + Collection criterions = criterionDAO.findByType(type); + assertEquals(1, criterions.size()); + assertTrue(criterions.contains(one)); + } + + private void save(Criterion criterion) { + if (!(criterionTypeDAO.exists(criterion.getType().getId()) || criterionTypeDAO + .existsByName(criterion.getType()))) { + criterionTypeDAO.save(criterion.getType()); + } + criterionDAO.save(criterion); + } + + public static ICriterionType createTypeThatMatches( + final Criterion criterion) { + return createTypeThatMatches(false, criterion); + } + + public static ICriterionType createTypeThatMatches( + final boolean allowSimultaneousCriterionsPerResource, + final Criterion criterion) { + return new ICriterionType() { + + @Override + public boolean allowSimultaneousCriterionsPerResource() { + return allowSimultaneousCriterionsPerResource; + } + + @Override + public boolean allowHierarchy() { + return false; + } + + @Override + public boolean contains(ICriterion c) { + return criterion.isEquivalent(c); + } + + @Override + public Criterion createCriterion(String name) { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public boolean allowAdding() { + return false; + } + + @Override + public boolean allowEditing() { + return false; + } + + @Override + public boolean criterionCanBeRelatedTo( + Class klass) { + return true; + } + + @Override + public Criterion createCriterionWithoutNameYet() { + return null; + } + }; + } + } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java deleted file mode 100644 index e50822e72..000000000 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java +++ /dev/null @@ -1,453 +0,0 @@ -package org.navalplanner.business.test.resources.services; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; -import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; - -import java.util.Collection; -import java.util.UUID; - -import org.hibernate.SessionFactory; -import org.hibernate.validator.InvalidStateException; -import org.junit.Assume; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.navalplanner.business.common.IAdHocTransactionService; -import org.navalplanner.business.common.IOnTransaction; -import org.navalplanner.business.common.exceptions.InstanceNotFoundException; -import org.navalplanner.business.common.exceptions.ValidationException; -import org.navalplanner.business.resources.entities.Criterion; -import org.navalplanner.business.resources.entities.CriterionSatisfaction; -import org.navalplanner.business.resources.entities.CriterionWithItsType; -import org.navalplanner.business.resources.entities.ICriterion; -import org.navalplanner.business.resources.entities.ICriterionOnData; -import org.navalplanner.business.resources.entities.ICriterionType; -import org.navalplanner.business.resources.entities.Interval; -import org.navalplanner.business.resources.entities.PredefinedCriterionTypes; -import org.navalplanner.business.resources.entities.Resource; -import org.navalplanner.business.resources.entities.Worker; -import org.navalplanner.business.resources.services.ICriterionService; -import org.navalplanner.business.resources.services.IResourceService; -import org.navalplanner.business.test.resources.daos.CriterionDAOTest; -import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest; -import org.navalplanner.business.test.resources.entities.ResourceTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.test.annotation.NotTransactional; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.transaction.annotation.Transactional; - -/** - * Test cases for {@link ICriterionService}
- * @author Óscar González Fernández - * @author Diego Pino García - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, - BUSINESS_SPRING_CONFIG_TEST_FILE }) -@Transactional -public class CriterionServiceTest { - - @Autowired - private ICriterionService criterionService; - - @Autowired - IAdHocTransactionService adHocTransactionService; - - @Autowired - private IResourceService resourceService; - - @Autowired - private SessionFactory sessionFactory; - - @Test(expected = InvalidStateException.class) - public void testCantSaveCriterionWithoutNameAndType() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion("valido"); - criterion.setName(""); - criterionService.save(criterion); - sessionFactory.getCurrentSession().flush(); - } - - @Test - public void testAddCriterion() throws Exception { - String unique = UUID.randomUUID().toString(); - Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique); - criterionService.save(criterion); - } - - @Test - @NotTransactional - public void testEditingCriterion() throws Exception { - String unique = UUID.randomUUID().toString(); - Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique); - int initial = criterionService.getCriterionsFor( - PredefinedCriterionTypes.WORK_RELATIONSHIP).size(); - criterionService.save(criterion); - assertThat("after saving one more", criterionService.getCriterionsFor( - PredefinedCriterionTypes.WORK_RELATIONSHIP).size(), - equalTo(initial + 1)); - criterion.setActive(false); - String newName = UUID.randomUUID().toString() + "random"; - criterion.setName(newName); - criterionService.save(criterion); - assertThat("after editing there are the same", criterionService - .getCriterionsFor(PredefinedCriterionTypes.WORK_RELATIONSHIP) - .size(), equalTo(initial + 1)); - Criterion retrieved = criterionService.load(criterion); - assertThat(retrieved.getName(), equalTo(newName)); - criterionService.remove(criterion); - } - - @Test - public void testSaveSameCriterionTwice() throws ValidationException { - String unique = UUID.randomUUID().toString(); - Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique); - criterionService.save(criterion); - criterionService.save(criterion); - } - - @Test - public void testCreateIfNotExists() throws ValidationException { - String unique = UUID.randomUUID().toString(); - Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique); - criterionService.createIfNotExists(criterion); - assertTrue(criterionService.exists(criterion)); - criterionService - .createIfNotExists(PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique)); - } - - @Test(expected = ValidationException.class) - @NotTransactional - public void twoDifferentCriterionsWithSameNameAndTypeAreDetectedIfPossible() - throws ValidationException { - String unique = UUID.randomUUID().toString(); - Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique); - criterionService.save(criterion); - Criterion criterion2 = PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique); - criterionService.save(criterion2); - } - - @Test(expected = DataIntegrityViolationException.class) - public void testCreateCriterionSatisfactionOnTransientCriterion() - throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - ICriterionType type = createTypeThatMatches(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - worker.addSatisfaction(new CriterionWithItsType(type, criterion)); - assertTrue(criterion.isSatisfiedBy(worker)); - resourceService.saveResource(worker); - assertTrue(criterion.isSatisfiedBy(worker)); - assertThat(criterionService.getResourcesSatisfying(criterion).size(), - equalTo(1)); - } - - @NotTransactional - @Test - public void testInNoTransaction() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - ICriterionType type = createTypeThatMatches(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - worker.addSatisfaction(new CriterionWithItsType(type, criterion)); - assertTrue(criterion.isSatisfiedBy(worker)); - resourceService.saveResource(worker); - assertTrue(criterion.isSatisfiedBy(worker)); - assertThat(criterionService.getResourcesSatisfying(criterion).size(), - equalTo(1)); - } - - public void testCreateCriterionSatisfactionOnTransientResource() - throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - ICriterionType type = createTypeThatMatches(criterion); - criterionService.save(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - worker.addSatisfaction(new CriterionWithItsType(type, criterion)); - resourceService.saveResource(worker); - assertThat(criterionService.getResourcesSatisfying(criterion).size(), - equalTo(1)); - assertThat((Worker) criterionService.getResourcesSatisfying(criterion) - .iterator().next(), equalTo(worker)); - } - - @Test - public void testGetSetOfResourcesSatisfyingCriterion() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - ICriterionType type = createTypeThatMatches(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - resourceService.saveResource(worker); - worker.addSatisfaction(new CriterionWithItsType(type, criterion)); - assertEquals(1, criterionService.getResourcesSatisfying(criterion) - .size()); - } - - public static class Prueba extends Resource { - - @Override - public int getDailyCapacity() { - return 0; - } - - @Override - public String getDescription() { - return ""; - } - - } - - @Test - public void testGetSetOfResourcesSubclassSatisfyingCriterion() - throws ValidationException { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - ICriterionType type = createTypeThatMatches(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - resourceService.saveResource(worker); - worker.addSatisfaction(new CriterionWithItsType(type, criterion)); - - assertThat(criterionService.getResourcesSatisfying(Resource.class, - criterion).size(), is(1)); - assertThat(criterionService.getResourcesSatisfying(Worker.class, - criterion).size(), is(1)); - assertThat(criterionService.getResourcesSatisfying(Prueba.class, - criterion).size(), is(0)); - } - - @Test - public void shouldLetCreateCriterionOnData() throws ValidationException { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - ICriterionType type = createTypeThatMatches(criterion); - criterionService.save(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - resourceService.saveResource(worker); - worker.addSatisfaction(new CriterionWithItsType(type, criterion), - Interval.from(CriterionSatisfactionDAOTest.year(2000))); - ICriterionOnData criterionOnData = criterionService.empower(criterion); - assertTrue(criterionOnData.isSatisfiedBy(worker)); - assertEquals(1, criterionOnData.getResourcesSatisfying().size()); - assertTrue(criterionOnData.getResourcesSatisfying().contains(worker)); - assertTrue(criterionOnData.getResourcesSatisfying( - CriterionSatisfactionDAOTest.year(1990), - CriterionSatisfactionDAOTest.year(2005)).isEmpty()); - assertEquals(1, criterionOnData.getResourcesSatisfying( - CriterionSatisfactionDAOTest.year(2001), - CriterionSatisfactionDAOTest.year(2005)).size()); - } - - @Test - @NotTransactional - public void testCriterionIsEquivalentOnDetachedAndProxifiedCriterion() - throws Exception { - final Worker worker1 = new Worker("worker-1", "worker-2-surname", - "11111111A", 8); - resourceService.saveResource(worker1); - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - createTypeThatMatches(criterion); - worker1.addSatisfaction(new CriterionWithItsType(criterion.getType(), - criterion)); - resourceService.saveResource(worker1); - Resource workerReloaded = adHocTransactionService - .onTransaction(new IOnTransaction() { - - @Override - public Resource execute() { - try { - Resource result = resourceService - .findResource(worker1.getId()); - forceLoadSatisfactions(result); - return result; - } catch (InstanceNotFoundException e) { - throw new RuntimeException(e); - } - } - }); - Collection satisfactionsFor = workerReloaded - .getSatisfactionsFor(criterion.getType()); - Criterion reloadedCriterion = satisfactionsFor.iterator().next() - .getCriterion(); - Assume.assumeTrue(!reloadedCriterion.getClass().equals( - criterion.getClass())); - assertTrue(reloadedCriterion.isEquivalent(criterion)); - } - - private void forceLoadSatisfactions(Resource resource) { - for (CriterionSatisfaction criterionSatisfaction : resource - .getAllSatisfactions()) { - criterionSatisfaction.getCriterion().getName(); - criterionSatisfaction.getCriterion().getType().getName(); - } - } - - @Test - @NotTransactional - public void shouldntThrowExceptionDueToTransparentProxyGotcha() - throws ValidationException { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - ICriterionType type = createTypeThatMatches(criterion); - criterionService.save(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - resourceService.saveResource(worker); - worker.addSatisfaction(new CriterionWithItsType(type, criterion), - Interval.from(CriterionSatisfactionDAOTest.year(2000))); - ICriterionOnData criterionOnData = criterionService.empower(criterion); - criterionOnData.getResourcesSatisfying(); - criterionOnData.getResourcesSatisfying(CriterionSatisfactionDAOTest - .year(2001), CriterionSatisfactionDAOTest.year(2005)); - } - - @Test(expected = IllegalArgumentException.class) - public void mustBeCorrectInterval() throws ValidationException { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - criterionService.getResourcesSatisfying(criterion, - CriterionSatisfactionDAOTest.year(2005), - CriterionSatisfactionDAOTest.year(2003)); - } - - @Test - public void testSearchInInterval() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - ICriterionType type = createTypeThatMatches(true, criterion); - CriterionWithItsType criterionWithItsType = new CriterionWithItsType( - type, criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - resourceService.saveResource(worker); - worker.addSatisfaction(criterionWithItsType, Interval - .from(CriterionSatisfactionDAOTest.year(2000))); - - assertEquals(1, criterionService.getResourcesSatisfying(criterion, - CriterionSatisfactionDAOTest.year(2001), - CriterionSatisfactionDAOTest.year(2005)).size()); - assertEquals(0, criterionService.getResourcesSatisfying(criterion, - CriterionSatisfactionDAOTest.year(1999), - CriterionSatisfactionDAOTest.year(2005)).size()); - - worker.addSatisfaction(new CriterionWithItsType(type, criterion), - Interval.from(CriterionSatisfactionDAOTest.year(1998))); - - assertEquals(1, criterionService.getResourcesSatisfying(criterion, - CriterionSatisfactionDAOTest.year(1999), - CriterionSatisfactionDAOTest.year(2005)).size()); - } - - @Test - public void testSearchResourcesForCriterionType() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - ICriterionType type = createTypeThatMatches(true, criterion); - CriterionWithItsType criterionWithItsType = new CriterionWithItsType( - type, criterion); - criterionService.save(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - resourceService.saveResource(worker); - worker.addSatisfaction(criterionWithItsType, Interval - .from(CriterionSatisfactionDAOTest.year(2000))); - worker.addSatisfaction(criterionWithItsType, Interval - .from(CriterionSatisfactionDAOTest.year(1998))); - - ICriterionType criterionType = ResourceTest - .createTypeThatMatches(criterion); - - assertEquals(2, criterionService.getSatisfactionsFor(criterionType, - CriterionSatisfactionDAOTest.year(2001), - CriterionSatisfactionDAOTest.year(2005)).size()); - assertEquals(1, criterionService.getSatisfactionsFor(criterionType, - CriterionSatisfactionDAOTest.year(1999), - CriterionSatisfactionDAOTest.year(2005)).size()); - assertEquals(0, criterionService.getSatisfactionsFor(criterionType, - CriterionSatisfactionDAOTest.year(1997), - CriterionSatisfactionDAOTest.year(2005)).size()); - - worker.addSatisfaction(criterionWithItsType, Interval - .from(CriterionSatisfactionDAOTest.year(1997))); - assertEquals(2, criterionService.getSatisfactionsFor(criterionType, - CriterionSatisfactionDAOTest.year(1999), - CriterionSatisfactionDAOTest.year(2005)).size()); - } - - @Test - public void testCriterionsForType() throws Exception { - final Criterion one = CriterionDAOTest.createValidCriterion(); - Criterion other = CriterionDAOTest.createValidCriterion(); - criterionService.save(one); - criterionService.save(other); - ICriterionType type = createTypeThatMatches(one); - Collection criterions = criterionService - .getCriterionsFor(type); - assertEquals(1, criterions.size()); - assertTrue(criterions.contains(one)); - } - - public static ICriterionType createTypeThatMatches( - final Criterion criterion) { - return createTypeThatMatches(false, criterion); - } - - public static ICriterionType createTypeThatMatches( - final boolean allowSimultaneousCriterionsPerResource, - final Criterion criterion) { - return new ICriterionType() { - - @Override - public boolean allowSimultaneousCriterionsPerResource() { - return allowSimultaneousCriterionsPerResource; - } - - @Override - public boolean allowHierarchy() { - return false; - } - - @Override - public boolean contains(ICriterion c) { - return criterion.isEquivalent(c); - } - - @Override - public Criterion createCriterion(String name) { - return null; - } - - @Override - public String getName() { - return null; - } - - @Override - public boolean allowAdding() { - return false; - } - - @Override - public boolean allowEditing() { - return false; - } - - @Override - public boolean criterionCanBeRelatedTo( - Class klass) { - return true; - } - - @Override - public Criterion createCriterionWithoutNameYet() { - return null; - } - }; - } - -} diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/ResourceServiceTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/ResourceServiceTest.java index be79a3fd2..44ac4a3f1 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/ResourceServiceTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/ResourceServiceTest.java @@ -15,7 +15,11 @@ import org.hibernate.validator.InvalidStateException; import org.hibernate.validator.InvalidValue; import org.junit.Test; import org.junit.runner.RunWith; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.IOnTransaction; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.resources.daos.ICriterionDAO; +import org.navalplanner.business.resources.daos.ICriterionTypeDAO; import org.navalplanner.business.resources.daos.IResourceDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionWithItsType; @@ -23,7 +27,6 @@ import org.navalplanner.business.resources.entities.ICriterion; import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; -import org.navalplanner.business.resources.services.ICriterionService; import org.navalplanner.business.resources.services.IResourceService; import org.navalplanner.business.test.resources.daos.CriterionDAOTest; import org.navalplanner.business.test.resources.entities.CriterionTest; @@ -51,7 +54,13 @@ public class ResourceServiceTest { private IResourceDAO resourceDao; @Autowired - private ICriterionService criterionService; + private ICriterionDAO criterionDAO; + + @Autowired + private ICriterionTypeDAO criterionTypeDAO; + + @Autowired + private IAdHocTransactionService adHocTransactionService; @Test public void testRemoveResource() throws InstanceNotFoundException { @@ -134,15 +143,85 @@ public class ResourceServiceTest { "11111111A", 8); resourceService.saveResource(worker1); long versionValueAfterSave = worker1.getVersion(); - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - ICriterionType type = CriterionServiceTest - .createTypeThatMatches(criterion); + final Criterion criterion = CriterionDAOTest.createValidCriterion(); + + adHocTransactionService.onTransaction(new IOnTransaction() { + + @Override + public Void execute() { + if (!(criterionTypeDAO.exists(criterion.getType().getId()) || criterionTypeDAO + .existsByName(criterion.getType()))) { + criterionTypeDAO.save(criterion.getType()); + } + criterionDAO.save(criterion); + return null; + } + }); + + ICriterionType type = createTypeThatMatches(criterion); worker1.addSatisfaction(new CriterionWithItsType(type, criterion)); resourceService.saveResource(worker1); assertThat(worker1.getVersion(), not(equalTo(versionValueAfterSave))); } + private static ICriterionType createTypeThatMatches( + final Criterion criterion) { + return createTypeThatMatches(false, criterion); + } + + private static ICriterionType createTypeThatMatches( + final boolean allowSimultaneousCriterionsPerResource, + final Criterion criterion) { + return new ICriterionType() { + + @Override + public boolean allowSimultaneousCriterionsPerResource() { + return allowSimultaneousCriterionsPerResource; + } + + @Override + public boolean allowHierarchy() { + return false; + } + + @Override + public boolean contains(ICriterion c) { + return criterion.isEquivalent(c); + } + + @Override + public Criterion createCriterion(String name) { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public boolean allowAdding() { + return false; + } + + @Override + public boolean allowEditing() { + return false; + } + + @Override + public boolean criterionCanBeRelatedTo( + Class klass) { + return true; + } + + @Override + public Criterion createCriterionWithoutNameYet() { + return null; + } + }; + } + public void testResourcesSatisfying() { Worker worker1 = new Worker("worker-1", "worker-2-surname", "11111111A", 8); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java index 09512263b..1014c328a 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java @@ -26,7 +26,6 @@ import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.daos.ICriterionTypeDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionType; -import org.navalplanner.business.resources.services.ICriterionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; @@ -43,9 +42,6 @@ import org.springframework.transaction.annotation.Transactional; @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class OrderModel implements IOrderModel { - @Autowired - ICriterionService criterionService; - @Autowired ICriterionTypeDAO criterionTypeDAO; @@ -82,7 +78,8 @@ public class OrderModel implements IOrderModel { .getCriterionTypes(); for (CriterionType criterionType : criterionTypes) { List criterions = new ArrayList( - criterionService.getCriterionsFor(criterionType)); + criterionDAO + .findByType(criterionType)); mapCriterions.put(criterionType, criterions); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java index 5a1dc16b3..d4818e235 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java @@ -11,6 +11,7 @@ import org.hibernate.validator.ClassValidator; import org.hibernate.validator.InvalidValue; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.daos.ICriterionTypeDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionType; @@ -18,7 +19,6 @@ import org.navalplanner.business.resources.entities.CriterionWithItsType; import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; -import org.navalplanner.business.resources.services.ICriterionService; import org.navalplanner.business.resources.services.IResourceService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; @@ -40,10 +40,10 @@ public class CriterionsModel implements ICriterionsModel { Criterion.class); @Autowired - private ICriterionService criterionService; + private ICriterionDAO criterionDAO; @Autowired - private ICriterionTypeDAO criterionDAO; + private ICriterionTypeDAO criterionTypeDAO; @Autowired private IResourceService resourceService; @@ -55,13 +55,13 @@ public class CriterionsModel implements ICriterionsModel { @Override @Transactional(readOnly = true) public List getTypes() { - return criterionDAO.getCriterionTypes(); + return criterionTypeDAO.getCriterionTypes(); } @Override @Transactional(readOnly = true) public Collection getCriterionsFor(ICriterionType type) { - return criterionService.getCriterionsFor(type); + return criterionDAO.findByType(type); } @Override @@ -95,6 +95,7 @@ public class CriterionsModel implements ICriterionsModel { } @Override + @Transactional public void saveCriterion() throws ValidationException { InvalidValue[] invalidValues = criterionValidator .getInvalidValues(criterion); @@ -102,7 +103,7 @@ public class CriterionsModel implements ICriterionsModel { throw new ValidationException(invalidValues); try { - criterionService.save(criterion); + save(criterion); } catch (ValidationException ve) { throw ve; } finally { @@ -111,6 +112,55 @@ public class CriterionsModel implements ICriterionsModel { } } + @Override + @Transactional + public void save(Criterion entity) throws ValidationException { + // Save criterion.type if it's new + CriterionType criterionType = entity.getType(); + if (criterionType.getId() == null) { + entity.setType(saveCriterionType(criterionType)); + } + if (threIsOtherWithSameNameAndType(entity)) { + InvalidValue[] invalidValues = { new InvalidValue(entity.getName() + + " already exists", Criterion.class, "name", entity + .getName(), entity) }; + throw new ValidationException(invalidValues, + "Couldn't save new criterion"); + } + criterionDAO.save(entity); + } + + private boolean threIsOtherWithSameNameAndType(Criterion toSave) { + List withSameNameAndType = criterionDAO + .findByNameAndType(toSave); + if (withSameNameAndType.isEmpty()) + return false; + if (withSameNameAndType.size() > 1) + return true; + return !areSameInDB(withSameNameAndType.get(0), toSave); + } + + private boolean areSameInDB(Criterion existentCriterion, Criterion other) { + return existentCriterion.getId().equals(other.getId()); + } + + private CriterionType saveCriterionType(CriterionType criterionType) + throws ValidationException { + if (criterionTypeDAO.exists(criterionType.getId()) + || criterionTypeDAO.existsByName(criterionType)) { + try { + criterionType = criterionTypeDAO.findUniqueByName(criterionType + .getName()); + } catch (InstanceNotFoundException e) { + throw new RuntimeException(e); + } + } else { + criterionTypeDAO.save(criterionType); + } + + return criterionType; + } + @Override public boolean isEditing() { return criterion != null; @@ -124,11 +174,25 @@ public class CriterionsModel implements ICriterionsModel { } @Override + @Transactional(readOnly = true) public List getResourcesSatisfyingCurrentCriterionOfType( Class klass) { if (criterion == null) return new ArrayList(); - return criterionService.getResourcesSatisfying(klass, criterion); + return getResourcesSatisfying(klass, criterion); + } + + private List getResourcesSatisfying( + Class resourceType, Criterion criterion) { + Validate.notNull(resourceType, "resourceType must be not null"); + Validate.notNull(criterion, "criterion must be not null"); + List result = new ArrayList(); + for (T r : resourceService.getResources(resourceType)) { + if (criterion.isSatisfiedBy(r)) { + result.add(r); + } + } + return result; } @Override diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java index 1d6c6dc08..a0d494410 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java @@ -45,4 +45,6 @@ public interface ICriterionsModel { void deactivateAll(Collection unSelectedWorkers); + void save(Criterion criterion) throws ValidationException; + } 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 da2a2e89d..d08408512 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 @@ -15,6 +15,7 @@ import org.hibernate.validator.ClassValidator; import org.hibernate.validator.InvalidValue; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionSatisfaction; import org.navalplanner.business.resources.entities.CriterionWithItsType; @@ -23,7 +24,6 @@ import org.navalplanner.business.resources.entities.Interval; import org.navalplanner.business.resources.entities.PredefinedCriterionTypes; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; -import org.navalplanner.business.resources.services.ICriterionService; import org.navalplanner.business.resources.services.IResourceService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; @@ -46,18 +46,18 @@ public class WorkerModel implements IWorkerModel { PredefinedCriterionTypes.WORK_RELATIONSHIP }; private Worker worker; private ClassValidator workerValidator; - private final ICriterionService criterionService; + private final ICriterionDAO criterionDAO; private IMultipleCriterionActiveAssigner localizationsAssigner; @Autowired public WorkerModel(IResourceService resourceService, - ICriterionService criterionService) { + ICriterionDAO criterionDAO) { Validate.notNull(resourceService); - Validate.notNull(criterionService); + Validate.notNull(criterionDAO); this.resourceService = resourceService; this.workerValidator = new ClassValidator(Worker.class); - this.criterionService = criterionService; + this.criterionDAO = criterionDAO; } @Override @@ -90,7 +90,7 @@ public class WorkerModel implements IWorkerModel { public void prepareForCreate() { worker = new Worker(); localizationsAssigner = new MultipleCriterionActiveAssigner( - criterionService, worker, + criterionDAO, worker, PredefinedCriterionTypes.LOCATION_GROUP); } @@ -102,7 +102,7 @@ public class WorkerModel implements IWorkerModel { this.worker = (Worker) resourceService.findResource(worker.getId()); forceLoadSatisfactions(this.worker); localizationsAssigner = new MultipleCriterionActiveAssigner( - criterionService, this.worker, + criterionDAO, this.worker, PredefinedCriterionTypes.LOCATION_GROUP); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); @@ -232,7 +232,7 @@ public class WorkerModel implements IWorkerModel { IMultipleCriterionActiveAssigner { private final Resource resource; private final ICriterionType type; - private final ICriterionService criterionService; + private final ICriterionDAO criterionDAO; private List history; private List initialCriterionsNotAssigned; private Set initialActive; @@ -242,13 +242,14 @@ public class WorkerModel implements IWorkerModel { private Set added = new HashSet(); public MultipleCriterionActiveAssigner( - ICriterionService criterionService, Resource resource, + ICriterionDAO criterionDAO, + Resource resource, ICriterionType type) { Validate .isTrue( type.allowSimultaneousCriterionsPerResource(), "must allow multiple active criterions for this type to use this assignment strategy"); - this.criterionService = criterionService; + this.criterionDAO = criterionDAO; this.resource = resource; this.type = type; forceLoadSatisfactions(this.resource); @@ -282,8 +283,8 @@ public class WorkerModel implements IWorkerModel { } private List calculateInitialCriterionsNotAssigned() { - Map allCriterions = byId(criterionService - .getCriterionsFor(type)); + Map allCriterions = byId(criterionDAO + .findByType(type)); for (Long activeId : asIds(resource.getCurrentCriterionsFor(type))) { allCriterions.remove(activeId); } @@ -374,7 +375,7 @@ public class WorkerModel implements IWorkerModel { public Map, Collection> getLaboralRelatedCriterions() { Map, Collection> result = new HashMap, Collection>(); for (ICriterionType type : laboralRelatedTypes) { - result.put(type, criterionService.getCriterionsFor(type)); + result.put(type, criterionDAO.findByType(type)); } return result; } diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/orders/OrderModelTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/orders/OrderModelTest.java index 882edc810..89ae60f66 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/orders/OrderModelTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/orders/OrderModelTest.java @@ -37,7 +37,7 @@ import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.business.planner.entities.TaskGroup; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionType; -import org.navalplanner.business.resources.services.ICriterionService; +import org.navalplanner.web.resources.criterion.ICriterionsModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.NotTransactional; import org.springframework.test.context.ContextConfiguration; @@ -77,9 +77,6 @@ public class OrderModelTest { @Autowired private IOrderModel orderModel; - @Autowired - private ICriterionService criterionService; - @Autowired private IOrderDAO orderDAO; @@ -89,6 +86,9 @@ public class OrderModelTest { @Autowired private IAdHocTransactionService adHocTransaction; + @Autowired + private ICriterionsModel criterionModel; + private Session getSession() { return sessionFactory.getCurrentSession(); } @@ -304,7 +304,7 @@ public class OrderModelTest { CriterionType criterionType = new CriterionType("test"); Criterion criterion = new Criterion("Test" + UUID.randomUUID(), criterionType); - criterionService.save(criterion); + criterionModel.save(criterion); hoursGroup.addCriterion(criterion); hoursGroup2.addCriterion(criterion); diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/CriterionModelTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/CriterionModelTest.java new file mode 100644 index 000000000..e1da9a315 --- /dev/null +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/CriterionModelTest.java @@ -0,0 +1,323 @@ +package org.navalplanner.web.resources; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; +import static org.navalplanner.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE; +import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE; + +import java.util.Collection; +import java.util.UUID; + +import org.hibernate.SessionFactory; +import org.hibernate.validator.InvalidStateException; +import org.junit.Assume; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.IOnTransaction; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.daos.ICriterionDAO; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionSatisfaction; +import org.navalplanner.business.resources.entities.CriterionType; +import org.navalplanner.business.resources.entities.CriterionWithItsType; +import org.navalplanner.business.resources.entities.ICriterion; +import org.navalplanner.business.resources.entities.ICriterionType; +import org.navalplanner.business.resources.entities.PredefinedCriterionTypes; +import org.navalplanner.business.resources.entities.Resource; +import org.navalplanner.business.resources.entities.Worker; +import org.navalplanner.business.resources.services.IResourceService; +import org.navalplanner.web.resources.criterion.CriterionsModel; +import org.navalplanner.web.resources.criterion.ICriterionsModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.NotTransactional; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +/** + * Tests for {@link CriterionsModel}.
+ * + * @author Óscar González Fernández + * @author Manuel Rego Casasnovas + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, + WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE }) +@Transactional +public class CriterionModelTest { + + @Autowired + private ICriterionsModel criterionModel; + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + private IAdHocTransactionService adHocTransactionService; + + @Autowired + private ICriterionDAO criterionDAO; + + @Autowired + private IResourceService resourceService; + + @Test(expected = InvalidStateException.class) + public void testCantSaveCriterionWithoutNameAndType() throws Exception { + Criterion criterion = createValidCriterion("valido"); + criterion.setName(""); + criterionModel.save(criterion); + sessionFactory.getCurrentSession().flush(); + } + + public static Criterion createValidCriterion() { + return createValidCriterion(UUID.randomUUID().toString()); + } + + public static Criterion createValidCriterion(String name) { + CriterionType criterionType = createValidCriterionType(); + + return Criterion.withNameAndType(name, criterionType); + } + + public static CriterionType createValidCriterionType(String name) { + return new CriterionType(name); + } + + public static CriterionType createValidCriterionType() { + String unique = UUID.randomUUID().toString(); + return createValidCriterionType(unique); + } + + @Test + public void testAddCriterion() throws Exception { + String unique = UUID.randomUUID().toString(); + Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique); + criterionModel.save(criterion); + } + + @Test + @NotTransactional + public void testEditingCriterion() throws Exception { + String unique = UUID.randomUUID().toString(); + final Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique); + int initial = getCriterionsNumber(PredefinedCriterionTypes.WORK_RELATIONSHIP); + criterionModel.save(criterion); + assertThat( + "after saving one more", + getCriterionsNumber(PredefinedCriterionTypes.WORK_RELATIONSHIP), + equalTo(initial + 1)); + criterion.setActive(false); + String newName = UUID.randomUUID().toString() + "random"; + criterion.setName(newName); + criterionModel.save(criterion); + assertThat( + "after editing there are the same", + getCriterionsNumber(PredefinedCriterionTypes.WORK_RELATIONSHIP), + equalTo(initial + 1)); + Criterion retrieved = adHocTransactionService + .onTransaction(new IOnTransaction() { + + @Override + public Criterion execute() { + try { + return criterionDAO.find(criterion); + } catch (InstanceNotFoundException e) { + throw new RuntimeException(e); + } + } + }); + + assertThat(retrieved.getName(), equalTo(newName)); + + adHocTransactionService.onTransaction(new IOnTransaction() { + + @Override + public Void execute() { + if (criterion.getId() != null) { + try { + criterionDAO.remove(criterion.getId()); + } catch (InstanceNotFoundException e) { + throw new RuntimeException(e); + } + } else { + criterionDAO.removeByNameAndType(criterion); + } + return null; + } + }); + } + + private int getCriterionsNumber(final ICriterionType type) { + int size = adHocTransactionService + .onTransaction(new IOnTransaction() { + + @Override + public Integer execute() { + return criterionDAO.findByType(type).size(); + } + }); + return size; + } + + @Test + public void testSaveSameCriterionTwice() throws ValidationException { + String unique = UUID.randomUUID().toString(); + Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique); + criterionModel.save(criterion); + criterionModel.save(criterion); + } + + @Test + public void testCreateIfNotExists() throws ValidationException { + String unique = UUID.randomUUID().toString(); + Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique); + if (!(criterionDAO.exists(criterion.getId()) || criterionDAO + .existsByNameAndType(criterion))) + criterionModel.save(criterion); + assertTrue(criterionDAO.exists(criterion.getId()) + || criterionDAO.existsByNameAndType(criterion)); + if (!(criterionDAO.exists(criterion.getId()) || criterionDAO + .existsByNameAndType(criterion))) + criterionModel.save(PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique)); + } + + @Test(expected = ValidationException.class) + @NotTransactional + public void twoDifferentCriterionsWithSameNameAndTypeAreDetectedIfPossible() + throws ValidationException { + String unique = UUID.randomUUID().toString(); + Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique); + criterionModel.save(criterion); + Criterion criterion2 = PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique); + criterionModel.save(criterion2); + } + + public static class ResourceTest extends Resource { + + @Override + public int getDailyCapacity() { + return 0; + } + + @Override + public String getDescription() { + return ""; + } + + } + + @Test + @NotTransactional + public void testCriterionIsEquivalentOnDetachedAndProxifiedCriterion() + throws Exception { + final Worker worker1 = new Worker("worker-1", "worker-2-surname", + "11111111A", 8); + resourceService.saveResource(worker1); + Criterion criterion = createValidCriterion(); + criterionModel.save(criterion); + createTypeThatMatches(criterion); + worker1.addSatisfaction(new CriterionWithItsType(criterion.getType(), + criterion)); + resourceService.saveResource(worker1); + Resource workerReloaded = adHocTransactionService + .onTransaction(new IOnTransaction() { + + @Override + public Resource execute() { + try { + Resource result = resourceService + .findResource(worker1.getId()); + forceLoadSatisfactions(result); + return result; + } catch (InstanceNotFoundException e) { + throw new RuntimeException(e); + } + } + }); + Collection satisfactionsFor = workerReloaded + .getSatisfactionsFor(criterion.getType()); + Criterion reloadedCriterion = satisfactionsFor.iterator().next() + .getCriterion(); + Assume.assumeTrue(!reloadedCriterion.getClass().equals( + criterion.getClass())); + assertTrue(reloadedCriterion.isEquivalent(criterion)); + } + + private void forceLoadSatisfactions(Resource resource) { + for (CriterionSatisfaction criterionSatisfaction : resource + .getAllSatisfactions()) { + criterionSatisfaction.getCriterion().getName(); + criterionSatisfaction.getCriterion().getType().getName(); + } + } + + private static ICriterionType createTypeThatMatches( + final Criterion criterion) { + return createTypeThatMatches(false, criterion); + } + + private static ICriterionType createTypeThatMatches( + final boolean allowSimultaneousCriterionsPerResource, + final Criterion criterion) { + return new ICriterionType() { + + @Override + public boolean allowSimultaneousCriterionsPerResource() { + return allowSimultaneousCriterionsPerResource; + } + + @Override + public boolean allowHierarchy() { + return false; + } + + @Override + public boolean contains(ICriterion c) { + return criterion.isEquivalent(c); + } + + @Override + public Criterion createCriterion(String name) { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public boolean allowAdding() { + return false; + } + + @Override + public boolean allowEditing() { + return false; + } + + @Override + public boolean criterionCanBeRelatedTo( + Class klass) { + return true; + } + + @Override + public Criterion createCriterionWithoutNameYet() { + return null; + } + }; + } + +} diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerModelTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerModelTest.java index 87ca0072b..d48e3c39d 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerModelTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerModelTest.java @@ -5,15 +5,15 @@ import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import java.util.ArrayList; -import java.util.Collection; +import java.util.List; import org.junit.Test; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.PredefinedCriterionTypes; import org.navalplanner.business.resources.entities.Worker; -import org.navalplanner.business.resources.services.ICriterionService; import org.navalplanner.business.resources.services.IResourceService; import org.navalplanner.web.resources.worker.WorkerModel; @@ -27,17 +27,17 @@ public class WorkerModelTest { public void testWorkerValid() throws ValidationException, InstanceNotFoundException { IResourceService resourceServiceMock = createMock(IResourceService.class); - ICriterionService criterionServiceMock = createMock(ICriterionService.class); + ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class); Worker workerToReturn = new Worker(); workerToReturn.setDailyHours(2); workerToReturn.setFirstName("firstName"); workerToReturn.setSurname("surname"); workerToReturn.setNif("232344243"); // expectations - Collection criterions = new ArrayList(); + List criterions = new ArrayList(); expect( criterionServiceMock - .getCriterionsFor(PredefinedCriterionTypes.LOCATION_GROUP)) + .findByType(PredefinedCriterionTypes.LOCATION_GROUP)) .andReturn(criterions).anyTimes(); expect(resourceServiceMock.findResource(workerToReturn.getId())) .andReturn(workerToReturn); @@ -55,13 +55,13 @@ public class WorkerModelTest { public void testWorkerInvalid() throws ValidationException, InstanceNotFoundException { IResourceService resourceServiceMock = createMock(IResourceService.class); - ICriterionService criterionServiceMock = createMock(ICriterionService.class); + ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class); Worker workerToReturn = new Worker(); // expectations - Collection criterions = new ArrayList(); + List criterions = new ArrayList(); expect( criterionServiceMock - .getCriterionsFor(PredefinedCriterionTypes.LOCATION_GROUP)) + .findByType(PredefinedCriterionTypes.LOCATION_GROUP)) .andReturn(criterions).anyTimes(); expect(resourceServiceMock.findResource(workerToReturn.getId())) .andReturn(workerToReturn);