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 new file mode 100644 index 000000000..1f39a06a0 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java @@ -0,0 +1,12 @@ +package org.navalplanner.business.resources.daos; + +import org.navalplanner.business.common.daos.IGenericDao; +import org.navalplanner.business.resources.entities.Criterion; + +/** + * Description goes here.
+ * @author Óscar González Fernández + */ +public interface ICriterionDAO extends IGenericDao { + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionSatisfactionDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionSatisfactionDAO.java new file mode 100644 index 000000000..e4c297b0c --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionSatisfactionDAO.java @@ -0,0 +1,13 @@ +package org.navalplanner.business.resources.daos; + +import org.navalplanner.business.common.daos.IGenericDao; +import org.navalplanner.business.resources.entities.CriterionSatisfaction; + +/** + * DAO for {@link CriterionSatisfaction}
+ * @author Óscar González Fernández + */ +public interface ICriterionSatisfactionDAO extends + IGenericDao { + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/impl/CriterionDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/impl/CriterionDAO.java new file mode 100644 index 000000000..62ef28c17 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/impl/CriterionDAO.java @@ -0,0 +1,14 @@ +package org.navalplanner.business.resources.daos.impl; + +import org.navalplanner.business.common.daos.impl.GenericDaoHibernate; +import org.navalplanner.business.resources.daos.ICriterionDAO; +import org.navalplanner.business.resources.entities.Criterion; + +/** + * Description goes here.
+ * @author Óscar González Fernández + */ +public class CriterionDAO extends GenericDaoHibernate + implements ICriterionDAO { + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/impl/CriterionSatisfactionDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/impl/CriterionSatisfactionDAO.java new file mode 100644 index 000000000..5cdb152c9 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/impl/CriterionSatisfactionDAO.java @@ -0,0 +1,14 @@ +package org.navalplanner.business.resources.daos.impl; + +import org.navalplanner.business.common.daos.impl.GenericDaoHibernate; +import org.navalplanner.business.resources.daos.ICriterionSatisfactionDAO; +import org.navalplanner.business.resources.entities.CriterionSatisfaction; + +/** + * Implementation
+ * @author Óscar González Fernández + */ +public class CriterionSatisfactionDAO extends + GenericDaoHibernate implements + ICriterionSatisfactionDAO { +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java new file mode 100644 index 000000000..55d3c2743 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java @@ -0,0 +1,34 @@ +package org.navalplanner.business.resources.entities; + +import java.util.Date; + +/** + * A criterion stored in the database
+ * @author Óscar González Fernández + */ +public class Criterion implements ICriterion { + + private Long id; + + @SuppressWarnings("unused") + private long version; + + private String type; + + private boolean active; + + public Long getId() { + return id; + } + + @Override + public boolean isSatisfiedBy(Resource resource) { + return !resource.getActiveSatisfactionsFor(this).isEmpty(); + } + + public boolean isSatisfiedBy(Resource resource, Date start, Date end) { + return !resource.getActiveSatisfactionsForIn(this, start, end) + .isEmpty(); + } + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionCompounder.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionCompounder.java new file mode 100644 index 000000000..83e22b4a9 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionCompounder.java @@ -0,0 +1,168 @@ +package org.navalplanner.business.resources.entities; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +/** + * Compounds some {@link ICriterion} into one
+ * Created at May 12, 2009 + * @author Óscar González Fernández + */ +public class CriterionCompounder { + + public static CriterionCompounder build() { + return new CriterionCompounder(); + } + + public static CriterionCompounder atom(ICriterion criterion) { + return build().and(criterion); + } + + public static ICriterion not(ICriterion criterion) { + return new Negated(criterion); + } + + public static ICriterion not(CriterionCompounder compounder) { + return not(compounder.getResult()); + } + + private static class Negated implements ICriterion { + private final ICriterion criterion; + + private Negated(ICriterion criterion) { + this.criterion = criterion; + } + + @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); + } + } + + private static class OrClause implements ICriterion { + + private Collection criterions; + + public OrClause(Collection atoms) { + this.criterions = atoms; + } + + @Override + public boolean isSatisfiedBy(Resource resource) { + for (ICriterion criterion : criterions) { + if (criterion.isSatisfiedBy(resource)) { + return true; + } + } + return false; + } + + public boolean isSatisfiedBy(Resource resource, Date start, Date end) { + for (ICriterion criterion : criterions) { + if (criterion.isSatisfiedBy(resource, start, end)) { + return true; + } + } + return false; + } + + } + + private static class AndClause implements ICriterion { + private List criterions; + + AndClause() { + this.criterions = new LinkedList(); + } + + private AndClause(List atoms) { + this.criterions = atoms; + } + + public AndClause and(ICriterion criterion) { + return new AndClause(join(criterions, criterion)); + } + + private static List join(List previous, + ICriterion criterion) { + LinkedList result = new LinkedList(previous); + result.add(criterion); + return result; + } + + @Override + public boolean isSatisfiedBy(Resource resource) { + for (ICriterion criterion : criterions) { + if (!criterion.isSatisfiedBy(resource)) + return false; + } + return true; + } + + @Override + public boolean isSatisfiedBy(Resource resource, Date start, Date end) { + for (ICriterion criterion : criterions) { + if (!criterion.isSatisfiedBy(resource, start, end)) + return false; + } + return true; + } + + } + + private final List clauses; + + private CriterionCompounder() { + this(new AndClause()); + } + + private CriterionCompounder(AndClause andClause) { + clauses = new ArrayList(); + clauses.add(andClause); + } + + private CriterionCompounder(List clauses) { + this.clauses = clauses; + } + + private AndClause getLast() { + return clauses.get(clauses.size() - 1); + } + + private List updateLast(AndClause clause) { + ArrayList arrayList = new ArrayList(clauses); + arrayList.set(arrayList.size() - 1, clause); + return arrayList; + } + + public CriterionCompounder and(CriterionCompounder compounder) { + return and(compounder.getResult()); + } + + public CriterionCompounder and(ICriterion criterion) { + return new CriterionCompounder(updateLast(getLast().and(criterion))); + } + + public CriterionCompounder or(CriterionCompounder compounder) { + return or(compounder.getResult()); + } + + public CriterionCompounder or(ICriterion criterion) { + ArrayList copied = new ArrayList(clauses); + copied.add(new AndClause()); + return new CriterionCompounder(copied).and(criterion); + } + + public ICriterion getResult() { + return new OrClause(clauses); + } + +} 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 new file mode 100644 index 000000000..3c6ed492b --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java @@ -0,0 +1,82 @@ +package org.navalplanner.business.resources.entities; + +import java.util.Date; + +import org.apache.commons.lang.Validate; + +/** + * Declares a interval of time in which the criterion is satisfied
+ * @author Óscar González Fernández + */ +public class CriterionSatisfaction { + + private Long id; + + @SuppressWarnings("unused") + private long version; + + /** + * Required by hibernate. Do not use directly + */ + public CriterionSatisfaction() { + + } + + public CriterionSatisfaction(Date startDate, Criterion criterion, + Resource resource) { + Validate.notNull(startDate, "startDate must be not null"); + Validate.notNull(criterion, "criterion must be not null"); + Validate.notNull(resource, "resource must be not null"); + this.startDate = startDate; + this.criterion = criterion; + this.resource = resource; + this.resource.add(this); + } + + public Long getId() { + return id; + } + + private Date startDate; + + private Date finishDate; + + private Criterion criterion; + + private Resource resource; + + public Date getStartDate() { + return new Date(startDate.getTime()); + } + + public Date getEndDate() { + return new Date(finishDate.getTime()); + } + + public Criterion getCriterion() { + return criterion; + } + + public Resource getResource() { + return resource; + } + + public boolean isActiveNow() { + return startDate.before(new Date()) && finishDate == null; + } + + public boolean isActiveIn(Date start, Date end) { + return startDate.before(start) + && (finishDate == null || end.before(finishDate)); + } + + public void finish(Date finish) { + Validate.notNull(finish); + Validate.isTrue(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 new file mode 100644 index 000000000..4f56e8c2c --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java @@ -0,0 +1,29 @@ +package org.navalplanner.business.resources.entities; + +/** + * Base implementation of {@link ICriterionType}
+ * @author Óscar González Fernández + */ +public abstract class CriterionTypeBase implements ICriterionType { + + private final boolean allowHierarchy; + + private final boolean allowMultipleValuesPerResource; + + protected CriterionTypeBase(boolean allowHierarchy, + boolean allowMultipleValuesPerResource) { + this.allowHierarchy = allowHierarchy; + this.allowMultipleValuesPerResource = allowMultipleValuesPerResource; + } + + @Override + public boolean allowHierarchy() { + return allowHierarchy; + } + + @Override + public boolean allowMultipleActiveCriterionsPerResource() { + return allowMultipleValuesPerResource; + } + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterion.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterion.java new file mode 100644 index 000000000..c6d953557 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterion.java @@ -0,0 +1,17 @@ +package org.navalplanner.business.resources.entities; + +import java.util.Date; + +/** + * Responsible of searching the resources satisfiying some condition or set of + * conditions.
+ * Created at May 12, 2009 + * @author Óscar González Fernández + */ +public interface ICriterion { + + boolean isSatisfiedBy(Resource resource); + + boolean isSatisfiedBy(Resource resource, Date start, Date end); + +} 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 new file mode 100644 index 000000000..5e623817f --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java @@ -0,0 +1,17 @@ +package org.navalplanner.business.resources.entities; + +/** + * Parametrizes the behaviour of some criterions
+ * @author Óscar González Fernández + */ +public interface ICriterionType { + + public boolean allowMultipleActiveCriterionsPerResource(); + + public boolean allowHierarchy(); + + public ICriterion createCriterion(); + + public boolean contains(ICriterion criterion); + +} 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 e9243f74f..9c6be64e0 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,5 +1,13 @@ package org.navalplanner.business.resources.entities; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang.Validate; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.daos.ResourcesDaoRegistry; @@ -22,6 +30,8 @@ public abstract class Resource { @SuppressWarnings("unused") private long version; + private Set criterionSatisfactions = new HashSet(); + public Long getId() { return id; } @@ -43,4 +53,87 @@ public abstract class Resource { } } + public Set getAllSatisfactions() { + return Collections.unmodifiableSet(criterionSatisfactions); + } + + public Collection getSatisfactionsFor( + ICriterionType type) { + Set allSatisfactions = getAllSatisfactions(); + ArrayList result = new ArrayList(); + for (CriterionSatisfaction criterionSatisfaction : allSatisfactions) { + if (type.contains(criterionSatisfaction.getCriterion())) { + result.add(criterionSatisfaction); + } + } + return result; + } + + public Collection getActiveSatisfactionsFor( + ICriterionType criterionType) { + Collection satisfactionsFor = getSatisfactionsFor(criterionType); + ArrayList result = new ArrayList(); + for (CriterionSatisfaction criterionSatisfaction : satisfactionsFor) { + if (criterionSatisfaction.isActiveNow()) { + result.add(criterionSatisfaction); + } + } + return result; + } + + public Collection getActiveSatisfactionsForIn( + ICriterionType criterionType, Date start, Date end) { + Validate.notNull(criterionType); + Validate.isTrue(start.before(end)); + Collection satisfactionsFor = getSatisfactionsFor(criterionType); + ArrayList result = new ArrayList(); + for (CriterionSatisfaction criterionSatisfaction : satisfactionsFor) { + if (criterionSatisfaction.isActiveIn(start, end)) { + result.add(criterionSatisfaction); + } + } + return result; + } + + public Collection getActiveSatisfactionsFor( + ICriterion criterion) { + Set result = new HashSet(); + for (CriterionSatisfaction criterionSatisfaction : getAllSatisfactionsFor(criterion)) { + if (criterionSatisfaction.isActiveNow()) { + result.add(criterionSatisfaction); + } + } + return result; + } + + private Collection getAllSatisfactionsFor( + ICriterion criterion) { + Set result = new HashSet(); + for (CriterionSatisfaction satisfaction : criterionSatisfactions) { + if (satisfaction.getCriterion().equals(criterion)) { + result.add(satisfaction); + } + } + return result; + } + + public Collection getActiveSatisfactionsForIn( + ICriterion criterion, Date start, Date end) { + Validate.isTrue(start.before(end)); + ArrayList result = new ArrayList(); + Collection allSatisfactionsFor = getAllSatisfactionsFor(criterion); + for (CriterionSatisfaction criterionSatisfaction : allSatisfactionsFor) { + if (criterionSatisfaction.isActiveIn(start, end)) { + result.add(criterionSatisfaction); + } + } + return result; + } + + void add(CriterionSatisfaction criterionSatisfaction) { + Validate.notNull(criterionSatisfaction, + "criterionSatisfaction must be not null"); + criterionSatisfactions.add(criterionSatisfaction); + } + } 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 new file mode 100644 index 000000000..a0079b4d7 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java @@ -0,0 +1,45 @@ +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.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionSatisfaction; +import org.navalplanner.business.resources.entities.ICriterion; +import org.navalplanner.business.resources.entities.ICriterionType; +import org.navalplanner.business.resources.entities.Resource; + +/** + * Services for aggregate {@link Criterion}
+ * @author Óscar González Fernández + */ +public interface CriterionService { + + boolean exists(Long id); + + Criterion find(Long id) throws InstanceNotFoundException; + + List list(); + + void remove(Criterion criterion) throws InstanceNotFoundException; + + void remove(Long id) throws InstanceNotFoundException; + + void save(Criterion entity); + + void add(CriterionSatisfaction criterionSatisfaction); + + Collection getResourcesSatisfying(ICriterion criterion); + + Collection getResourcesSatisfying(ICriterion criterion, + Date begin, Date end); + + Collection getSatisfactionsFor( + ICriterionType criterionType); + + Collection getSatisfactionsFor( + ICriterionType criterionType, Date begin, Date end); + +} 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 1af8811a7..c060d53d1 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 @@ -1,8 +1,10 @@ package org.navalplanner.business.resources.services; import java.util.List; +import java.util.Set; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.resources.entities.ICriterion; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; @@ -34,4 +36,7 @@ public interface ResourceService { public List getWorkers(); + public List getResources(); + + 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 new file mode 100644 index 000000000..23c7fc47a --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java @@ -0,0 +1,113 @@ +package org.navalplanner.business.resources.services.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +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; +import org.navalplanner.business.resources.entities.ICriterionType; +import org.navalplanner.business.resources.entities.Resource; +import org.navalplanner.business.resources.services.CriterionService; +import org.navalplanner.business.resources.services.ResourceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +/** + * Implementation of {@link CriterionService} using {@link CriterionDAO}
+ * @author Óscar González Fernández + */ +@Transactional +public class CriterionServiceImpl implements CriterionService { + + @Autowired + private CriterionDAO criterionDAO; + + @Autowired + private CriterionSatisfactionDAO criterionSatisfactionDAO; + + @Autowired + private ResourceService resourceService; + + public boolean exists(Long id) { + return criterionDAO.exists(id); + } + + public Criterion find(Long id) throws InstanceNotFoundException { + return criterionDAO.find(id); + } + + public List list() { + return criterionDAO.list(Criterion.class); + } + + public void remove(Criterion criterion) throws InstanceNotFoundException { + criterionDAO.remove(criterion.getId()); + } + + public void remove(Long id) throws InstanceNotFoundException { + criterionDAO.remove(id); + } + + public void save(Criterion entity) { + criterionDAO.save(entity); + } + + @Override + public void add(CriterionSatisfaction criterionSatisfaction) { + criterionSatisfactionDAO.save(criterionSatisfaction); + } + + @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.getActiveSatisfactionsFor(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.getActiveSatisfactionsForIn(criterionType, + start, end)); + } + return result; + } +} 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 6cc399cbd..e25820040 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 @@ -1,9 +1,12 @@ package org.navalplanner.business.resources.services.impl; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.daos.IResourceDao; +import org.navalplanner.business.resources.entities.ICriterion; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.resources.services.ResourceService; @@ -51,4 +54,21 @@ public class ResourceServiceImpl implements ResourceService { public List getWorkers() { return resourceDao.list(Worker.class); } + + @Override + public Set getSetOfResourcesSatisfying(ICriterion criterion) { + List resources = resourceDao.list(Resource.class); + HashSet result = new HashSet(); + for (Resource resource : resources) { + if (criterion.isSatisfiedBy(resource)) { + result.add(resource); + } + } + return result; + } + + @Override + public List getResources() { + return resourceDao.list(Resource.class); + } } diff --git a/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml b/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml index 72dd606ee..49e28f4bd 100644 --- a/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml +++ b/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml @@ -25,7 +25,6 @@ - @@ -57,6 +56,11 @@ + + + + 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 aa34c6ff9..36ad692de 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 @@ -1,34 +1,43 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 000000000..ae7a3379a --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionDAOTest.java @@ -0,0 +1,77 @@ +package org.navalplanner.business.test.resources.daos; + +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.resources.daos.ICriterionDAO; +import org.navalplanner.business.resources.entities.Criterion; +import org.springframework.beans.factory.annotation.Autowired; +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.assertFalse; +import static junit.framework.Assert.assertNotNull; +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; + +/** + * Test cases for CriterionDAO
+ * Created at May 13, 2009 + * @author Óscar González Fernández + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, + BUSINESS_SPRING_CONFIG_TEST_FILE }) +@Transactional +public class CriterionDAOTest { + + @Autowired + private ICriterionDAO criterionDAO; + + @Test + public void testInSpringContainer() { + assertNotNull(criterionDAO); + } + + @Test + public void testSaveCriterions() throws Exception { + Criterion criterion = createValidCriterion(); + criterionDAO.save(criterion); + assertNotNull(criterion.getId()); + assertTrue(criterionDAO.exists(criterion.getId())); + } + + public static Criterion createValidCriterion() { + return new Criterion(); + } + + @Test(expected = InstanceNotFoundException.class) + public void testRemoveNotExistent() throws InstanceNotFoundException { + criterionDAO.remove(Long.MAX_VALUE); + } + + @Test + public void testRemove() throws InstanceNotFoundException { + Criterion criterion = createValidCriterion(); + criterionDAO.save(criterion); + assertTrue(criterionDAO.exists(criterion.getId())); + criterionDAO.remove(criterion.getId()); + assertFalse(criterionDAO.exists(criterion.getId())); + } + + @Test + public void testList() { + int previous = criterionDAO.list(Criterion.class).size(); + Criterion criterion1 = createValidCriterion(); + Criterion criterion2 = createValidCriterion(); + criterionDAO.save(criterion1); + criterionDAO.save(criterion2); + List list = criterionDAO.list(Criterion.class); + assertEquals(previous + 2, list.size()); + } +} diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionSatisfactionDAOTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionSatisfactionDAOTest.java new file mode 100644 index 000000000..e6cd638f7 --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/daos/CriterionSatisfactionDAOTest.java @@ -0,0 +1,100 @@ +package org.navalplanner.business.test.resources.daos; + +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.resources.daos.ICriterionDAO; +import org.navalplanner.business.resources.daos.ICriterionSatisfactionDAO; +import org.navalplanner.business.resources.daos.impl.WorkerDaoHibernate; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionSatisfaction; +import org.navalplanner.business.resources.entities.Worker; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +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.assertFalse; +import static junit.framework.Assert.assertNotNull; +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; + +/** + * Description goes here.
+ * @author Óscar González Fernández + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, + BUSINESS_SPRING_CONFIG_TEST_FILE }) +@Transactional +public class CriterionSatisfactionDAOTest { + + @Autowired + private ICriterionSatisfactionDAO satisfactionDAO; + + @Autowired + private ICriterionDAO criterionDAO; + + @Autowired + private WorkerDaoHibernate workerDAO; + + @Test + public void testSaveCriterions() throws Exception { + CriterionSatisfaction criterionSatisfaction = createValidCriterionSatisfaction(2007); + satisfactionDAO.save(criterionSatisfaction); + assertNotNull(criterionSatisfaction.getId()); + assertTrue(satisfactionDAO.exists(criterionSatisfaction.getId())); + } + + private CriterionSatisfaction createValidCriterionSatisfaction(int year) { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + criterionDAO.save(criterion); + Worker worker = new Worker("firstname", "surname", "nif", 4); + workerDAO.save(worker); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + year(year), criterion, worker); + return criterionSatisfaction; + } + + @Test(expected = DataIntegrityViolationException.class) + public void testNotSaveWithTransientCriterionAndWorker() { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstname", "surname", "nif", 4); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + year(2007), criterion, worker); + satisfactionDAO.save(criterionSatisfaction); + } + + public static Date year(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + return calendar.getTime(); + } + + @Test + public void testRemove() throws InstanceNotFoundException { + CriterionSatisfaction satisfaction = createValidCriterionSatisfaction(2008); + satisfactionDAO.save(satisfaction); + assertTrue(satisfactionDAO.exists(satisfaction.getId())); + satisfactionDAO.remove(satisfaction.getId()); + assertFalse(criterionDAO.exists(satisfaction.getId())); + } + + @Test + public void testList() { + int previous = satisfactionDAO.list(CriterionSatisfaction.class).size(); + CriterionSatisfaction satisfaction1 = createValidCriterionSatisfaction(2007); + CriterionSatisfaction satisfaction2 = createValidCriterionSatisfaction(2008); + satisfactionDAO.save(satisfaction1); + satisfactionDAO.save(satisfaction2); + assertEquals(previous + 2, satisfactionDAO.list( + CriterionSatisfaction.class).size()); + } +} 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 new file mode 100644 index 000000000..b1cbb16cd --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionSatisfactionTest.java @@ -0,0 +1,45 @@ +package org.navalplanner.business.test.resources.entities; + +import java.util.Date; + +import org.junit.Test; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionSatisfaction; +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.junit.Assert.assertTrue; + +/** + * Tests for {@link CriterionSatisfaction}
+ * @author Óscar González Fernández + */ +public class CriterionSatisfactionTest { + + @Test + public void testFinish() { + final Criterion criterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(2000), criterion, worker); + Date end = CriterionSatisfactionDAOTest.year(2006); + criterionSatisfaction.finish(end); + assertTrue(criterionSatisfaction.isFinished()); + assertEquals(end, criterionSatisfaction.getEndDate()); + criterionSatisfaction.getEndDate().setTime(end.getTime() + 2000); + assertEquals("endDate must be well encapsulated", end, + criterionSatisfaction.getEndDate()); + } + + @Test(expected = IllegalArgumentException.class) + public void testCantFinishBeforeStart() { + final Criterion criterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(2000), criterion, worker); + criterionSatisfaction.finish(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 new file mode 100644 index 000000000..a9afd9f30 --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/CriterionTest.java @@ -0,0 +1,139 @@ +package org.navalplanner.business.test.resources.entities; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; + +import org.junit.Test; +import org.navalplanner.business.resources.entities.CriterionCompounder; +import org.navalplanner.business.resources.entities.ICriterion; +import org.navalplanner.business.resources.entities.Resource; +import org.navalplanner.business.resources.entities.Worker; + +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; + +/** + * Tests for criterion.
+ * Created at May 12, 2009 + * @author Óscar González Fernández + */ +public class CriterionTest { + + @Test + public void testCompounding() throws Exception { + Worker worker1 = new Worker(); + Worker worker2 = new Worker(); + + ICriterion criterionForWorker1 = justThisResourcesCriterion(worker1); + ICriterion criterionForWorker2 = justThisResourcesCriterion(worker2); + ICriterion criterionForWorkers1And2 = justThisResourcesCriterion( + worker1, worker2); + + assertTrue(criterionForWorker1.isSatisfiedBy(worker1)); + assertTrue(criterionForWorker2.isSatisfiedBy(worker2)); + assertFalse(criterionForWorker2.isSatisfiedBy(worker1)); + assertTrue(criterionForWorkers1And2.isSatisfiedBy(worker1)); + assertTrue(criterionForWorkers1And2.isSatisfiedBy(worker2)); + + ICriterion compositedCriterion = CriterionCompounder.atom(criterionForWorker1) + .and(criterionForWorkers1And2).getResult(); + ICriterion matchesNoneComposited = CriterionCompounder.build().and( + criterionForWorker1).and(criterionForWorker2).getResult(); + + assertFalse(matchesNoneComposited.isSatisfiedBy(worker2)); + assertFalse(matchesNoneComposited.isSatisfiedBy(worker1)); + + assertTrue(compositedCriterion.isSatisfiedBy(worker1)); + assertFalse(compositedCriterion.isSatisfiedBy(worker2)); + } + + @Test + public void testEmptyMatchesAll() throws Exception { + assertTrue(build().getResult().isSatisfiedBy(new Worker())); + } + + @Test + public void testSimpleNegation() throws Exception { + Worker worker1 = new Worker(); + Worker worker2 = new Worker(); + Worker worker3 = new Worker(); + ICriterion criterionForWorker1 = justThisResourcesCriterion(worker1); + ICriterion criterionForWorker2 = justThisResourcesCriterion(worker2); + ICriterion worker1Negated = not(criterionForWorker1); + ICriterion compound = build().and(criterionForWorker1).and( + not(criterionForWorker2)).getResult(); + assertFalse(worker1Negated.isSatisfiedBy(worker1)); + assertTrue(worker1Negated.isSatisfiedBy(worker2)); + assertFalse(compound.isSatisfiedBy(worker2)); + assertTrue(compound.isSatisfiedBy(worker1)); + assertFalse(compound.isSatisfiedBy(worker3)); + } + + @Test + public void testNegateAnd() throws Exception { + Worker worker1 = new Worker(); + Worker worker2 = new Worker(); + Worker worker3 = new Worker(); + ICriterion criterionForWorker1 = justThisResourcesCriterion(worker1); + ICriterion both = justThisResourcesCriterion(worker1, worker2); + ICriterion andNegated = not(atom(criterionForWorker1).and(both)); + assertTrue(andNegated.isSatisfiedBy(worker2)); + assertTrue(andNegated.isSatisfiedBy(worker3)); + assertFalse(andNegated.isSatisfiedBy(worker1)); + } + + @Test + public void testOr() throws Exception { + Worker worker1 = new Worker(); + Worker worker2 = new Worker(); + Worker worker3 = new Worker(); + ICriterion both = justThisResourcesCriterion(worker1, worker2); + assertFalse(both.isSatisfiedBy(worker3)); + + ICriterion all = atom(both).or(justThisResourcesCriterion(worker3)) + .getResult(); + + assertTrue(all.isSatisfiedBy(worker1)); + assertTrue(all.isSatisfiedBy(worker2)); + assertTrue(all.isSatisfiedBy(worker3)); + } + + @Test + public void testOrHasLessPrecendenceThanAnd() throws Exception { + Worker worker1 = new Worker(); + Worker worker2 = new Worker(); + Worker worker3 = new Worker(); + ICriterion criterionForWorker1 = justThisResourcesCriterion(worker1); + ICriterion both = justThisResourcesCriterion(worker1, worker2); + + ICriterion or = atom(criterionForWorker1).and(both).or( + justThisResourcesCriterion(worker3)).getResult(); + + assertTrue(or.isSatisfiedBy(worker1)); + assertFalse(or.isSatisfiedBy(worker2)); + assertTrue("or has less priority", or.isSatisfiedBy(worker3)); + } + + public static ICriterion justThisResourcesCriterion( + final Resource... resources) { + final HashSet set = new HashSet(Arrays + .asList(resources)); + return new ICriterion() { + + @Override + public boolean isSatisfiedBy(Resource resource) { + return set.contains(resource); + } + + @Override + public boolean isSatisfiedBy(Resource resource, Date start, Date end) { + return isSatisfiedBy(resource); + } + }; + } + +} 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 new file mode 100644 index 000000000..ab5825117 --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java @@ -0,0 +1,136 @@ +package org.navalplanner.business.test.resources.entities; + +import java.util.Arrays; +import java.util.HashSet; + +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.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.test.resources.daos.CriterionDAOTest; +import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest; + +import static junit.framework.Assert.assertEquals; + +/** + * Tests for {@link Resource}.
+ * @author Óscar González Fernández + */ +public class ResourceTest { + + @Test + public void testRelationResourceWithCriterionSatisfaction() + throws Exception { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + 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()); + } + + @Test(expected = IllegalArgumentException.class) + public void getSatisfactionsForWrongIntervalThrowsException() { + Worker worker = new Worker("firstName", "surName", "2333232", 10); + worker.getActiveSatisfactionsForIn(CriterionDAOTest + .createValidCriterion(), CriterionSatisfactionDAOTest + .year(2000), CriterionSatisfactionDAOTest.year(1999)); + } + + @Test(expected = IllegalArgumentException.class) + public void getSatisfactionsForWrongIntervalForCriterionTypeThrowsException() { + Worker worker = new Worker("firstName", "surName", "2333232", 10); + worker.getActiveSatisfactionsForIn(createTypeThatMatches(), + CriterionSatisfactionDAOTest.year(2000), + 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); + assertEquals(2, worker.getSatisfactionsFor(criterionType).size()); + assertEquals(1, worker.getActiveSatisfactionsFor(criterionType).size()); + } + + public static CriterionTypeBase createTypeThatMatches( + final Criterion... criterions) { + final HashSet criterionsSet = new HashSet(Arrays + .asList(criterions)); + return new CriterionTypeBase(true, true) { + + @Override + public boolean contains(ICriterion c) { + return criterionsSet.contains(c); + } + + @Override + public ICriterion createCriterion() { + return null; + } + }; + } + + @Test + 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); + + assertEquals(2, worker.getSatisfactionsFor(criterionType).size()); + assertEquals(1, worker.getActiveSatisfactionsForIn(criterionType, + CriterionSatisfactionDAOTest.year(2001), + CriterionSatisfactionDAOTest.year(2005)).size()); + assertEquals(2, worker.getActiveSatisfactionsForIn(criterionType, + CriterionSatisfactionDAOTest.year(2004), + CriterionSatisfactionDAOTest.year(2005)).size()); + assertEquals(0, worker.getActiveSatisfactionsForIn(criterionType, + CriterionSatisfactionDAOTest.year(1999), + CriterionSatisfactionDAOTest.year(2005)).size()); + } + +} 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 new file mode 100644 index 000000000..c952bf762 --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java @@ -0,0 +1,178 @@ +package org.navalplanner.business.test.resources.services; + +import org.hibernate.SessionFactory; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionSatisfaction; +import org.navalplanner.business.resources.entities.ICriterionType; +import org.navalplanner.business.resources.entities.Worker; +import org.navalplanner.business.resources.services.CriterionService; +import org.navalplanner.business.resources.services.ResourceService; +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.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import static junit.framework.Assert.assertEquals; +import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; +import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; + +/** + * Test cases for {@link CriterionService}
+ * @author Óscar González Fernández + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, + BUSINESS_SPRING_CONFIG_TEST_FILE }) +@Transactional +public class CriterionServiceTest { + + @Autowired + private CriterionService criterionService; + + @Autowired + private ResourceService resourceService; + + @Autowired + private SessionFactory sessionFactory; + + @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 resource that doesn't exist yet + */ + @Test(expected = DataIntegrityViolationException.class) + public void testCreateCriterionSatisfactionOnTransientCriterion() + throws Exception { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + resourceService.saveResource(worker); + + criterionService.add(new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(2000), criterion, worker)); + } + + @Test(expected = DataIntegrityViolationException.class) + public void testCreateCriterionSatisfactionOnTransientResource() + throws Exception { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + 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); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(2000), criterion, worker); + 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()); + } + + @Test + public void testGetSetOfResourcesSatisfyingCriterion() throws Exception { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + 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); + assertEquals(1, criterionService.getResourcesSatisfying(criterion) + .size()); + } + + @Test(expected = IllegalArgumentException.class) + public void mustBeCorrectInterval() { + 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); + Worker worker = new Worker("firstName", "surName", "2333232", 10); + resourceService.saveResource(worker); + CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(2000), criterion, worker); + + criterionService.add(criterionSatisfaction); + + assertEquals(1, criterionService.getResourcesSatisfying(criterion, + CriterionSatisfactionDAOTest.year(2001), + CriterionSatisfactionDAOTest.year(2005)).size()); + assertEquals(0, criterionService.getResourcesSatisfying(criterion, + CriterionSatisfactionDAOTest.year(1999), + CriterionSatisfactionDAOTest.year(2005)).size()); + + CriterionSatisfaction otherSatisfaction = new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(1998), criterion, worker); + criterionService.add(otherSatisfaction); + + assertEquals(1, criterionService.getResourcesSatisfying(criterion, + CriterionSatisfactionDAOTest.year(1999), + CriterionSatisfactionDAOTest.year(2005)).size()); + } + + @Test + public void testSearchResourcesForCriterionType() throws Exception { + Criterion criterion = CriterionDAOTest.createValidCriterion(); + 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)); + + 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()); + + criterionService.add(new CriterionSatisfaction( + CriterionSatisfactionDAOTest.year(1997), criterion, worker)); + assertEquals(2, criterionService.getSatisfactionsFor(criterionType, + CriterionSatisfactionDAOTest.year(1999), + CriterionSatisfactionDAOTest.year(2005)).size()); + + } + +} 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 4a069103e..7b781b9d5 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 @@ -8,9 +8,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.daos.IResourceDao; +import org.navalplanner.business.resources.entities.ICriterion; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.resources.services.ResourceService; +import org.navalplanner.business.test.resources.entities.CriterionTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.NotTransactional; import org.springframework.test.context.ContextConfiguration; @@ -105,4 +107,27 @@ public class ResourceServiceTest { } } + public void testResourcesSatisfying() { + Worker worker1 = new Worker("worker-1", "worker-2-surname", + "11111111A", 8); + Worker worker2 = new Worker("worker-2", "worker-3-surname", + "22222222B", 6); + resourceService.saveResource(worker1); + resourceService.saveResource(worker2); + ICriterion firstCriterion = CriterionTest + .justThisResourcesCriterion(worker1); + ICriterion secondCriterion = CriterionTest + .justThisResourcesCriterion(worker2); + ICriterion bothCriterion = CriterionTest.justThisResourcesCriterion( + worker1, worker2); + assertEquals(1, resourceService.getSetOfResourcesSatisfying( + firstCriterion).size()); + assertEquals(worker1, resourceService.getSetOfResourcesSatisfying( + firstCriterion).iterator().next()); + assertEquals(1, resourceService.getSetOfResourcesSatisfying( + secondCriterion).size()); + assertEquals(2, resourceService.getSetOfResourcesSatisfying( + bothCriterion).size()); + } + } diff --git a/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml b/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml index 05d325e3e..982dbcde8 100644 --- a/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml +++ b/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml @@ -1,36 +1,37 @@ - + - - - + p:driverClassName="${jdbcDriver.className}" p:url="${testDataSource.url}" + p:username="${testDataSource.user}" p:password="${testDataSource.password}" /> + + + - - + + - org/navalplanner/business/resources/entities/Resources.hbm.xml + + org/navalplanner/business/resources/entities/Resources.hbm.xml + - + - +