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
index c6d953557..663c5f2d1 100644
--- 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
@@ -3,9 +3,7 @@ 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
+ * It's a predicate that can be applied on resources
* @author Óscar González Fernández
*/
public interface ICriterion {
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionOnData.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionOnData.java
new file mode 100644
index 000000000..78652f1da
--- /dev/null
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionOnData.java
@@ -0,0 +1,18 @@
+package org.navalplanner.business.resources.entities;
+
+import java.util.Collection;
+import java.util.Date;
+
+/**
+ * Expands the capabilities of {@link ICriterion}. It also lets retrieve the
+ * resources satisfying the criterion
+ * @author Óscar González Fernández
+ */
+public interface ICriterionOnData extends ICriterion {
+
+ Collection getResourcesSatisfying();
+
+ Collection getResourcesSatisfying(Date start, Date end)
+ throws IllegalArgumentException;
+
+}
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 0b33c5dfb..16751ec4f 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
@@ -8,6 +8,7 @@ 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.ICriterionOnData;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Resource;
@@ -40,4 +41,6 @@ public interface CriterionService {
boolean exists(Criterion criterion);
+ ICriterionOnData empower(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 cec2a72d6..8e8c8ae2d 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
@@ -12,11 +12,13 @@ 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.ICriterionOnData;
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.context.ApplicationContext;
import org.springframework.transaction.annotation.Transactional;
/**
@@ -112,4 +114,43 @@ public class CriterionServiceImpl implements CriterionService {
if (!exists(criterion))
save(criterion);
}
+
+ @Override
+ public ICriterionOnData empower(final ICriterion criterion) {
+ final CriterionService criterionService = getProxifiedCriterionService();
+ return new ICriterionOnData() {
+ @Override
+ public boolean isSatisfiedBy(Resource resource) {
+ return criterion.isSatisfiedBy(resource);
+ }
+
+ @Override
+ public boolean isSatisfiedBy(Resource resource, Date start, Date end) {
+ return criterion.isSatisfiedBy(resource, start, end);
+ }
+
+ @Override
+ public Collection getResourcesSatisfying() {
+ return criterionService.getResourcesSatisfying(criterion);
+ }
+
+ @Override
+ public Collection getResourcesSatisfying(Date start,
+ Date end) throws IllegalArgumentException {
+ return criterionService.getResourcesSatisfying(criterion,
+ start, end);
+ }
+ };
+ }
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ // this is a hack to avoid using the this variable in empower method. The
+ // this instance is not proxified because spring uses an transparent proxy,
+ // so it doesn't open the transacion
+ private CriterionService getProxifiedCriterionService() {
+ return (CriterionService) applicationContext.getBeansOfType(
+ CriterionService.class).values().iterator().next();
+ }
}
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 e33b22932..836d59ca6 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
@@ -13,6 +13,7 @@ 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.ICriterionOnData;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.navalplanner.business.resources.entities.Worker;
@@ -23,6 +24,7 @@ import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTes
import org.navalplanner.business.test.resources.entities.ResourceTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.test.annotation.NotTransactional;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@@ -160,6 +162,44 @@ public class CriterionServiceTest {
.size());
}
+ @Test
+ public void shouldLetCreateCriterionOnData() {
+ 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);
+ ICriterionOnData criterionOnData = criterionService.empower(criterion);
+ assertTrue(criterionOnData.isSatisfiedBy(worker));
+ assertEquals(1, criterionOnData.getResourcesSatisfying().size());
+ assertTrue(criterionOnData.getResourcesSatisfying().contains(worker));
+ assertTrue(criterionOnData.getResourcesSatisfying(
+ CriterionSatisfactionDAOTest.year(1990),
+ CriterionSatisfactionDAOTest.year(2005)).isEmpty());
+ assertEquals(1, criterionOnData.getResourcesSatisfying(
+ CriterionSatisfactionDAOTest.year(2001),
+ CriterionSatisfactionDAOTest.year(2005)).size());
+ }
+
+ @Test
+ @NotTransactional
+ public void shouldntThrowExceptionDueToTransparentProxyGotcha() {
+ 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);
+ ICriterionOnData criterionOnData = criterionService.empower(criterion);
+ criterionOnData.getResourcesSatisfying();
+ criterionOnData.getResourcesSatisfying(
+ CriterionSatisfactionDAOTest.year(2001),
+ CriterionSatisfactionDAOTest.year(2005));
+ }
+
@Test(expected = IllegalArgumentException.class)
public void mustBeCorrectInterval() {
Criterion criterion = CriterionDAOTest.createValidCriterion();
@@ -225,7 +265,6 @@ public class CriterionServiceTest {
assertEquals(2, criterionService.getSatisfactionsFor(criterionType,
CriterionSatisfactionDAOTest.year(1999),
CriterionSatisfactionDAOTest.year(2005)).size());
-
}
}