ItEr21S04ArquitecturaServidorItEr20S04: Removed use of CriterionService.

This commit is contained in:
Manuel Rego Casasnovas 2009-08-11 22:57:08 +02:00 committed by Óscar González Fernández
parent 449ff9cea3
commit 8d88d3da4e
16 changed files with 647 additions and 823 deletions

View file

@ -9,11 +9,10 @@ import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.services.ICriterionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@ -32,7 +31,7 @@ public class CriterionsBootstrap implements ICriterionsBootstrap {
private static final Log LOG = LogFactory.getLog(CriterionsBootstrap.class);
@Autowired
private ICriterionService criterionService;
private ICriterionDAO criterionDAO;
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@ -61,11 +60,14 @@ public class CriterionsBootstrap implements ICriterionsBootstrap {
private void ensureCriterionExists(String criterionName,
CriterionType criterionType) {
try {
Criterion criterion = new Criterion(criterionName, criterionType);
criterionService.createIfNotExists(criterion);
} catch (ValidationException e) {
throw new RuntimeException(e);
Criterion criterion = new Criterion(criterionName, criterionType);
if (!(criterionDAO.exists(criterion.getId()) || criterionDAO
.existsByNameAndType(criterion))) {
if (!(criterionTypeDAO.exists(criterion.getType().getId()) || criterionTypeDAO
.existsByName(criterion.getType()))) {
criterionTypeDAO.save(criterion.getType());
}
criterionDAO.save(criterion);
}
}

View file

@ -10,6 +10,7 @@ import org.hibernate.criterion.Restrictions;
import org.navalplanner.business.common.daos.GenericDAOHibernate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
@ -76,4 +77,17 @@ public class CriterionDAO extends GenericDAOHibernate<Criterion, Long>
throw new RuntimeException(ex);
}
}
@Override
public List<Criterion> findByType(ICriterionType<?> type) {
List<Criterion> list = list(Criterion.class);
ArrayList<Criterion> result = new ArrayList<Criterion>();
for (Criterion criterion : list) {
if (type.contains(criterion)) {
result.add(criterion);
}
}
return result;
}
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import org.navalplanner.business.common.daos.IGenericDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.ICriterionType;
/**
* Contract for {@link CriterionDAO} <br />
@ -22,4 +23,6 @@ public interface ICriterionDAO extends IGenericDAO<Criterion, Long> {
Criterion find(Criterion criterion) throws InstanceNotFoundException;
List<Criterion> findByType(ICriterionType<?> type);
}

View file

@ -1,248 +0,0 @@
package org.navalplanner.business.resources.services;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.hibernate.validator.InvalidValue;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.daos.CriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionSatisfaction;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionOnData;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Interval;
import org.navalplanner.business.resources.entities.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* Implementation of {@link ICriterionService} using {@link CriterionDAO} <br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Diego Pino García <dpino@igalia.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_SINGLETON)
@Transactional
public class CriterionServiceImpl implements ICriterionService {
@Autowired
private ICriterionDAO criterionDAO;
@Autowired
private IResourceService resourceService;
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
public boolean exists(Criterion criterion) {
return criterionDAO.exists(criterion.getId())
|| criterionDAO.existsByNameAndType(criterion);
}
public Criterion find(Criterion criterion) throws InstanceNotFoundException {
return criterionDAO.find(criterion);
}
public List<Criterion> list() {
return criterionDAO.list(Criterion.class);
}
public void remove(Criterion criterion) throws InstanceNotFoundException {
if (criterion.getId() != null) {
criterionDAO.remove(criterion.getId());
} else {
criterionDAO.removeByNameAndType(criterion);
}
}
@Transactional(rollbackFor = ValidationException.class)
@Override
public void save(Criterion entity) throws ValidationException {
// Save criterion.type if it's new
CriterionType criterionType = entity.getType();
if (criterionType.getId() == null) {
entity.setType(saveCriterionType(criterionType));
}
if (threIsOtherWithSameNameAndType(entity)) {
InvalidValue[] invalidValues = { new InvalidValue(entity.getName()
+ " already exists", Criterion.class, "name", entity
.getName(), entity) };
throw new ValidationException(invalidValues,
"Couldn't save new criterion");
}
criterionDAO.save(entity);
}
private boolean threIsOtherWithSameNameAndType(Criterion toSave) {
List<Criterion> withSameNameAndType = criterionDAO
.findByNameAndType(toSave);
if (withSameNameAndType.isEmpty())
return false;
if (withSameNameAndType.size() > 1)
return true;
return !areSameInDB(withSameNameAndType.get(0), toSave);
}
private boolean areSameInDB(Criterion existentCriterion, Criterion other) {
return existentCriterion.getId().equals(other.getId());
}
private CriterionType saveCriterionType(CriterionType criterionType)
throws ValidationException {
if (criterionTypeDAO.exists(criterionType.getId())
|| criterionTypeDAO.existsByName(criterionType)) {
try {
criterionType = criterionTypeDAO.findUniqueByName(criterionType
.getName());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
} else {
criterionTypeDAO.save(criterionType);
}
return criterionType;
}
@Override
public Collection<Resource> getResourcesSatisfying(ICriterion criterion) {
List<Resource> resources = resourceService.getResources();
ArrayList<Resource> result = new ArrayList<Resource>();
for (Resource resource : resources) {
if (criterion.isSatisfiedBy(resource)) {
result.add(resource);
}
}
return result;
}
@Override
public Collection<Resource> getResourcesSatisfying(ICriterion criterion,
Date start, Date end) {
Validate.isTrue(start.before(end), "start must be before than end");
List<Resource> resources = resourceService.getResources();
ArrayList<Resource> result = new ArrayList<Resource>();
for (Resource resource : resources) {
if (criterion.isSatisfiedBy(resource, start, end)) {
result.add(resource);
}
}
return result;
}
@Override
public Collection<CriterionSatisfaction> getSatisfactionsFor(
ICriterionType<?> criterionType) {
ArrayList<CriterionSatisfaction> result = new ArrayList<CriterionSatisfaction>();
for (Resource resource : resourceService.getResources()) {
result.addAll(resource.getCurrentSatisfactionsFor(criterionType));
}
return result;
}
@Override
public Collection<CriterionSatisfaction> getSatisfactionsFor(
ICriterionType<?> criterionType, Date start, Date end) {
ArrayList<CriterionSatisfaction> result = new ArrayList<CriterionSatisfaction>();
for (Resource resource : resourceService.getResources()) {
result.addAll(resource.query().from(criterionType).enforcedInAll(
Interval.range(start, end)).result());
}
return result;
}
@Override
public void createIfNotExists(Criterion criterion)
throws ValidationException {
if (!exists(criterion))
save(criterion);
}
@Override
public ICriterionOnData empower(final ICriterion criterion) {
final ICriterionService criterionService = getProxifiedCriterionService();
return new ICriterionOnData() {
@Override
public boolean isSatisfiedBy(Resource resource) {
return criterion.isSatisfiedBy(resource);
}
@Override
public boolean isSatisfiedBy(Resource resource, Date start, Date end) {
return criterion.isSatisfiedBy(resource, start, end);
}
@Override
public Collection<Resource> getResourcesSatisfying() {
return criterionService.getResourcesSatisfying(criterion);
}
@Override
public Collection<Resource> getResourcesSatisfying(Date start,
Date end) throws IllegalArgumentException {
return criterionService.getResourcesSatisfying(criterion,
start, end);
}
};
}
@Autowired
private ApplicationContext applicationContext;
// this is a hack to avoid using the this variable in empower method. The
// this instance is not proxified because spring uses an transparent proxy,
// so it doesn't open the transacion
private ICriterionService getProxifiedCriterionService() {
return (ICriterionService) applicationContext.getBeansOfType(
ICriterionService.class).values().iterator().next();
}
@Override
public Collection<Criterion> getCriterionsFor(ICriterionType<?> type) {
List<Criterion> list = criterionDAO.list(Criterion.class);
ArrayList<Criterion> result = new ArrayList<Criterion>();
for (Criterion criterion : list) {
if (type.contains(criterion)) {
result.add(criterion);
}
}
return result;
}
@Override
public <T extends Resource> List<T> getResourcesSatisfying(
Class<T> resourceType, Criterion criterion) {
Validate.notNull(resourceType, "resourceType must be not null");
Validate.notNull(criterion, "criterion must be not null");
List<T> result = new ArrayList<T>();
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);
}
}
}

View file

@ -1,59 +0,0 @@
package org.navalplanner.business.resources.services;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionSatisfaction;
import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionOnData;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Resource;
/**
* Services for {@link Criterion} <br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public interface ICriterionService {
List<Criterion> list();
void remove(Criterion criterion) throws InstanceNotFoundException;
/**
* Save or update criterion
*
* "name" and "type" fields must be both unique
*
* @param entity
*/
void save(Criterion entity) throws ValidationException;
Collection<Resource> getResourcesSatisfying(ICriterion criterion);
Collection<Resource> getResourcesSatisfying(ICriterion criterion,
Date begin, Date end);
Collection<CriterionSatisfaction> getSatisfactionsFor(
ICriterionType<?> criterionType);
Collection<CriterionSatisfaction> getSatisfactionsFor(
ICriterionType<?> criterionType, Date begin, Date end);
void createIfNotExists(Criterion criterion) throws ValidationException;
boolean exists(Criterion criterion);
ICriterionOnData empower(ICriterion criterion);
Collection<Criterion> getCriterionsFor(ICriterionType<?> type);
<T extends Resource> List<T> getResourcesSatisfying(Class<T> resourceType,
Criterion criterion);
Criterion load(Criterion criterion);
}

View file

@ -7,8 +7,9 @@ import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.resources.bootstrap.ICriterionsBootstrap;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.WorkingRelationship;
import org.navalplanner.business.resources.services.ICriterionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -24,21 +25,37 @@ public class CriterionsBootstrapTest {
private ICriterionsBootstrap criterionsBootstrap;
@Autowired
private ICriterionService criterionService;
private ICriterionDAO criterionDAO;
@Test
public void testBootstrap() throws Exception {
if (criterionService.exists(WorkingRelationship.FIRED.criterion())) {
criterionService.remove(WorkingRelationship.FIRED.criterion());
Criterion criterion = WorkingRelationship.FIRED.criterion();
if (criterionDAO.exists(criterion.getId())
|| criterionDAO.existsByNameAndType(criterion)) {
if (criterion.getId() != null) {
criterionDAO.remove(criterion.getId());
} else {
criterionDAO.removeByNameAndType(criterion);
}
}
if (criterionService.exists(WorkingRelationship.HIRED.criterion())) {
criterionService.remove(WorkingRelationship.HIRED.criterion());
criterion = WorkingRelationship.HIRED.criterion();
if (criterionDAO.exists(criterion.getId())
|| criterionDAO.existsByNameAndType(criterion)) {
if (criterion.getId() != null) {
criterionDAO.remove(criterion.getId());
} else {
criterionDAO.removeByNameAndType(criterion);
}
}
criterionsBootstrap.loadRequiredData();
assertTrue(criterionService.exists(WorkingRelationship.FIRED
.criterion()));
assertTrue(criterionService.exists(WorkingRelationship.HIRED
.criterion()));
criterion = WorkingRelationship.FIRED.criterion();
assertTrue(criterionDAO.exists(criterion.getId())
|| criterionDAO.existsByNameAndType(criterion));
criterion = WorkingRelationship.HIRED.criterion();
assertTrue(criterionDAO.exists(criterion.getId())
|| criterionDAO.existsByNameAndType(criterion));
}
}

View file

@ -7,6 +7,7 @@ import static junit.framework.Assert.assertTrue;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
@ -18,10 +19,12 @@ import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.navalplanner.business.resources.entities.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.annotation.NotTransactional;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@ -116,4 +119,83 @@ public class CriterionDAOTest {
criterionDAO.save(criterion2);
criterionDAO.flush();
}
@Test
public void testCriterionsForType() throws Exception {
final Criterion one = CriterionDAOTest.createValidCriterion();
Criterion other = CriterionDAOTest.createValidCriterion();
save(one);
save(other);
ICriterionType<Criterion> type = createTypeThatMatches(one);
Collection<Criterion> criterions = criterionDAO.findByType(type);
assertEquals(1, criterions.size());
assertTrue(criterions.contains(one));
}
private void save(Criterion criterion) {
if (!(criterionTypeDAO.exists(criterion.getType().getId()) || criterionTypeDAO
.existsByName(criterion.getType()))) {
criterionTypeDAO.save(criterion.getType());
}
criterionDAO.save(criterion);
}
public static ICriterionType<Criterion> createTypeThatMatches(
final Criterion criterion) {
return createTypeThatMatches(false, criterion);
}
public static ICriterionType<Criterion> createTypeThatMatches(
final boolean allowSimultaneousCriterionsPerResource,
final Criterion criterion) {
return new ICriterionType<Criterion>() {
@Override
public boolean allowSimultaneousCriterionsPerResource() {
return allowSimultaneousCriterionsPerResource;
}
@Override
public boolean allowHierarchy() {
return false;
}
@Override
public boolean contains(ICriterion c) {
return criterion.isEquivalent(c);
}
@Override
public Criterion createCriterion(String name) {
return null;
}
@Override
public String getName() {
return null;
}
@Override
public boolean allowAdding() {
return false;
}
@Override
public boolean allowEditing() {
return false;
}
@Override
public boolean criterionCanBeRelatedTo(
Class<? extends Resource> klass) {
return true;
}
@Override
public Criterion createCriterionWithoutNameYet() {
return null;
}
};
}
}

View file

@ -1,453 +0,0 @@
package org.navalplanner.business.test.resources.services;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
import java.util.Collection;
import java.util.UUID;
import org.hibernate.SessionFactory;
import org.hibernate.validator.InvalidStateException;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionSatisfaction;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionOnData;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Interval;
import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.ICriterionService;
import org.navalplanner.business.resources.services.IResourceService;
import org.navalplanner.business.test.resources.daos.CriterionDAOTest;
import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest;
import org.navalplanner.business.test.resources.entities.ResourceTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.annotation.NotTransactional;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* Test cases for {@link ICriterionService} <br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
BUSINESS_SPRING_CONFIG_TEST_FILE })
@Transactional
public class CriterionServiceTest {
@Autowired
private ICriterionService criterionService;
@Autowired
IAdHocTransactionService adHocTransactionService;
@Autowired
private IResourceService resourceService;
@Autowired
private SessionFactory sessionFactory;
@Test(expected = InvalidStateException.class)
public void testCantSaveCriterionWithoutNameAndType() throws Exception {
Criterion criterion = CriterionDAOTest.createValidCriterion("valido");
criterion.setName("");
criterionService.save(criterion);
sessionFactory.getCurrentSession().flush();
}
@Test
public void testAddCriterion() throws Exception {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionService.save(criterion);
}
@Test
@NotTransactional
public void testEditingCriterion() throws Exception {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
int initial = criterionService.getCriterionsFor(
PredefinedCriterionTypes.WORK_RELATIONSHIP).size();
criterionService.save(criterion);
assertThat("after saving one more", criterionService.getCriterionsFor(
PredefinedCriterionTypes.WORK_RELATIONSHIP).size(),
equalTo(initial + 1));
criterion.setActive(false);
String newName = UUID.randomUUID().toString() + "random";
criterion.setName(newName);
criterionService.save(criterion);
assertThat("after editing there are the same", criterionService
.getCriterionsFor(PredefinedCriterionTypes.WORK_RELATIONSHIP)
.size(), equalTo(initial + 1));
Criterion retrieved = criterionService.load(criterion);
assertThat(retrieved.getName(), equalTo(newName));
criterionService.remove(criterion);
}
@Test
public void testSaveSameCriterionTwice() throws ValidationException {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionService.save(criterion);
criterionService.save(criterion);
}
@Test
public void testCreateIfNotExists() throws ValidationException {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionService.createIfNotExists(criterion);
assertTrue(criterionService.exists(criterion));
criterionService
.createIfNotExists(PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique));
}
@Test(expected = ValidationException.class)
@NotTransactional
public void twoDifferentCriterionsWithSameNameAndTypeAreDetectedIfPossible()
throws ValidationException {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionService.save(criterion);
Criterion criterion2 = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionService.save(criterion2);
}
@Test(expected = DataIntegrityViolationException.class)
public void testCreateCriterionSatisfactionOnTransientCriterion()
throws Exception {
Criterion criterion = CriterionDAOTest.createValidCriterion();
ICriterionType<?> type = createTypeThatMatches(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
worker.addSatisfaction(new CriterionWithItsType(type, criterion));
assertTrue(criterion.isSatisfiedBy(worker));
resourceService.saveResource(worker);
assertTrue(criterion.isSatisfiedBy(worker));
assertThat(criterionService.getResourcesSatisfying(criterion).size(),
equalTo(1));
}
@NotTransactional
@Test
public void testInNoTransaction() throws Exception {
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
ICriterionType<?> type = createTypeThatMatches(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
worker.addSatisfaction(new CriterionWithItsType(type, criterion));
assertTrue(criterion.isSatisfiedBy(worker));
resourceService.saveResource(worker);
assertTrue(criterion.isSatisfiedBy(worker));
assertThat(criterionService.getResourcesSatisfying(criterion).size(),
equalTo(1));
}
public void testCreateCriterionSatisfactionOnTransientResource()
throws Exception {
Criterion criterion = CriterionDAOTest.createValidCriterion();
ICriterionType<?> type = createTypeThatMatches(criterion);
criterionService.save(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
worker.addSatisfaction(new CriterionWithItsType(type, criterion));
resourceService.saveResource(worker);
assertThat(criterionService.getResourcesSatisfying(criterion).size(),
equalTo(1));
assertThat((Worker) criterionService.getResourcesSatisfying(criterion)
.iterator().next(), equalTo(worker));
}
@Test
public void testGetSetOfResourcesSatisfyingCriterion() throws Exception {
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
ICriterionType<?> type = createTypeThatMatches(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
resourceService.saveResource(worker);
worker.addSatisfaction(new CriterionWithItsType(type, criterion));
assertEquals(1, criterionService.getResourcesSatisfying(criterion)
.size());
}
public static class Prueba extends Resource {
@Override
public int getDailyCapacity() {
return 0;
}
@Override
public String getDescription() {
return "";
}
}
@Test
public void testGetSetOfResourcesSubclassSatisfyingCriterion()
throws ValidationException {
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
ICriterionType<Criterion> type = createTypeThatMatches(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
resourceService.saveResource(worker);
worker.addSatisfaction(new CriterionWithItsType(type, criterion));
assertThat(criterionService.getResourcesSatisfying(Resource.class,
criterion).size(), is(1));
assertThat(criterionService.getResourcesSatisfying(Worker.class,
criterion).size(), is(1));
assertThat(criterionService.getResourcesSatisfying(Prueba.class,
criterion).size(), is(0));
}
@Test
public void shouldLetCreateCriterionOnData() throws ValidationException {
Criterion criterion = CriterionDAOTest.createValidCriterion();
ICriterionType<?> type = createTypeThatMatches(criterion);
criterionService.save(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
resourceService.saveResource(worker);
worker.addSatisfaction(new CriterionWithItsType(type, criterion),
Interval.from(CriterionSatisfactionDAOTest.year(2000)));
ICriterionOnData criterionOnData = criterionService.empower(criterion);
assertTrue(criterionOnData.isSatisfiedBy(worker));
assertEquals(1, criterionOnData.getResourcesSatisfying().size());
assertTrue(criterionOnData.getResourcesSatisfying().contains(worker));
assertTrue(criterionOnData.getResourcesSatisfying(
CriterionSatisfactionDAOTest.year(1990),
CriterionSatisfactionDAOTest.year(2005)).isEmpty());
assertEquals(1, criterionOnData.getResourcesSatisfying(
CriterionSatisfactionDAOTest.year(2001),
CriterionSatisfactionDAOTest.year(2005)).size());
}
@Test
@NotTransactional
public void testCriterionIsEquivalentOnDetachedAndProxifiedCriterion()
throws Exception {
final Worker worker1 = new Worker("worker-1", "worker-2-surname",
"11111111A", 8);
resourceService.saveResource(worker1);
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
createTypeThatMatches(criterion);
worker1.addSatisfaction(new CriterionWithItsType(criterion.getType(),
criterion));
resourceService.saveResource(worker1);
Resource workerReloaded = adHocTransactionService
.onTransaction(new IOnTransaction<Resource>() {
@Override
public Resource execute() {
try {
Resource result = resourceService
.findResource(worker1.getId());
forceLoadSatisfactions(result);
return result;
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
}
});
Collection<CriterionSatisfaction> satisfactionsFor = workerReloaded
.getSatisfactionsFor(criterion.getType());
Criterion reloadedCriterion = satisfactionsFor.iterator().next()
.getCriterion();
Assume.assumeTrue(!reloadedCriterion.getClass().equals(
criterion.getClass()));
assertTrue(reloadedCriterion.isEquivalent(criterion));
}
private void forceLoadSatisfactions(Resource resource) {
for (CriterionSatisfaction criterionSatisfaction : resource
.getAllSatisfactions()) {
criterionSatisfaction.getCriterion().getName();
criterionSatisfaction.getCriterion().getType().getName();
}
}
@Test
@NotTransactional
public void shouldntThrowExceptionDueToTransparentProxyGotcha()
throws ValidationException {
Criterion criterion = CriterionDAOTest.createValidCriterion();
ICriterionType<Criterion> type = createTypeThatMatches(criterion);
criterionService.save(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
resourceService.saveResource(worker);
worker.addSatisfaction(new CriterionWithItsType(type, criterion),
Interval.from(CriterionSatisfactionDAOTest.year(2000)));
ICriterionOnData criterionOnData = criterionService.empower(criterion);
criterionOnData.getResourcesSatisfying();
criterionOnData.getResourcesSatisfying(CriterionSatisfactionDAOTest
.year(2001), CriterionSatisfactionDAOTest.year(2005));
}
@Test(expected = IllegalArgumentException.class)
public void mustBeCorrectInterval() throws ValidationException {
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
criterionService.getResourcesSatisfying(criterion,
CriterionSatisfactionDAOTest.year(2005),
CriterionSatisfactionDAOTest.year(2003));
}
@Test
public void testSearchInInterval() throws Exception {
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
ICriterionType<Criterion> type = createTypeThatMatches(true, criterion);
CriterionWithItsType criterionWithItsType = new CriterionWithItsType(
type, criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
resourceService.saveResource(worker);
worker.addSatisfaction(criterionWithItsType, Interval
.from(CriterionSatisfactionDAOTest.year(2000)));
assertEquals(1, criterionService.getResourcesSatisfying(criterion,
CriterionSatisfactionDAOTest.year(2001),
CriterionSatisfactionDAOTest.year(2005)).size());
assertEquals(0, criterionService.getResourcesSatisfying(criterion,
CriterionSatisfactionDAOTest.year(1999),
CriterionSatisfactionDAOTest.year(2005)).size());
worker.addSatisfaction(new CriterionWithItsType(type, criterion),
Interval.from(CriterionSatisfactionDAOTest.year(1998)));
assertEquals(1, criterionService.getResourcesSatisfying(criterion,
CriterionSatisfactionDAOTest.year(1999),
CriterionSatisfactionDAOTest.year(2005)).size());
}
@Test
public void testSearchResourcesForCriterionType() throws Exception {
Criterion criterion = CriterionDAOTest.createValidCriterion();
ICriterionType<Criterion> type = createTypeThatMatches(true, criterion);
CriterionWithItsType criterionWithItsType = new CriterionWithItsType(
type, criterion);
criterionService.save(criterion);
Worker worker = new Worker("firstName", "surName", "2333232", 10);
resourceService.saveResource(worker);
worker.addSatisfaction(criterionWithItsType, Interval
.from(CriterionSatisfactionDAOTest.year(2000)));
worker.addSatisfaction(criterionWithItsType, Interval
.from(CriterionSatisfactionDAOTest.year(1998)));
ICriterionType<?> criterionType = ResourceTest
.createTypeThatMatches(criterion);
assertEquals(2, criterionService.getSatisfactionsFor(criterionType,
CriterionSatisfactionDAOTest.year(2001),
CriterionSatisfactionDAOTest.year(2005)).size());
assertEquals(1, criterionService.getSatisfactionsFor(criterionType,
CriterionSatisfactionDAOTest.year(1999),
CriterionSatisfactionDAOTest.year(2005)).size());
assertEquals(0, criterionService.getSatisfactionsFor(criterionType,
CriterionSatisfactionDAOTest.year(1997),
CriterionSatisfactionDAOTest.year(2005)).size());
worker.addSatisfaction(criterionWithItsType, Interval
.from(CriterionSatisfactionDAOTest.year(1997)));
assertEquals(2, criterionService.getSatisfactionsFor(criterionType,
CriterionSatisfactionDAOTest.year(1999),
CriterionSatisfactionDAOTest.year(2005)).size());
}
@Test
public void testCriterionsForType() throws Exception {
final Criterion one = CriterionDAOTest.createValidCriterion();
Criterion other = CriterionDAOTest.createValidCriterion();
criterionService.save(one);
criterionService.save(other);
ICriterionType<Criterion> type = createTypeThatMatches(one);
Collection<Criterion> criterions = criterionService
.getCriterionsFor(type);
assertEquals(1, criterions.size());
assertTrue(criterions.contains(one));
}
public static ICriterionType<Criterion> createTypeThatMatches(
final Criterion criterion) {
return createTypeThatMatches(false, criterion);
}
public static ICriterionType<Criterion> createTypeThatMatches(
final boolean allowSimultaneousCriterionsPerResource,
final Criterion criterion) {
return new ICriterionType<Criterion>() {
@Override
public boolean allowSimultaneousCriterionsPerResource() {
return allowSimultaneousCriterionsPerResource;
}
@Override
public boolean allowHierarchy() {
return false;
}
@Override
public boolean contains(ICriterion c) {
return criterion.isEquivalent(c);
}
@Override
public Criterion createCriterion(String name) {
return null;
}
@Override
public String getName() {
return null;
}
@Override
public boolean allowAdding() {
return false;
}
@Override
public boolean allowEditing() {
return false;
}
@Override
public boolean criterionCanBeRelatedTo(
Class<? extends Resource> klass) {
return true;
}
@Override
public Criterion createCriterionWithoutNameYet() {
return null;
}
};
}
}

View file

@ -15,7 +15,11 @@ import org.hibernate.validator.InvalidStateException;
import org.hibernate.validator.InvalidValue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.daos.IResourceDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
@ -23,7 +27,6 @@ import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.ICriterionService;
import org.navalplanner.business.resources.services.IResourceService;
import org.navalplanner.business.test.resources.daos.CriterionDAOTest;
import org.navalplanner.business.test.resources.entities.CriterionTest;
@ -51,7 +54,13 @@ public class ResourceServiceTest {
private IResourceDAO resourceDao;
@Autowired
private ICriterionService criterionService;
private ICriterionDAO criterionDAO;
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@Autowired
private IAdHocTransactionService adHocTransactionService;
@Test
public void testRemoveResource() throws InstanceNotFoundException {
@ -134,15 +143,85 @@ public class ResourceServiceTest {
"11111111A", 8);
resourceService.saveResource(worker1);
long versionValueAfterSave = worker1.getVersion();
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
ICriterionType<Criterion> type = CriterionServiceTest
.createTypeThatMatches(criterion);
final Criterion criterion = CriterionDAOTest.createValidCriterion();
adHocTransactionService.onTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
if (!(criterionTypeDAO.exists(criterion.getType().getId()) || criterionTypeDAO
.existsByName(criterion.getType()))) {
criterionTypeDAO.save(criterion.getType());
}
criterionDAO.save(criterion);
return null;
}
});
ICriterionType<Criterion> type = createTypeThatMatches(criterion);
worker1.addSatisfaction(new CriterionWithItsType(type, criterion));
resourceService.saveResource(worker1);
assertThat(worker1.getVersion(), not(equalTo(versionValueAfterSave)));
}
private static ICriterionType<Criterion> createTypeThatMatches(
final Criterion criterion) {
return createTypeThatMatches(false, criterion);
}
private static ICriterionType<Criterion> createTypeThatMatches(
final boolean allowSimultaneousCriterionsPerResource,
final Criterion criterion) {
return new ICriterionType<Criterion>() {
@Override
public boolean allowSimultaneousCriterionsPerResource() {
return allowSimultaneousCriterionsPerResource;
}
@Override
public boolean allowHierarchy() {
return false;
}
@Override
public boolean contains(ICriterion c) {
return criterion.isEquivalent(c);
}
@Override
public Criterion createCriterion(String name) {
return null;
}
@Override
public String getName() {
return null;
}
@Override
public boolean allowAdding() {
return false;
}
@Override
public boolean allowEditing() {
return false;
}
@Override
public boolean criterionCanBeRelatedTo(
Class<? extends Resource> klass) {
return true;
}
@Override
public Criterion createCriterionWithoutNameYet() {
return null;
}
};
}
public void testResourcesSatisfying() {
Worker worker1 = new Worker("worker-1", "worker-2-surname",
"11111111A", 8);

View file

@ -26,7 +26,6 @@ import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.services.ICriterionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
@ -43,9 +42,6 @@ import org.springframework.transaction.annotation.Transactional;
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class OrderModel implements IOrderModel {
@Autowired
ICriterionService criterionService;
@Autowired
ICriterionTypeDAO criterionTypeDAO;
@ -82,7 +78,8 @@ public class OrderModel implements IOrderModel {
.getCriterionTypes();
for (CriterionType criterionType : criterionTypes) {
List<Criterion> criterions = new ArrayList<Criterion>(
criterionService.getCriterionsFor(criterionType));
criterionDAO
.findByType(criterionType));
mapCriterions.put(criterionType, criterions);
}

View file

@ -11,6 +11,7 @@ import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
@ -18,7 +19,6 @@ import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.ICriterionService;
import org.navalplanner.business.resources.services.IResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@ -40,10 +40,10 @@ public class CriterionsModel implements ICriterionsModel {
Criterion.class);
@Autowired
private ICriterionService criterionService;
private ICriterionDAO criterionDAO;
@Autowired
private ICriterionTypeDAO criterionDAO;
private ICriterionTypeDAO criterionTypeDAO;
@Autowired
private IResourceService resourceService;
@ -55,13 +55,13 @@ public class CriterionsModel implements ICriterionsModel {
@Override
@Transactional(readOnly = true)
public List<CriterionType> getTypes() {
return criterionDAO.getCriterionTypes();
return criterionTypeDAO.getCriterionTypes();
}
@Override
@Transactional(readOnly = true)
public Collection<Criterion> getCriterionsFor(ICriterionType<?> type) {
return criterionService.getCriterionsFor(type);
return criterionDAO.findByType(type);
}
@Override
@ -95,6 +95,7 @@ public class CriterionsModel implements ICriterionsModel {
}
@Override
@Transactional
public void saveCriterion() throws ValidationException {
InvalidValue[] invalidValues = criterionValidator
.getInvalidValues(criterion);
@ -102,7 +103,7 @@ public class CriterionsModel implements ICriterionsModel {
throw new ValidationException(invalidValues);
try {
criterionService.save(criterion);
save(criterion);
} catch (ValidationException ve) {
throw ve;
} finally {
@ -111,6 +112,55 @@ public class CriterionsModel implements ICriterionsModel {
}
}
@Override
@Transactional
public void save(Criterion entity) throws ValidationException {
// Save criterion.type if it's new
CriterionType criterionType = entity.getType();
if (criterionType.getId() == null) {
entity.setType(saveCriterionType(criterionType));
}
if (threIsOtherWithSameNameAndType(entity)) {
InvalidValue[] invalidValues = { new InvalidValue(entity.getName()
+ " already exists", Criterion.class, "name", entity
.getName(), entity) };
throw new ValidationException(invalidValues,
"Couldn't save new criterion");
}
criterionDAO.save(entity);
}
private boolean threIsOtherWithSameNameAndType(Criterion toSave) {
List<Criterion> withSameNameAndType = criterionDAO
.findByNameAndType(toSave);
if (withSameNameAndType.isEmpty())
return false;
if (withSameNameAndType.size() > 1)
return true;
return !areSameInDB(withSameNameAndType.get(0), toSave);
}
private boolean areSameInDB(Criterion existentCriterion, Criterion other) {
return existentCriterion.getId().equals(other.getId());
}
private CriterionType saveCriterionType(CriterionType criterionType)
throws ValidationException {
if (criterionTypeDAO.exists(criterionType.getId())
|| criterionTypeDAO.existsByName(criterionType)) {
try {
criterionType = criterionTypeDAO.findUniqueByName(criterionType
.getName());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
} else {
criterionTypeDAO.save(criterionType);
}
return criterionType;
}
@Override
public boolean isEditing() {
return criterion != null;
@ -124,11 +174,25 @@ public class CriterionsModel implements ICriterionsModel {
}
@Override
@Transactional(readOnly = true)
public <T extends Resource> List<T> getResourcesSatisfyingCurrentCriterionOfType(
Class<T> klass) {
if (criterion == null)
return new ArrayList<T>();
return criterionService.getResourcesSatisfying(klass, criterion);
return getResourcesSatisfying(klass, criterion);
}
private <T extends Resource> List<T> getResourcesSatisfying(
Class<T> resourceType, Criterion criterion) {
Validate.notNull(resourceType, "resourceType must be not null");
Validate.notNull(criterion, "criterion must be not null");
List<T> result = new ArrayList<T>();
for (T r : resourceService.getResources(resourceType)) {
if (criterion.isSatisfiedBy(r)) {
result.add(r);
}
}
return result;
}
@Override

View file

@ -45,4 +45,6 @@ public interface ICriterionsModel {
void deactivateAll(Collection<? extends Resource> unSelectedWorkers);
void save(Criterion criterion) throws ValidationException;
}

View file

@ -15,6 +15,7 @@ import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionSatisfaction;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
@ -23,7 +24,6 @@ import org.navalplanner.business.resources.entities.Interval;
import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.ICriterionService;
import org.navalplanner.business.resources.services.IResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@ -46,18 +46,18 @@ public class WorkerModel implements IWorkerModel {
PredefinedCriterionTypes.WORK_RELATIONSHIP };
private Worker worker;
private ClassValidator<Worker> workerValidator;
private final ICriterionService criterionService;
private final ICriterionDAO criterionDAO;
private IMultipleCriterionActiveAssigner localizationsAssigner;
@Autowired
public WorkerModel(IResourceService resourceService,
ICriterionService criterionService) {
ICriterionDAO criterionDAO) {
Validate.notNull(resourceService);
Validate.notNull(criterionService);
Validate.notNull(criterionDAO);
this.resourceService = resourceService;
this.workerValidator = new ClassValidator<Worker>(Worker.class);
this.criterionService = criterionService;
this.criterionDAO = criterionDAO;
}
@Override
@ -90,7 +90,7 @@ public class WorkerModel implements IWorkerModel {
public void prepareForCreate() {
worker = new Worker();
localizationsAssigner = new MultipleCriterionActiveAssigner(
criterionService, worker,
criterionDAO, worker,
PredefinedCriterionTypes.LOCATION_GROUP);
}
@ -102,7 +102,7 @@ public class WorkerModel implements IWorkerModel {
this.worker = (Worker) resourceService.findResource(worker.getId());
forceLoadSatisfactions(this.worker);
localizationsAssigner = new MultipleCriterionActiveAssigner(
criterionService, this.worker,
criterionDAO, this.worker,
PredefinedCriterionTypes.LOCATION_GROUP);
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
@ -232,7 +232,7 @@ public class WorkerModel implements IWorkerModel {
IMultipleCriterionActiveAssigner {
private final Resource resource;
private final ICriterionType<?> type;
private final ICriterionService criterionService;
private final ICriterionDAO criterionDAO;
private List<CriterionSatisfaction> history;
private List<Criterion> initialCriterionsNotAssigned;
private Set<CriterionSatisfaction> initialActive;
@ -242,13 +242,14 @@ public class WorkerModel implements IWorkerModel {
private Set<CriterionSatisfaction> added = new HashSet<CriterionSatisfaction>();
public MultipleCriterionActiveAssigner(
ICriterionService criterionService, Resource resource,
ICriterionDAO criterionDAO,
Resource resource,
ICriterionType<?> type) {
Validate
.isTrue(
type.allowSimultaneousCriterionsPerResource(),
"must allow multiple active criterions for this type to use this assignment strategy");
this.criterionService = criterionService;
this.criterionDAO = criterionDAO;
this.resource = resource;
this.type = type;
forceLoadSatisfactions(this.resource);
@ -282,8 +283,8 @@ public class WorkerModel implements IWorkerModel {
}
private List<Criterion> calculateInitialCriterionsNotAssigned() {
Map<Long, Criterion> allCriterions = byId(criterionService
.getCriterionsFor(type));
Map<Long, Criterion> allCriterions = byId(criterionDAO
.findByType(type));
for (Long activeId : asIds(resource.getCurrentCriterionsFor(type))) {
allCriterions.remove(activeId);
}
@ -374,7 +375,7 @@ public class WorkerModel implements IWorkerModel {
public Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions() {
Map<ICriterionType<?>, Collection<Criterion>> result = new HashMap<ICriterionType<?>, Collection<Criterion>>();
for (ICriterionType<?> type : laboralRelatedTypes) {
result.put(type, criterionService.getCriterionsFor(type));
result.put(type, criterionDAO.findByType(type));
}
return result;
}

View file

@ -37,7 +37,7 @@ import org.navalplanner.business.planner.entities.TaskElement;
import org.navalplanner.business.planner.entities.TaskGroup;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.services.ICriterionService;
import org.navalplanner.web.resources.criterion.ICriterionsModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.NotTransactional;
import org.springframework.test.context.ContextConfiguration;
@ -77,9 +77,6 @@ public class OrderModelTest {
@Autowired
private IOrderModel orderModel;
@Autowired
private ICriterionService criterionService;
@Autowired
private IOrderDAO orderDAO;
@ -89,6 +86,9 @@ public class OrderModelTest {
@Autowired
private IAdHocTransactionService adHocTransaction;
@Autowired
private ICriterionsModel criterionModel;
private Session getSession() {
return sessionFactory.getCurrentSession();
}
@ -304,7 +304,7 @@ public class OrderModelTest {
CriterionType criterionType = new CriterionType("test");
Criterion criterion = new Criterion("Test" + UUID.randomUUID(),
criterionType);
criterionService.save(criterion);
criterionModel.save(criterion);
hoursGroup.addCriterion(criterion);
hoursGroup2.addCriterion(criterion);

View file

@ -0,0 +1,323 @@
package org.navalplanner.web.resources;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE;
import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE;
import java.util.Collection;
import java.util.UUID;
import org.hibernate.SessionFactory;
import org.hibernate.validator.InvalidStateException;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionSatisfaction;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.IResourceService;
import org.navalplanner.web.resources.criterion.CriterionsModel;
import org.navalplanner.web.resources.criterion.ICriterionsModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.NotTransactional;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* Tests for {@link CriterionsModel}. <br />
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE })
@Transactional
public class CriterionModelTest {
@Autowired
private ICriterionsModel criterionModel;
@Autowired
private SessionFactory sessionFactory;
@Autowired
private IAdHocTransactionService adHocTransactionService;
@Autowired
private ICriterionDAO criterionDAO;
@Autowired
private IResourceService resourceService;
@Test(expected = InvalidStateException.class)
public void testCantSaveCriterionWithoutNameAndType() throws Exception {
Criterion criterion = createValidCriterion("valido");
criterion.setName("");
criterionModel.save(criterion);
sessionFactory.getCurrentSession().flush();
}
public static Criterion createValidCriterion() {
return createValidCriterion(UUID.randomUUID().toString());
}
public static Criterion createValidCriterion(String name) {
CriterionType criterionType = createValidCriterionType();
return Criterion.withNameAndType(name, criterionType);
}
public static CriterionType createValidCriterionType(String name) {
return new CriterionType(name);
}
public static CriterionType createValidCriterionType() {
String unique = UUID.randomUUID().toString();
return createValidCriterionType(unique);
}
@Test
public void testAddCriterion() throws Exception {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionModel.save(criterion);
}
@Test
@NotTransactional
public void testEditingCriterion() throws Exception {
String unique = UUID.randomUUID().toString();
final Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
int initial = getCriterionsNumber(PredefinedCriterionTypes.WORK_RELATIONSHIP);
criterionModel.save(criterion);
assertThat(
"after saving one more",
getCriterionsNumber(PredefinedCriterionTypes.WORK_RELATIONSHIP),
equalTo(initial + 1));
criterion.setActive(false);
String newName = UUID.randomUUID().toString() + "random";
criterion.setName(newName);
criterionModel.save(criterion);
assertThat(
"after editing there are the same",
getCriterionsNumber(PredefinedCriterionTypes.WORK_RELATIONSHIP),
equalTo(initial + 1));
Criterion retrieved = adHocTransactionService
.onTransaction(new IOnTransaction<Criterion>() {
@Override
public Criterion execute() {
try {
return criterionDAO.find(criterion);
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
}
});
assertThat(retrieved.getName(), equalTo(newName));
adHocTransactionService.onTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
if (criterion.getId() != null) {
try {
criterionDAO.remove(criterion.getId());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
} else {
criterionDAO.removeByNameAndType(criterion);
}
return null;
}
});
}
private int getCriterionsNumber(final ICriterionType<?> type) {
int size = adHocTransactionService
.onTransaction(new IOnTransaction<Integer>() {
@Override
public Integer execute() {
return criterionDAO.findByType(type).size();
}
});
return size;
}
@Test
public void testSaveSameCriterionTwice() throws ValidationException {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionModel.save(criterion);
criterionModel.save(criterion);
}
@Test
public void testCreateIfNotExists() throws ValidationException {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
if (!(criterionDAO.exists(criterion.getId()) || criterionDAO
.existsByNameAndType(criterion)))
criterionModel.save(criterion);
assertTrue(criterionDAO.exists(criterion.getId())
|| criterionDAO.existsByNameAndType(criterion));
if (!(criterionDAO.exists(criterion.getId()) || criterionDAO
.existsByNameAndType(criterion)))
criterionModel.save(PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique));
}
@Test(expected = ValidationException.class)
@NotTransactional
public void twoDifferentCriterionsWithSameNameAndTypeAreDetectedIfPossible()
throws ValidationException {
String unique = UUID.randomUUID().toString();
Criterion criterion = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionModel.save(criterion);
Criterion criterion2 = PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(unique);
criterionModel.save(criterion2);
}
public static class ResourceTest extends Resource {
@Override
public int getDailyCapacity() {
return 0;
}
@Override
public String getDescription() {
return "";
}
}
@Test
@NotTransactional
public void testCriterionIsEquivalentOnDetachedAndProxifiedCriterion()
throws Exception {
final Worker worker1 = new Worker("worker-1", "worker-2-surname",
"11111111A", 8);
resourceService.saveResource(worker1);
Criterion criterion = createValidCriterion();
criterionModel.save(criterion);
createTypeThatMatches(criterion);
worker1.addSatisfaction(new CriterionWithItsType(criterion.getType(),
criterion));
resourceService.saveResource(worker1);
Resource workerReloaded = adHocTransactionService
.onTransaction(new IOnTransaction<Resource>() {
@Override
public Resource execute() {
try {
Resource result = resourceService
.findResource(worker1.getId());
forceLoadSatisfactions(result);
return result;
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
}
});
Collection<CriterionSatisfaction> satisfactionsFor = workerReloaded
.getSatisfactionsFor(criterion.getType());
Criterion reloadedCriterion = satisfactionsFor.iterator().next()
.getCriterion();
Assume.assumeTrue(!reloadedCriterion.getClass().equals(
criterion.getClass()));
assertTrue(reloadedCriterion.isEquivalent(criterion));
}
private void forceLoadSatisfactions(Resource resource) {
for (CriterionSatisfaction criterionSatisfaction : resource
.getAllSatisfactions()) {
criterionSatisfaction.getCriterion().getName();
criterionSatisfaction.getCriterion().getType().getName();
}
}
private static ICriterionType<Criterion> createTypeThatMatches(
final Criterion criterion) {
return createTypeThatMatches(false, criterion);
}
private static ICriterionType<Criterion> createTypeThatMatches(
final boolean allowSimultaneousCriterionsPerResource,
final Criterion criterion) {
return new ICriterionType<Criterion>() {
@Override
public boolean allowSimultaneousCriterionsPerResource() {
return allowSimultaneousCriterionsPerResource;
}
@Override
public boolean allowHierarchy() {
return false;
}
@Override
public boolean contains(ICriterion c) {
return criterion.isEquivalent(c);
}
@Override
public Criterion createCriterion(String name) {
return null;
}
@Override
public String getName() {
return null;
}
@Override
public boolean allowAdding() {
return false;
}
@Override
public boolean allowEditing() {
return false;
}
@Override
public boolean criterionCanBeRelatedTo(
Class<? extends Resource> klass) {
return true;
}
@Override
public Criterion createCriterionWithoutNameYet() {
return null;
}
};
}
}

View file

@ -5,15 +5,15 @@ import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.ICriterionService;
import org.navalplanner.business.resources.services.IResourceService;
import org.navalplanner.web.resources.worker.WorkerModel;
@ -27,17 +27,17 @@ public class WorkerModelTest {
public void testWorkerValid() throws ValidationException,
InstanceNotFoundException {
IResourceService resourceServiceMock = createMock(IResourceService.class);
ICriterionService criterionServiceMock = createMock(ICriterionService.class);
ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class);
Worker workerToReturn = new Worker();
workerToReturn.setDailyHours(2);
workerToReturn.setFirstName("firstName");
workerToReturn.setSurname("surname");
workerToReturn.setNif("232344243");
// expectations
Collection<Criterion> criterions = new ArrayList<Criterion>();
List<Criterion> criterions = new ArrayList<Criterion>();
expect(
criterionServiceMock
.getCriterionsFor(PredefinedCriterionTypes.LOCATION_GROUP))
.findByType(PredefinedCriterionTypes.LOCATION_GROUP))
.andReturn(criterions).anyTimes();
expect(resourceServiceMock.findResource(workerToReturn.getId()))
.andReturn(workerToReturn);
@ -55,13 +55,13 @@ public class WorkerModelTest {
public void testWorkerInvalid() throws ValidationException,
InstanceNotFoundException {
IResourceService resourceServiceMock = createMock(IResourceService.class);
ICriterionService criterionServiceMock = createMock(ICriterionService.class);
ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class);
Worker workerToReturn = new Worker();
// expectations
Collection<Criterion> criterions = new ArrayList<Criterion>();
List<Criterion> criterions = new ArrayList<Criterion>();
expect(
criterionServiceMock
.getCriterionsFor(PredefinedCriterionTypes.LOCATION_GROUP))
.findByType(PredefinedCriterionTypes.LOCATION_GROUP))
.andReturn(criterions).anyTimes();
expect(resourceServiceMock.findResource(workerToReturn.getId()))
.andReturn(workerToReturn);