From e797f6e35010cf5aa33a8a2a0c17f8f94e9e073b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Thu, 21 May 2009 13:59:45 +0200 Subject: [PATCH] ItEr09S09AdministracionGrupos: Refactored bussiness layer so it follows ICriterionType restrictions when saving. --- .../bootstrap/CriterionsBootstrap.java | 10 +- .../bootstrap/ICriterionsBootstrap.java | 18 ++ .../entities/CriterionSatisfaction.java | 14 +- .../resources/entities/CriterionTypeBase.java | 8 +- .../entities/CriterionWithItsType.java | 31 +++ .../resources/entities/ICriterionType.java | 2 + .../entities/PredefinedCriterionTypes.java | 19 +- .../business/resources/entities/Resource.java | 132 +++++++++- .../resources/services/CriterionService.java | 9 +- .../resources/services/ResourceService.java | 3 + .../services/impl/CriterionServiceImpl.java | 33 ++- .../services/impl/ResourceServiceImpl.java | 5 + .../resources/entities/Resources.hbm.xml | 2 +- .../bootstrap/CriterionsBootstrapTest.java | 12 +- .../entities/CriterionSatisfactionTest.java | 33 +++ .../resources/entities/CriterionTest.java | 31 ++- .../test/resources/entities/ResourceTest.java | 248 ++++++++++++++---- .../services/CriterionServiceTest.java | 164 +++++++----- .../web/resources/CriterionsModel.java | 4 +- 19 files changed, 616 insertions(+), 162 deletions(-) create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/ICriterionsBootstrap.java create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionWithItsType.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 900fe02ff..d481f9e50 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 @@ -6,13 +6,13 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.navalplanner.business.IDataBootstrap; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.services.CriterionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; /** * Loads all {@link ICriterionTypeProvider} and if there is any criterion that @@ -21,7 +21,7 @@ import org.springframework.stereotype.Component; */ @Component @Scope("singleton") -public class CriterionsBootstrap implements IDataBootstrap { +public class CriterionsBootstrap implements ICriterionsBootstrap { @Autowired private CriterionService criterionService; @@ -29,6 +29,9 @@ public class CriterionsBootstrap implements IDataBootstrap { @Autowired private List providers; + public CriterionsBootstrap() { + } + public List> getTypes() { ArrayList> result = new ArrayList>(); for (ICriterionTypeProvider provider : providers) { @@ -38,6 +41,7 @@ public class CriterionsBootstrap implements IDataBootstrap { } @Override + @Transactional public void loadRequiredData() { Map, List> typesWithCriterions = getTypesWithCriterions(); for (Entry, List> entry : typesWithCriterions @@ -48,7 +52,7 @@ public class CriterionsBootstrap implements IDataBootstrap { } } - public Map, List> getTypesWithCriterions() { + private Map, List> getTypesWithCriterions() { HashMap, List> result = new HashMap, List>(); for (ICriterionTypeProvider provider : providers) { for (Entry, List> entry : provider diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/ICriterionsBootstrap.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/ICriterionsBootstrap.java new file mode 100644 index 000000000..009f5345e --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/ICriterionsBootstrap.java @@ -0,0 +1,18 @@ +package org.navalplanner.business.resources.bootstrap; + +import java.util.List; + +import org.navalplanner.business.IDataBootstrap; +import org.navalplanner.business.resources.entities.ICriterionType; + +/** + * Contract for {@link CriterionsBootstrap}.
+ * @author Óscar González Fernández + */ +public interface ICriterionsBootstrap extends IDataBootstrap { + + public abstract List> getTypes(); + + public abstract void loadRequiredData(); + +} \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java index 3c6ed492b..ae8b3f3ff 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java @@ -30,7 +30,6 @@ public class CriterionSatisfaction { this.startDate = startDate; this.criterion = criterion; this.resource = resource; - this.resource.add(this); } public Long getId() { @@ -62,21 +61,28 @@ public class CriterionSatisfaction { } public boolean isActiveNow() { - return startDate.before(new Date()) && finishDate == null; + Date now = new Date(); + return isActiveAt(now); + } + + public boolean isActiveAt(Date date) { + return (startDate.before(date) || startDate.equals(date)) + && (finishDate == null || date.before(finishDate)); } public boolean isActiveIn(Date start, Date end) { - return startDate.before(start) + return (startDate.equals(start) || startDate.before(start)) && (finishDate == null || end.before(finishDate)); } public void finish(Date finish) { Validate.notNull(finish); - Validate.isTrue(startDate.before(finish)); + Validate.isTrue(startDate.equals(finish) || startDate.before(finish)); finishDate = finish; } public boolean isFinished() { return finishDate != null; } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java index 3ab08da71..413afa12f 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java @@ -10,7 +10,7 @@ public abstract class CriterionTypeBase implements ICriterionType { private final boolean allowHierarchy; - private final boolean allowMultipleValuesPerResource; + private final boolean allowMultipleCriterionsPerResource; private final String name; @@ -19,11 +19,11 @@ public abstract class CriterionTypeBase implements ICriterionType { private final boolean allowEditing; protected CriterionTypeBase(String name, boolean allowHierarchy, - boolean allowMultipleValuesPerResource, boolean allowAdding, + boolean allowMultipleCriterionsPerResource, boolean allowAdding, boolean allowEditing) { Validate.notNull(name, "name is not null"); this.allowHierarchy = allowHierarchy; - this.allowMultipleValuesPerResource = allowMultipleValuesPerResource; + this.allowMultipleCriterionsPerResource = allowMultipleCriterionsPerResource; this.name = name; this.allowAdding = allowAdding; this.allowEditing = allowEditing; @@ -36,7 +36,7 @@ public abstract class CriterionTypeBase implements ICriterionType { @Override public boolean allowMultipleActiveCriterionsPerResource() { - return allowMultipleValuesPerResource; + return allowMultipleCriterionsPerResource; } public String getName() { diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionWithItsType.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionWithItsType.java new file mode 100644 index 000000000..8053152f7 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionWithItsType.java @@ -0,0 +1,31 @@ +package org.navalplanner.business.resources.entities; + +import org.apache.commons.lang.Validate; + +/** + * A {@link ICriterion} with his associated {@link ICriterionType}
+ * @author Óscar González Fernández + */ +public class CriterionWithItsType { + + private final ICriterionType type; + + private final Criterion criterion; + + public CriterionWithItsType(ICriterionType type, Criterion criterion) { + Validate.notNull(type); + Validate.notNull(criterion); + Validate.isTrue(type.contains(criterion), + "the criterion must be belong to the type"); + this.type = type; + this.criterion = criterion; + } + + public ICriterionType getType() { + return type; + } + + public Criterion getCriterion() { + return criterion; + } +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java index 0e82a9825..4c7a65a4d 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java @@ -20,4 +20,6 @@ public interface ICriterionType { public boolean contains(ICriterion criterion); + public boolean criterionCanBeRelatedTo(Class klass); + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java index d1c56c384..719f9f8e0 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java @@ -9,13 +9,13 @@ import java.util.List; */ public enum PredefinedCriterionTypes implements ICriterionType { - WORK_RELATIONSHIP(false, false, false, false) { + WORK_RELATIONSHIP(false, false, false, false, Worker.class) { @Override public List getPredefined() { return WorkingRelationship.getCriterions(); } }, - LOCATION_GROUP(false, true, true, true) { + LOCATION_GROUP(false, true, true, true, Resource.class) { @Override public List getPredefined() { @@ -31,13 +31,26 @@ public enum PredefinedCriterionTypes implements ICriterionType { private final boolean allowEditing; + private List> classes; + private PredefinedCriterionTypes(boolean allowHierarchy, boolean allowMultipleActiveCriterionsPerResource, - boolean allowAdding, boolean allowEditing) { + boolean allowAdding, boolean allowEditing, + Class... klasses) { this.allowHierarchy = allowHierarchy; this.allowMultipleActiveCriterionsPerResource = allowMultipleActiveCriterionsPerResource; this.allowAdding = allowAdding; this.allowEditing = allowEditing; + this.classes = Arrays.asList(klasses); + } + + @Override + public boolean criterionCanBeRelatedTo(Class klass) { + for (Class c : classes) { + if (c.isAssignableFrom(klass)) + return true; + } + return false; } @Override diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java index 0dcd68520..5ea2a5ae2 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java @@ -1,10 +1,12 @@ package org.navalplanner.business.resources.entities; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.apache.commons.lang.Validate; @@ -69,6 +71,16 @@ public abstract class Resource { return result; } + public List getSatisfactionsFor(ICriterion criterion) { + ArrayList result = new ArrayList(); + for (CriterionSatisfaction criterionSatisfaction : getAllSatisfactions()) { + if (criterionSatisfaction.getCriterion().equals(criterion)) { + result.add(criterionSatisfaction); + } + } + return result; + } + public Collection getActiveSatisfactionsFor( ICriterionType criterionType) { Collection satisfactionsFor = getSatisfactionsFor(criterionType); @@ -84,17 +96,24 @@ public abstract class Resource { public Collection getActiveSatisfactionsForIn( ICriterionType criterionType, Date start, Date end) { Validate.notNull(criterionType); - Validate.isTrue(start.before(end)); + Validate.isTrue(end == null || start.before(end)); Collection satisfactionsFor = getSatisfactionsFor(criterionType); ArrayList result = new ArrayList(); for (CriterionSatisfaction criterionSatisfaction : satisfactionsFor) { - if (criterionSatisfaction.isActiveIn(start, end)) { + if (end == null && criterionSatisfaction.isActiveAt(start) + || end != null + && criterionSatisfaction.isActiveIn(start, end)) { result.add(criterionSatisfaction); } } return result; } + public Collection getActiveSatisfactionsAt( + ICriterionType criterionType, Date pointInTime) { + return getActiveSatisfactionsForIn(criterionType, pointInTime, null); + } + public Collection getActiveSatisfactionsFor( ICriterion criterion) { Set result = new HashSet(); @@ -119,7 +138,7 @@ public abstract class Resource { public Collection getActiveSatisfactionsForIn( ICriterion criterion, Date start, Date end) { - Validate.isTrue(start.before(end)); + Validate.isTrue(end == null || start.before(end)); ArrayList result = new ArrayList(); Collection allSatisfactionsFor = getAllSatisfactionsFor(criterion); for (CriterionSatisfaction criterionSatisfaction : allSatisfactionsFor) { @@ -130,10 +149,109 @@ public abstract class Resource { return result; } - void add(CriterionSatisfaction criterionSatisfaction) { - Validate.notNull(criterionSatisfaction, - "criterionSatisfaction must be not null"); - criterionSatisfactions.add(criterionSatisfaction); + public void activate(CriterionWithItsType criterionWithItsType) { + activate(criterionWithItsType, new Date()); + } + + public void activate(CriterionWithItsType criterionWithItsType, Date start) { + activate(criterionWithItsType, start, null); + } + + public void activate(CriterionWithItsType criterionWithItsType, Date start, + Date finish) { + ICriterionType type = criterionWithItsType.getType(); + Criterion criterion = criterionWithItsType.getCriterion(); + if (canBeActivated(criterionWithItsType, start, finish)) { + CriterionSatisfaction newSatisfaction = new CriterionSatisfaction( + start, criterion, this); + criterionSatisfactions.add(newSatisfaction); + if (finish != null) + newSatisfaction.finish(finish); + if (!type.allowMultipleActiveCriterionsPerResource()) { + for (CriterionSatisfaction criterionSatisfaction : getActiveSatisfactionsAt( + type, start)) { + if (newSatisfaction != criterionSatisfaction) { + criterionSatisfaction.finish(start); + } + } + Set posterior = getSatisfactionsPosteriorTo( + type, newSatisfaction); + Date earliest = getEarliestStartDate(posterior); + if (earliest != null) { + newSatisfaction.finish(earliest); + } + } + } else { + throw new IllegalStateException( + "this resource is activaved for other criterion of the same type"); + } + + } + + private static Date getEarliestStartDate( + Set posterior) { + Date earliest = null; + for (CriterionSatisfaction criterionSatisfaction : posterior) { + if (earliest == null) + earliest = criterionSatisfaction.getStartDate(); + earliest = Collections.min(Arrays.asList(earliest, + criterionSatisfaction.getStartDate())); + } + return earliest; + } + + private Set getSatisfactionsPosteriorTo( + ICriterionType type, CriterionSatisfaction newSatisfaction) { + Date start = newSatisfaction.getStartDate(); + Date finish = newSatisfaction.isFinished() ? newSatisfaction + .getEndDate() : null; + Set posterior = new HashSet(); + if (finish != null) { + posterior.addAll(getActiveSatisfactionsAt(type, finish)); + } else { + ArrayList result = new ArrayList(); + for (CriterionSatisfaction satisfaction : getSatisfactionsFor(type)) { + if (!satisfaction.isFinished() + && satisfaction.getStartDate().after(start)) { + result.add(satisfaction); + } + } + posterior.addAll(result); + } + posterior.remove(newSatisfaction); + return posterior; + } + + public void deactivate(CriterionWithItsType criterionWithItsType) { + for (CriterionSatisfaction criterionSatisfaction : getActiveSatisfactionsFor(criterionWithItsType + .getCriterion())) { + criterionSatisfaction.finish(new Date()); + } + } + + private boolean noneOf(CriterionWithItsType criterionWithItsType, + Date start, Date end) { + ICriterionType type = criterionWithItsType.getType(); + Criterion criterion = criterionWithItsType.getCriterion(); + return getActiveSatisfactionsForIn(type, start, end).size() == getActiveSatisfactionsForIn( + criterion, start, end).size(); + } + + public boolean canBeActivated(CriterionWithItsType criterionWithItsType) { + return canBeActivated(criterionWithItsType, new Date()); + } + + public boolean canBeActivated(CriterionWithItsType criterionWithItsType, + Date start) { + return canBeActivated(criterionWithItsType, start, null); + } + + public boolean canBeActivated(CriterionWithItsType criterionWithItsType, + Date start, Date finish) { + ICriterionType type = criterionWithItsType.getType(); + return type.criterionCanBeRelatedTo(getClass()) + && (type.allowMultipleActiveCriterionsPerResource() || noneOf( + criterionWithItsType, start, finish)); } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java index 1867a99c4..21e9c0261 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java @@ -13,7 +13,7 @@ import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.entities.Resource; /** - * Services for aggregate {@link Criterion}
+ * Services for {@link Criterion}
* @author Óscar González Fernández */ public interface CriterionService { @@ -24,8 +24,6 @@ public interface CriterionService { void save(Criterion entity); - void add(CriterionSatisfaction criterionSatisfaction); - Collection getResourcesSatisfying(ICriterion criterion); Collection getResourcesSatisfying(ICriterion criterion, @@ -45,4 +43,9 @@ public interface CriterionService { Collection getCriterionsFor(ICriterionType type); + List getResourcesSatisfying(Class resourceType, + Criterion criterion); + + Criterion load(Criterion criterion); + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ResourceService.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ResourceService.java index c060d53d1..7c6f075b4 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ResourceService.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/ResourceService.java @@ -38,5 +38,8 @@ public interface ResourceService { public List getResources(); + public List getResources(Class klass); + public Set getSetOfResourcesSatisfying(ICriterion criterion); + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java index 0c8caccbd..4fc180bab 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java @@ -8,7 +8,6 @@ import java.util.List; import org.apache.commons.lang.Validate; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.daos.impl.CriterionDAO; -import org.navalplanner.business.resources.daos.impl.CriterionSatisfactionDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionSatisfaction; import org.navalplanner.business.resources.entities.ICriterion; @@ -31,9 +30,6 @@ public class CriterionServiceImpl implements CriterionService { @Autowired private CriterionDAO criterionDAO; - @Autowired - private CriterionSatisfactionDAO criterionSatisfactionDAO; - @Autowired private ResourceService resourceService; @@ -57,11 +53,6 @@ public class CriterionServiceImpl implements CriterionService { criterionDAO.save(entity); } - @Override - public void add(CriterionSatisfaction criterionSatisfaction) { - criterionSatisfactionDAO.save(criterionSatisfaction); - } - @Override public Collection getResourcesSatisfying(ICriterion criterion) { List resources = resourceService.getResources(); @@ -165,4 +156,28 @@ public class CriterionServiceImpl implements CriterionService { } 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/impl/ResourceServiceImpl.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/ResourceServiceImpl.java index e25820040..d065d8306 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/ResourceServiceImpl.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/ResourceServiceImpl.java @@ -71,4 +71,9 @@ public class ResourceServiceImpl implements ResourceService { public List getResources() { return resourceDao.list(Resource.class); } + + @Override + public List getResources(Class klass) { + return resourceDao.list(klass); + } } diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml index 9119e2262..cf92b12c7 100644 --- a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml @@ -10,7 +10,7 @@ Hibernate infers type="integer". --> - + 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 048742010..a93c633db 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 @@ -1,12 +1,8 @@ package org.navalplanner.business.test.resources.bootstrap; -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 org.junit.Test; import org.junit.runner.RunWith; -import org.navalplanner.business.resources.bootstrap.CriterionsBootstrap; +import org.navalplanner.business.resources.bootstrap.ICriterionsBootstrap; import org.navalplanner.business.resources.entities.WorkingRelationship; import org.navalplanner.business.resources.services.CriterionService; import org.springframework.beans.factory.annotation.Autowired; @@ -14,6 +10,10 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; +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; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, BUSINESS_SPRING_CONFIG_TEST_FILE }) @@ -21,7 +21,7 @@ import org.springframework.transaction.annotation.Transactional; public class CriterionsBootstrapTest { @Autowired - private CriterionsBootstrap criterionsBootstrap; + private ICriterionsBootstrap criterionsBootstrap; @Autowired private CriterionService criterionService; diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionSatisfactionTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionSatisfactionTest.java index b1cbb16cd..65200e3dc 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionSatisfactionTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionSatisfactionTest.java @@ -10,6 +10,7 @@ import org.navalplanner.business.test.resources.daos.CriterionDAOTest; import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest; import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** @@ -33,6 +34,17 @@ public class CriterionSatisfactionTest { criterionSatisfaction.getEndDate()); } + @Test + public void canFinishWhenItStarted() throws Exception { + final Criterion criterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + Date start = CriterionSatisfactionDAOTest.year(2000); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + start, criterion, worker); + criterionSatisfaction.finish(start); + assertTrue(criterionSatisfaction.isFinished()); + } + @Test(expected = IllegalArgumentException.class) public void testCantFinishBeforeStart() { final Criterion criterion = CriterionDAOTest.createValidCriterion(); @@ -42,4 +54,25 @@ public class CriterionSatisfactionTest { criterionSatisfaction.finish(CriterionSatisfactionDAOTest.year(1999)); } + @Test + public void isValidAtDate() { + final Criterion criterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(2000), criterion, worker); + assertTrue(criterionSatisfaction + .isActiveAt(CriterionSatisfactionDAOTest.year(3000))); + assertTrue(criterionSatisfaction + .isActiveAt(CriterionSatisfactionDAOTest.year(2000))); + assertFalse(criterionSatisfaction + .isActiveAt(CriterionSatisfactionDAOTest.year(1999))); + criterionSatisfaction.finish(CriterionSatisfactionDAOTest.year(2005)); + assertFalse(criterionSatisfaction + .isActiveAt(CriterionSatisfactionDAOTest.year(3000))); + assertTrue(criterionSatisfaction + .isActiveAt(CriterionSatisfactionDAOTest.year(2000))); + assertFalse(criterionSatisfaction + .isActiveAt(CriterionSatisfactionDAOTest.year(1999))); + } + } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionTest.java index 9776ccacd..994fbe5c0 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionTest.java @@ -1,12 +1,5 @@ package org.navalplanner.business.test.resources.entities; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; -import static org.navalplanner.business.resources.entities.CriterionCompounder.atom; -import static org.navalplanner.business.resources.entities.CriterionCompounder.build; -import static org.navalplanner.business.resources.entities.CriterionCompounder.not; - import java.util.Arrays; import java.util.Date; import java.util.HashSet; @@ -19,6 +12,13 @@ import org.navalplanner.business.resources.entities.PredefinedCriterionTypes; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.navalplanner.business.resources.entities.CriterionCompounder.atom; +import static org.navalplanner.business.resources.entities.CriterionCompounder.build; +import static org.navalplanner.business.resources.entities.CriterionCompounder.not; + /** * Tests for criterion.
* Created at May 12, 2009 @@ -34,7 +34,6 @@ public class CriterionTest { .contains(firedCriterion)); } - @Test public void testCriterionNameAndTypeIsInmutableBusinessKey() throws Exception { @@ -59,8 +58,8 @@ public class CriterionTest { assertTrue(criterionForWorkers1And2.isSatisfiedBy(worker1)); assertTrue(criterionForWorkers1And2.isSatisfiedBy(worker2)); - ICriterion compositedCriterion = CriterionCompounder.atom(criterionForWorker1) - .and(criterionForWorkers1And2).getResult(); + ICriterion compositedCriterion = CriterionCompounder.atom( + criterionForWorker1).and(criterionForWorkers1And2).getResult(); ICriterion matchesNoneComposited = CriterionCompounder.build().and( criterionForWorker1).and(criterionForWorker2).getResult(); @@ -138,6 +137,18 @@ public class CriterionTest { assertTrue("or has less priority", or.isSatisfiedBy(worker3)); } + @Test + public void testCanBeRelatedTo() throws Exception { + assertTrue(PredefinedCriterionTypes.LOCATION_GROUP + .criterionCanBeRelatedTo(Resource.class)); + assertTrue(PredefinedCriterionTypes.LOCATION_GROUP + .criterionCanBeRelatedTo(Worker.class)); + assertFalse(PredefinedCriterionTypes.WORK_RELATIONSHIP + .criterionCanBeRelatedTo(Resource.class)); + assertTrue(PredefinedCriterionTypes.WORK_RELATIONSHIP + .criterionCanBeRelatedTo(Worker.class)); + } + public static ICriterion justThisResourcesCriterion( final Resource... resources) { final HashSet set = new HashSet(Arrays diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java index 0420fc53b..4054138b6 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java @@ -7,6 +7,7 @@ import org.junit.Test; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionSatisfaction; import org.navalplanner.business.resources.entities.CriterionTypeBase; +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.Resource; @@ -14,7 +15,12 @@ import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.test.resources.daos.CriterionDAOTest; import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest; -import static junit.framework.Assert.assertEquals; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * Tests for {@link Resource}.
@@ -23,24 +29,20 @@ import static junit.framework.Assert.assertEquals; public class ResourceTest { @Test - public void testRelationResourceWithCriterionSatisfaction() - throws Exception { + public void testGetSatisfactionsForCriterion() { Criterion criterion = CriterionDAOTest.createValidCriterion(); + Criterion other = CriterionDAOTest.createValidCriterion(); + CriterionTypeBase type = createTypeThatMatches(false, criterion); + CriterionTypeBase otherType = createTypeThatMatches(false, other); Worker worker = new Worker("firstName", "surName", "2333232", 10); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - criterion, worker); - assertEquals(1, worker.getAllSatisfactions().size()); - } - - @Test - public void testGetActiveSatisfactionsForCriterion() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - criterion, worker); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(4000), - criterion, worker); - assertEquals(1, worker.getActiveSatisfactionsFor(criterion).size()); + assertThat(worker.getSatisfactionsFor(criterion).size(), equalTo(0)); + worker.activate(new CriterionWithItsType(type, criterion)); + assertTrue(criterion.isSatisfiedBy(worker)); + assertThat(worker.getSatisfactionsFor(criterion).size(), equalTo(1)); + worker.activate(new CriterionWithItsType(otherType, other)); + assertTrue(other.isSatisfiedBy(worker)); + assertThat(worker.getSatisfactionsFor(other).size(), equalTo(1)); + assertThat(worker.getSatisfactionsFor(criterion).size(), equalTo(1)); } @Test(expected = IllegalArgumentException.class) @@ -59,40 +61,38 @@ public class ResourceTest { CriterionSatisfactionDAOTest.year(1999)); } - @Test - public void tesGetSatisfactionsInIntervalForCriterion() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - criterion, worker); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(1997), - criterion, worker); - assertEquals(1, worker.getActiveSatisfactionsForIn(criterion, - CriterionSatisfactionDAOTest.year(1999), - CriterionSatisfactionDAOTest.year(2010)).size()); - } - @Test public void testRetrieveActiveCriterionsForCriterionType() throws Exception { final Criterion criterion = CriterionDAOTest.createValidCriterion(); Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - criterion, worker); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - otherCriterion, worker); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(4000), - criterion, worker); ICriterionType criterionType = createTypeThatMatches(criterion); + CriterionWithItsType criterionWithItsType = new CriterionWithItsType( + criterionType, criterion); + CriterionWithItsType otherCriterionWithItsType = new CriterionWithItsType( + createTypeThatMatches(otherCriterion), otherCriterion); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(2000)); + worker.activate(otherCriterionWithItsType, CriterionSatisfactionDAOTest + .year(2000)); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(4000)); assertEquals(2, worker.getSatisfactionsFor(criterionType).size()); assertEquals(1, worker.getActiveSatisfactionsFor(criterionType).size()); } public static CriterionTypeBase createTypeThatMatches( final Criterion... criterions) { + return createTypeThatMatches(true, criterions); + } + + public static CriterionTypeBase createTypeThatMatches( + boolean allowMultipleCriterionsPerResource, + final Criterion... criterions) { final HashSet criterionsSet = new HashSet(Arrays .asList(criterions)); - return new CriterionTypeBase("base", true, true, false, false) { + return new CriterionTypeBase("base", true, + allowMultipleCriterionsPerResource, false, false) { @Override public boolean contains(ICriterion c) { @@ -103,6 +103,12 @@ public class ResourceTest { public Criterion createCriterion(String name) { return null; } + + @Override + public boolean criterionCanBeRelatedTo( + Class klass) { + return true; + } }; } @@ -110,16 +116,20 @@ public class ResourceTest { public void testRetrieveSatisfactionsInIntervalForCriterionType() throws Exception { Criterion criterion = CriterionDAOTest.createValidCriterion(); - Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - criterion, worker); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2003), - criterion, worker); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - otherCriterion, worker); - ICriterionType criterionType = createTypeThatMatches(criterion); + CriterionWithItsType criterionWithItsType = new CriterionWithItsType( + criterionType, criterion); + Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); + CriterionWithItsType otherCriterionWithItsType = new CriterionWithItsType( + createTypeThatMatches(otherCriterion), otherCriterion); + + Worker worker = new Worker("firstName", "surName", "2333232", 10); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(2000)); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(2003)); + worker.activate(otherCriterionWithItsType, CriterionSatisfactionDAOTest + .year(2000)); assertEquals(2, worker.getSatisfactionsFor(criterionType).size()); assertEquals(1, worker.getActiveSatisfactionsForIn(criterionType, @@ -133,4 +143,148 @@ public class ResourceTest { CriterionSatisfactionDAOTest.year(2005)).size()); } + @Test(expected = IllegalArgumentException.class) + public void invalidadCriterionWithItsTypeNotAllowd() throws Exception { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); + ICriterionType criterionType = createTypeThatMatches(criterion); + new CriterionWithItsType(criterionType, otherCriterion); + } + + @Test + public void testActivateAndDeactivateCriterion() { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + ICriterionType criterionType = createTypeThatMatches(false, + criterion, otherCriterion); + assertThat(worker.getActiveSatisfactionsFor(criterion).size(), + equalTo(0)); + assertFalse(criterion.isSatisfiedBy(worker)); + assertTrue(worker.canBeActivated(new CriterionWithItsType( + criterionType, criterion))); + worker.activate(new CriterionWithItsType(criterionType, criterion)); + assertTrue(criterion.isSatisfiedBy(worker)); + assertThat(worker.getActiveSatisfactionsFor(criterion).size(), + equalTo(1)); + assertFalse(worker.canBeActivated(new CriterionWithItsType( + criterionType, otherCriterion))); + try { + worker.activate(new CriterionWithItsType(criterionType, + otherCriterion)); + fail("must send exception since it already is activated for a criterion of the same type and the type doesn't allow repeated criterions per resource"); + } catch (IllegalStateException e) { + // ok + } + assertTrue(worker.canBeActivated(new CriterionWithItsType( + criterionType, criterion))); + assertThat(worker.getActiveSatisfactionsFor(criterion).size(), + equalTo(1)); + worker.deactivate(new CriterionWithItsType(criterionType, criterion)); + assertTrue("the satisfactions are deactivated", worker + .getActiveSatisfactionsFor(criterion).isEmpty()); + } + + @Test + public void testActivateInDate() throws Exception { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + ICriterionType criterionType = createTypeThatMatches(false, + criterion, otherCriterion); + worker.activate(new CriterionWithItsType(criterionType, criterion), + CriterionSatisfactionDAOTest.year(4000)); + worker.activate(new CriterionWithItsType(criterionType, criterion), + CriterionSatisfactionDAOTest.year(5000), + CriterionSatisfactionDAOTest.year(6000)); + + assertThat(worker.getActiveSatisfactionsForIn(criterion, + CriterionSatisfactionDAOTest.year(4001), + CriterionSatisfactionDAOTest.year(4999)).size(), equalTo(1)); + assertThat(worker.getActiveSatisfactionsForIn(criterion, + CriterionSatisfactionDAOTest.year(5001), + CriterionSatisfactionDAOTest.year(5500)).size(), equalTo(1)); + + worker.deactivate(new CriterionWithItsType(criterionType, criterion)); + + assertThat(worker.getActiveSatisfactionsForIn(criterion, + CriterionSatisfactionDAOTest.year(4001), + CriterionSatisfactionDAOTest.year(4999)).size(), equalTo(1)); + assertThat(worker.getActiveSatisfactionsForIn(criterion, + CriterionSatisfactionDAOTest.year(5001), + CriterionSatisfactionDAOTest.year(5500)).size(), equalTo(1)); + + assertFalse(worker.canBeActivated(new CriterionWithItsType( + criterionType, otherCriterion), CriterionSatisfactionDAOTest + .year(4001))); + } + + @Test + // when type doesnt allow multiple active criterions per resource + public void activateOnlyUntilNextCriterionIsActive() { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + ICriterionType criterionType = createTypeThatMatches(false, + criterion, otherCriterion); + worker.activate(new CriterionWithItsType(criterionType, criterion), + CriterionSatisfactionDAOTest.year(4000)); + worker.activate( + new CriterionWithItsType(criterionType, otherCriterion), + CriterionSatisfactionDAOTest.year(3500)); + assertThat(worker.getSatisfactionsFor(otherCriterion).size(), + equalTo(1)); + CriterionSatisfaction satisfaction = worker.getSatisfactionsFor( + otherCriterion).iterator().next(); + assertThat(satisfaction.getEndDate(), + equalTo(CriterionSatisfactionDAOTest.year(4000))); + } + + @Test(expected = IllegalStateException.class) + // when type doesnt allow multiple active criterions per resource + public void deactivatePrevious() { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Criterion otherCriterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + ICriterionType criterionType = createTypeThatMatches(false, + criterion, otherCriterion); + worker.activate( + new CriterionWithItsType(criterionType, otherCriterion), + CriterionSatisfactionDAOTest.year(3500)); + assertFalse(worker.canBeActivated(new CriterionWithItsType( + criterionType, criterion), CriterionSatisfactionDAOTest + .year(4000))); + worker.activate(new CriterionWithItsType(criterionType, criterion), + CriterionSatisfactionDAOTest.year(4000)); + } + + @Test(expected = IllegalStateException.class) + public void shouldntActivate() { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + ICriterionType type = new CriterionTypeBase("prueba", false, false, + false, false) { + + @Override + public boolean contains(ICriterion c) { + return true; + } + + @Override + public Criterion createCriterion(String name) { + return null; + } + + @Override + public boolean criterionCanBeRelatedTo( + Class klass) { + return false; + } + }; + CriterionWithItsType criterionWithItsType = new CriterionWithItsType( + type, criterion); + assertFalse(worker.canBeActivated(criterionWithItsType)); + worker.activate(criterionWithItsType); + } + } 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 index 4371e16f0..584b5181c 100644 --- 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 @@ -7,12 +7,14 @@ import org.hibernate.SessionFactory; import org.hibernate.validator.InvalidStateException; import org.junit.Test; import org.junit.runner.RunWith; +import org.navalplanner.business.resources.bootstrap.ICriterionsBootstrap; 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.PredefinedCriterionTypes; +import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.resources.services.CriterionService; import org.navalplanner.business.resources.services.ResourceService; @@ -26,8 +28,11 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +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; @@ -50,6 +55,9 @@ public class CriterionServiceTest { @Autowired private SessionFactory sessionFactory; + @Autowired + private ICriterionsBootstrap criterionsBootstrap; + @Test(expected = InvalidStateException.class) public void testCantSaveCriterionWithoutNameAndType() throws Exception { Criterion criterion = new Criterion("", ""); @@ -99,81 +107,96 @@ public class CriterionServiceTest { assertEquals(criterion, other); } - @Test - public void testCreateCriterionSatisfactionButNotSave() { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - resourceService.saveResource(worker); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - criterion, worker); - assertEquals(1, worker.getAllSatisfactions().size()); - } - - /* - * It sends a dataIntegrityViolationException when adding a - * criterionSatisfaction with a criterion that doesn't exist yet - */ @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.activate(new CriterionWithItsType(type, criterion)); + assertTrue(criterion.isSatisfiedBy(worker)); resourceService.saveResource(worker); - - criterionService.add(new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, 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.activate(new CriterionWithItsType(type, criterion)); + assertTrue(criterion.isSatisfiedBy(worker)); + resourceService.saveResource(worker); + assertTrue(criterion.isSatisfiedBy(worker)); + assertThat(criterionService.getResourcesSatisfying(criterion).size(), + equalTo(1)); } - @Test(expected = DataIntegrityViolationException.class) public void testCreateCriterionSatisfactionOnTransientResource() throws Exception { Criterion criterion = CriterionDAOTest.createValidCriterion(); + ICriterionType type = createTypeThatMatches(criterion); criterionService.save(criterion); Worker worker = new Worker("firstName", "surName", "2333232", 10); - CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, worker); - criterionService.add(criterionSatisfaction); - } - - @Test - public void testCreatingButNotPersistingSatisfaction() throws Exception { - Criterion criterion = CriterionDAOTest.createValidCriterion(); - criterionService.save(criterion); - Worker worker = new Worker("firstName", "surName", "2333232", 10); - new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), - criterion, worker); + worker.activate(new CriterionWithItsType(type, criterion)); resourceService.saveResource(worker); - assertEquals(1, criterionService.getResourcesSatisfying(criterion) - .size()); - sessionFactory.getCurrentSession().evict(worker); - assertEquals( - "once the worker has been evicted the satisfaction created is not taken into account", - 0, criterionService.getResourcesSatisfying(criterion).size()); + 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); - CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, worker); - criterionService.add(criterionSatisfaction); + worker.activate(new CriterionWithItsType(type, criterion)); assertEquals(1, criterionService.getResourcesSatisfying(criterion) .size()); } + public static class Prueba extends Resource { + + @Override + public int getDailyCapacity() { + return 0; + } + + } + + @Test + public void testGetSetOfResourcesSubclassSatisfyingCriterion() { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + criterionService.save(criterion); + ICriterionType type = createTypeThatMatches(criterion); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + resourceService.saveResource(worker); + worker.activate(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() { Criterion criterion = CriterionDAOTest.createValidCriterion(); + ICriterionType type = createTypeThatMatches(criterion); criterionService.save(criterion); Worker worker = new Worker("firstName", "surName", "2333232", 10); resourceService.saveResource(worker); - CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, worker); - criterionService.add(criterionSatisfaction); + worker.activate(new CriterionWithItsType(type, criterion), + CriterionSatisfactionDAOTest.year(2000)); ICriterionOnData criterionOnData = criterionService.empower(criterion); assertTrue(criterionOnData.isSatisfiedBy(worker)); assertEquals(1, criterionOnData.getResourcesSatisfying().size()); @@ -190,12 +213,12 @@ public class CriterionServiceTest { @NotTransactional public void shouldntThrowExceptionDueToTransparentProxyGotcha() { Criterion criterion = CriterionDAOTest.createValidCriterion(); + ICriterionType type = createTypeThatMatches(criterion); criterionService.save(criterion); Worker worker = new Worker("firstName", "surName", "2333232", 10); resourceService.saveResource(worker); - CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, worker); - criterionService.add(criterionSatisfaction); + worker.activate(new CriterionWithItsType(type, criterion), + CriterionSatisfactionDAOTest.year(2000)); ICriterionOnData criterionOnData = criterionService.empower(criterion); criterionOnData.getResourcesSatisfying(); criterionOnData.getResourcesSatisfying(CriterionSatisfactionDAOTest @@ -215,12 +238,13 @@ public class CriterionServiceTest { 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); - CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, worker); - - criterionService.add(criterionSatisfaction); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(2000)); assertEquals(1, criterionService.getResourcesSatisfying(criterion, CriterionSatisfactionDAOTest.year(2001), @@ -229,9 +253,8 @@ public class CriterionServiceTest { CriterionSatisfactionDAOTest.year(1999), CriterionSatisfactionDAOTest.year(2005)).size()); - CriterionSatisfaction otherSatisfaction = new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(1998), criterion, worker); - criterionService.add(otherSatisfaction); + worker.activate(new CriterionWithItsType(type, criterion), + CriterionSatisfactionDAOTest.year(1998)); assertEquals(1, criterionService.getResourcesSatisfying(criterion, CriterionSatisfactionDAOTest.year(1999), @@ -241,13 +264,16 @@ public class CriterionServiceTest { @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); - criterionService.add(new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, worker)); - criterionService.add(new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(1998), criterion, worker)); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(2000)); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(1998)); ICriterionType criterionType = ResourceTest .createTypeThatMatches(criterion); @@ -262,8 +288,8 @@ public class CriterionServiceTest { CriterionSatisfactionDAOTest.year(1997), CriterionSatisfactionDAOTest.year(2005)).size()); - criterionService.add(new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(1997), criterion, worker)); + worker.activate(criterionWithItsType, CriterionSatisfactionDAOTest + .year(1997)); assertEquals(2, criterionService.getSatisfactionsFor(criterionType, CriterionSatisfactionDAOTest.year(1999), CriterionSatisfactionDAOTest.year(2005)).size()); @@ -284,6 +310,12 @@ public class CriterionServiceTest { private ICriterionType createTypeThatMatches( final Criterion criterion) { + return createTypeThatMatches(false, criterion); + } + + private ICriterionType createTypeThatMatches( + final boolean allowMultipleActiveCriterionsPerResource, + final Criterion criterion) { return new ICriterionType() { @Override @@ -293,7 +325,7 @@ public class CriterionServiceTest { @Override public boolean allowMultipleActiveCriterionsPerResource() { - return false; + return allowMultipleActiveCriterionsPerResource; } @Override @@ -323,6 +355,12 @@ public class CriterionServiceTest { // TODO Auto-generated method stub return false; } + + @Override + public boolean criterionCanBeRelatedTo( + Class klass) { + return true; + } }; } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java index b928f692c..5395fedee 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java @@ -7,7 +7,7 @@ import org.apache.commons.lang.Validate; import org.hibernate.validator.ClassValidator; import org.hibernate.validator.InvalidValue; import org.navalplanner.business.common.exceptions.ValidationException; -import org.navalplanner.business.resources.bootstrap.CriterionsBootstrap; +import org.navalplanner.business.resources.bootstrap.ICriterionsBootstrap; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.services.CriterionService; @@ -29,7 +29,7 @@ public class CriterionsModel implements ICriterionsModel { Criterion.class); @Autowired - private CriterionsBootstrap criterionsBootstrap; + private ICriterionsBootstrap criterionsBootstrap; @Autowired private CriterionService criterionService;