ItEr16S10ClasificacionTraballoItEr15S13: Adds CriterionType entity

This commit is contained in:
Diego Pino Garcia 2009-07-06 20:01:01 +02:00 committed by Javier Moran Rua
parent f2fa4099bc
commit 6a7a8066b8
25 changed files with 835 additions and 142 deletions

View file

@ -5,11 +5,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.services.CriterionService;
import org.navalplanner.business.resources.services.CriterionTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@ -19,14 +23,20 @@ import org.springframework.transaction.annotation.Transactional;
* Loads all {@link ICriterionTypeProvider} and if there is any criterion that
* doesn't exist, creates them.<br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
@Component
@Scope("singleton")
public class CriterionsBootstrap implements ICriterionsBootstrap {
private static final Log LOG = LogFactory.getLog(CriterionsBootstrap.class);
@Autowired
private CriterionService criterionService;
@Autowired
private CriterionTypeService criterionTypeService;
@Autowired
private List<ICriterionTypeProvider> providers;
@ -44,12 +54,33 @@ public class CriterionsBootstrap implements ICriterionsBootstrap {
@Override
@Transactional
public void loadRequiredData() {
Map<ICriterionType<?>, List<Criterion>> typesWithCriterions = getTypesWithCriterions();
for (Entry<ICriterionType<?>, List<Criterion>> entry : typesWithCriterions
.entrySet()) {
for (Criterion criterion : entry.getValue()) {
LOG.debug("### loadRequiredData()");
Map<CriterionType, List<String>> typesWithCriterions = getTypesWithCriterions();
// Insert predefined criterions
for (Entry<CriterionType, List<String>> entry :
typesWithCriterions.entrySet()) {
// Create PredefinedCriterionType
CriterionType criterionType = entry.getKey();
try {
criterionTypeService.createIfNotExists(criterionType);
} catch (ValidationException e) {
}
// Retrieve existing criterionType if not exists
if (criterionType.getId() == null) {
criterionType = criterionTypeService.findUniqueByName(criterionType.getName());
}
// Create predefined criterions for criterionType
for (String criterionName : entry.getValue()) {
try {
Criterion criterion = new Criterion(criterionName, criterionType);
criterionService.createIfNotExists(criterion);
LOG.debug("### Create criterion: (" + criterionName +
"; " + criterionType.getName());
} catch (ValidationException e) {
e.printStackTrace();
}
@ -57,13 +88,13 @@ public class CriterionsBootstrap implements ICriterionsBootstrap {
}
}
private Map<ICriterionType<?>, List<Criterion>> getTypesWithCriterions() {
HashMap<ICriterionType<?>, List<Criterion>> result = new HashMap<ICriterionType<?>, List<Criterion>>();
private Map<CriterionType, List<String>> getTypesWithCriterions() {
HashMap<CriterionType, List<String>> result = new HashMap<CriterionType, List<String>>();
for (ICriterionTypeProvider provider : providers) {
for (Entry<ICriterionType<?>, List<Criterion>> entry : provider
for (Entry<CriterionType, List<String>> entry : provider
.getRequiredCriterions().entrySet()) {
if (!result.containsKey(entry.getKey())) {
result.put(entry.getKey(), new ArrayList<Criterion>());
result.put(entry.getKey(), new ArrayList<String>());
}
result.get(entry.getKey()).addAll(entry.getValue());
}

View file

@ -3,16 +3,17 @@ package org.navalplanner.business.resources.bootstrap;
import java.util.List;
import java.util.Map;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.ICriterionType;
/**
* Defines a class that can provide some known {@link ICriterionType} along with
* their associated Criterion <br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
public interface ICriterionTypeProvider {
public Map<ICriterionType<?>, List<Criterion>> getRequiredCriterions();
public Map<CriterionType, List<String>> getRequiredCriterions();
}

View file

@ -4,8 +4,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@ -14,6 +13,7 @@ import org.springframework.stereotype.Component;
* This class provides the CriterionTypes with their criterions that are known a
* priori<br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
@Component
@Scope("singleton")
@ -23,12 +23,11 @@ public class PredefinedCriterionTypesProvider implements ICriterionTypeProvider
}
@Override
public Map<ICriterionType<?>, List<Criterion>> getRequiredCriterions() {
Map<ICriterionType<?>, List<Criterion>> result = new HashMap<ICriterionType<?>, List<Criterion>>();
public Map<CriterionType, List<String>> getRequiredCriterions() {
Map<CriterionType, List<String>> result = new HashMap<CriterionType, List<String>>();
for (PredefinedCriterionTypes type : PredefinedCriterionTypes.values()) {
result.put(type, type.getPredefined());
result.put(CriterionType.asCriterionType(type), type.getPredefined());
}
return result;
}
}

View file

@ -0,0 +1,26 @@
package org.navalplanner.business.resources.daos;
import java.util.List;
import org.navalplanner.business.common.daos.IGenericDao;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.daos.impl.CriterionTypeDAO;
import org.navalplanner.business.resources.entities.CriterionType;
/**
* DAO for {@link CriterionTypeDAO} <br />
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public interface ICriterionTypeDAO extends IGenericDao<CriterionType, Long> {
CriterionType findUniqueByName(String name)
throws InstanceNotFoundException;
CriterionType findUniqueByName(CriterionType criterionType)
throws InstanceNotFoundException;
List<CriterionType> findByName(CriterionType criterionType);
public boolean existsByName(CriterionType criterionType);
public void removeByName(CriterionType criterionType);
}

View file

@ -1,9 +1,12 @@
package org.navalplanner.business.resources.daos.impl;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.navalplanner.business.common.daos.impl.GenericDaoHibernate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
@ -29,14 +32,14 @@ public class CriterionDAO extends GenericDaoHibernate<Criterion, Long>
@Override
public List<Criterion> findByNameAndType(Criterion criterion) {
if (criterion.getType() == null) return new ArrayList<Criterion>();
Criteria c = getSession().createCriteria(Criterion.class);
c.add(Restrictions.eq("name", criterion.getName()).ignoreCase())
.createCriteria("type")
.add(Restrictions.eq("name", criterion.getType().getName()).ignoreCase());
c.add(Restrictions.eq("name", criterion.getName()).ignoreCase());
c.add(Restrictions.eq("type", criterion.getType()).ignoreCase());
List result = (List<Criterion>) c.list();
return result;
return (List<Criterion>) c.list();
}
public Criterion findUniqueByNameAndType(Criterion criterion) throws InstanceNotFoundException {
@ -75,5 +78,4 @@ public class CriterionDAO extends GenericDaoHibernate<Criterion, Long>
throw new RuntimeException(ex);
}
}
}

View file

@ -0,0 +1,67 @@
package org.navalplanner.business.resources.daos.impl;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.navalplanner.business.common.daos.impl.GenericDaoHibernate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.CriterionType;
import org.springframework.stereotype.Component;
/**
* DAO implementation for Criterion. <br />
* @author Diego Pino Garcia <dpino@igalia.com>
*/
@Component
public class CriterionTypeDAO extends GenericDaoHibernate<CriterionType, Long>
implements ICriterionTypeDAO {
@Override
public List<CriterionType> findByName(CriterionType criterionType) {
Criteria c = getSession().createCriteria(CriterionType.class);
c.add(Restrictions.eq("name", criterionType.getName()).ignoreCase());
return (List<CriterionType>) c.list();
}
@Override
public CriterionType findUniqueByName(CriterionType criterionType)
throws InstanceNotFoundException {
Validate.notNull(criterionType);
return findUniqueByName(criterionType.getName());
}
@Override
public CriterionType findUniqueByName(String name)
throws InstanceNotFoundException {
Criteria c = getSession().createCriteria(CriterionType.class);
c.add(Restrictions.eq("name", name));
return (CriterionType) c.uniqueResult();
}
@Override
public boolean existsByName(CriterionType criterionType) {
try {
return findUniqueByName(criterionType) != null;
} catch (InstanceNotFoundException e) {
return false;
}
}
@Override
public void removeByName(CriterionType criterionType) {
try {
CriterionType reloaded = findUniqueByName(criterionType);
remove(reloaded.getId());
} catch (InstanceNotFoundException ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -6,6 +6,9 @@ import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.navalplanner.business.resources.services.CriterionTypeService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* A criterion stored in the database <br />
@ -21,19 +24,16 @@ public class Criterion implements ICriterion {
@NotEmpty
private String name;
@NotEmpty
private String type;
@NotNull
private CriterionType type;
private boolean active = true;
public static Criterion ofType(String type) {
Validate.notEmpty(type);
Criterion result = new Criterion();
result.type = type;
return result;
public static Criterion ofType(CriterionType type) {
return new Criterion(type);
}
public static Criterion withNameAndType(String name, String type) {
public static Criterion withNameAndType(String name, CriterionType type) {
return new Criterion(name, type);
}
@ -43,11 +43,18 @@ public class Criterion implements ICriterion {
public Criterion() {
}
private Criterion(String name, String type) {
Validate.notEmpty(name);
Validate.notEmpty(type);
public Criterion(CriterionType type) {
Validate.notNull(type);
this.type = type;
}
public Criterion(String name, CriterionType type) {
Validate.notEmpty(name);
Validate.notNull(type);
this.name = name;
this.type = type;
}
public Long getId() {
@ -59,6 +66,7 @@ public class Criterion implements ICriterion {
return !resource.getCurrentSatisfactionsFor(this).isEmpty();
}
@Override
public boolean isSatisfiedBy(Resource resource, Date start, Date end) {
return !resource.query().from(this).enforcedInAll(
Interval.range(start, end)).result().isEmpty();
@ -72,10 +80,14 @@ public class Criterion implements ICriterion {
this.name = name;
}
public String getType() {
public CriterionType getType() {
return type;
}
public void setType(CriterionType type) {
this.type = type;
}
public boolean isActive() {
return active;
}

View file

@ -0,0 +1,177 @@
package org.navalplanner.business.resources.entities;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.hibernate.validator.NotEmpty;
import org.navalplanner.business.resources.entities.ResourceEnum;
import org.navalplanner.business.resources.services.CriterionTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Base implementation of {@link ICriterionType} <br />
* @author Diego Pino García <dpino@igalia.com>
*/
@Component
public class CriterionType implements ICriterionType<Criterion> {
private Long id;
@SuppressWarnings("unused")
private long version;
@Autowired
CriterionTypeService criterionTypeService;
@NotEmpty
private String name;
private boolean allowHierarchy = true;
private boolean allowSimultaneousCriterionsPerResource = true;
private boolean allowAdding = true;
private boolean allowEditing = true;
private ResourceEnum resource = ResourceEnum.getDefault();
public CriterionType() {
}
public CriterionType(String name) {
this.name = name;
}
public CriterionType(
String name,
boolean allowHierarchy,
boolean allowSimultaneousCriterionsPerResource,
boolean allowAdding,
boolean allowEditing,
ResourceEnum resource) {
this.allowHierarchy = allowHierarchy;
this.allowSimultaneousCriterionsPerResource = allowSimultaneousCriterionsPerResource;
this.name = name;
this.allowAdding = allowAdding;
this.allowEditing = allowEditing;
this.resource = resource;
}
public static CriterionType asCriterionType(ICriterionType criterionType) {
return new CriterionType(
criterionType.getName(),
criterionType.allowHierarchy(),
criterionType.allowSimultaneousCriterionsPerResource(),
criterionType.allowAdding(),
criterionType.allowEditing(),
CriterionType.getResource(criterionType));
}
private static ResourceEnum getResource(ICriterionType criterionType) {
for (ResourceEnum resource : ResourceEnum.values()) {
if (criterionType.criterionCanBeRelatedTo(resource.asClass())) {
return resource;
}
}
return ResourceEnum.getDefault();
}
public Long getId() {
return id;
}
@Override
public String getName() {
return name;
}
@Override
public boolean allowHierarchy() {
return allowHierarchy;
}
@Override
public boolean allowSimultaneousCriterionsPerResource() {
return allowSimultaneousCriterionsPerResource;
}
@Override
public boolean allowAdding() {
return allowAdding;
}
@Override
public boolean allowEditing() {
return allowEditing;
}
public ResourceEnum resource() {
return resource;
}
@Override
public Criterion createCriterion(String name) {
return Criterion.withNameAndType(name, this);
}
public static Criterion createCriterion(
PredefinedCriterionTypes predefinedCriterionType,
String name) {
CriterionType criterionType = CriterionType.
asCriterionType(predefinedCriterionType);
return Criterion.withNameAndType(name, criterionType);
}
@Override
public Criterion createCriterionWithoutNameYet() {
return Criterion.ofType(this);
}
@Override
public boolean contains(ICriterion criterion) {
if (criterion instanceof Criterion) {
Criterion c = (Criterion) criterion;
return this.equals(c.getType());
} else {
return false;
}
}
@Override
public boolean criterionCanBeRelatedTo(Class<? extends Resource> klass) {
for (ResourceEnum resource : ResourceEnum.values()) {
if (resource.isAssignableFrom(klass)) {
return true;
}
}
return false;
}
/**
* Two criterion types are equals if they both got the same name
*
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (o instanceof CriterionType == false)
return false;
if (this == o)
return true;
CriterionType criterionType = (CriterionType) o;
return new EqualsBuilder()
.append(criterionType.getName(), this.getName())
.isEquals();
}
}

View file

@ -3,27 +3,31 @@ package org.navalplanner.business.resources.entities;
import java.util.ArrayList;
import java.util.List;
/**
* Predefined leave criterions<br />
* @author Lorenzo Tilve <ltilve@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
public enum LeaveCriterions {
MEDICAL_LEAVE("medicalLeaveWorkingRelationship"), PATERNITY_LEAVE(
"paternityLeaveWorkingRelationship");
MEDICAL_LEAVE("medicalLeave"),
PATERNITY_LEAVE("paternityLeave");
public static List<Criterion> getCriterions() {
ArrayList<Criterion> result = new ArrayList<Criterion>();
for (LeaveCriterions leaveCriterions : values()) {
result.add(leaveCriterions.criterion());
public static List<String> getCriterionNames() {
ArrayList<String> result = new ArrayList<String>();
for (LeaveCriterions leaveCriterions: values()) {
result.add(leaveCriterions.criterionName);
}
return result;
}
private final String criterionName;
public Criterion criterion() {
return new Criterion(criterionName,
CriterionType.asCriterionType(PredefinedCriterionTypes.LEAVE));
}
private LeaveCriterions(String name) {
this.criterionName = name;
}
public Criterion criterion() {
return PredefinedCriterionTypes.LEAVE
.createCriterion(criterionName);
}
}
}

View file

@ -6,25 +6,26 @@ import java.util.List;
/**
* This class defines some criterion types known a priori<br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
public enum PredefinedCriterionTypes implements ICriterionType<Criterion> {
WORK_RELATIONSHIP(false, false, false, false, Worker.class) {
WORK_RELATIONSHIP(false, false, false, false, ResourceEnum.WORKER) {
@Override
public List<Criterion> getPredefined() {
return WorkingRelationship.getCriterions();
public List<String> getPredefined() {
return WorkingRelationship.getCriterionNames();
}
},
LOCATION_GROUP(false, true, true, true, Resource.class) {
LOCATION_GROUP(false, true, true, true, ResourceEnum.RESOURCE) {
@Override
public List<Criterion> getPredefined() {
public List<String> getPredefined() {
return Arrays.asList();
}
},
LEAVE(false, false, false, false, Worker.class) {
LEAVE(false, false, false, false, ResourceEnum.WORKER) {
@Override
public List<Criterion> getPredefined() {
return LeaveCriterions.getCriterions();
public List<String> getPredefined() {
return LeaveCriterions.getCriterionNames();
}
};
@ -36,26 +37,22 @@ public enum PredefinedCriterionTypes implements ICriterionType<Criterion> {
private final boolean allowEditing;
private List<Class<? extends Resource>> classes;
private final ResourceEnum resource;
private PredefinedCriterionTypes(boolean allowHierarchy,
boolean allowSimultaneousCriterionsPerResource,
boolean allowAdding, boolean allowEditing,
Class<? extends Resource>... klasses) {
ResourceEnum resource) {
this.allowHierarchy = allowHierarchy;
this.allowSimultaneousCriterionsPerResource = allowSimultaneousCriterionsPerResource;
this.allowAdding = allowAdding;
this.allowEditing = allowEditing;
this.classes = Arrays.asList(klasses);
this.resource = resource;
}
@Override
public boolean criterionCanBeRelatedTo(Class<? extends Resource> klass) {
for (Class<? extends Resource> c : classes) {
if (c.isAssignableFrom(klass))
return true;
}
return false;
public String getName() {
return name();
}
@Override
@ -68,46 +65,6 @@ public enum PredefinedCriterionTypes implements ICriterionType<Criterion> {
return allowSimultaneousCriterionsPerResource;
}
@Override
public boolean contains(ICriterion criterion) {
if (criterion instanceof Criterion) {
Criterion c = (Criterion) criterion;
return this.getType().equals(c.getType());
} else
return false;
}
@Override
public Criterion createCriterion(String name) {
return Criterion.withNameAndType(name, getType());
}
@Override
public Criterion createCriterionWithoutNameYet() {
return Criterion.ofType(getType());
}
public abstract List<Criterion> getPredefined();
private String getType() {
return name();
}
public static ICriterionType<Criterion> getType(String type) {
for (PredefinedCriterionTypes predefinedType : PredefinedCriterionTypes
.values()) {
if (predefinedType.name().equals(type))
return predefinedType;
}
throw new RuntimeException("not found "
+ PredefinedCriterionTypes.class.getName() + " type for "
+ type);
}
public String getName() {
return name();
}
@Override
public boolean allowAdding() {
return allowAdding;
@ -118,4 +75,30 @@ public enum PredefinedCriterionTypes implements ICriterionType<Criterion> {
return allowEditing;
}
}
@Override
public Criterion createCriterion(String name) {
return new Criterion(name, CriterionType.asCriterionType(this));
}
@Override
public Criterion createCriterionWithoutNameYet() {
return createCriterion("");
}
@Override
public boolean contains(ICriterion criterion) {
if (criterion instanceof Criterion) {
Criterion c = (Criterion) criterion;
return CriterionType.asCriterionType(this).equals(c.getType());
}
return false;
}
@Override
public boolean criterionCanBeRelatedTo(Class<? extends Resource> klass) {
return resource.isAssignableFrom(klass);
}
public abstract List<String> getPredefined();
}

View file

@ -176,7 +176,7 @@ public abstract class Resource {
public void forceLoadSatisfactions() {
for (CriterionSatisfaction criterionSatisfaction : criterionSatisfactions) {
criterionSatisfaction.getCriterion().getName();
criterionSatisfaction.getCriterion().getType();
criterionSatisfaction.getCriterion().getType().getName();
}
}

View file

@ -0,0 +1,36 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.navalplanner.business.resources.entities;
import java.util.List;
/**
*
* @author Diego Pino Garcia<dpino@igalia.com>
*/
public enum ResourceEnum {
RESOURCE(Resource.class),
WORKER(Worker.class);
Class clase;
private ResourceEnum(Class clase) {
this.clase = clase;
}
public Class asClass() {
return clase;
}
public static ResourceEnum getDefault() {
return RESOURCE;
}
public boolean isAssignableFrom(Class clase) {
return asClass().equals(clase);
}
}

View file

@ -3,28 +3,35 @@ package org.navalplanner.business.resources.entities;
import java.util.ArrayList;
import java.util.List;
/**
* Predefined working relationships<br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
public enum WorkingRelationship {
HIRED("hiredResourceWorkingRelationship"), FIRED(
"firedResourceWorkingRelationship");
HIRED("hiredResourceWorkingRelationship"),
FIRED("firedResourceWorkingRelationship");
public static List<Criterion> getCriterions() {
ArrayList<Criterion> result = new ArrayList<Criterion>();
public static List<String> getCriterionNames() {
ArrayList<String> result = new ArrayList<String>();
for (WorkingRelationship workingRelationship : values()) {
result.add(workingRelationship.criterion());
result.add(workingRelationship.criterionName);
}
return result;
}
private final String criterionName;
public Criterion criterion() {
return new Criterion(criterionName,
CriterionType.asCriterionType(PredefinedCriterionTypes.WORK_RELATIONSHIP));
}
public String getCriterionName() {
return criterionName;
}
private WorkingRelationship(String name) {
this.criterionName = name;
}
public Criterion criterion() {
return PredefinedCriterionTypes.WORK_RELATIONSHIP
.createCriterion(criterionName);
}
}

View file

@ -0,0 +1,27 @@
package org.navalplanner.business.resources.services;
import java.util.List;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.CriterionType;
/**
* Services for {@link CriterionType} <br />
* @author Diego Pino García <dpino@igalia.com>
*/
public interface CriterionTypeService {
void createIfNotExists(CriterionType criterionType) throws ValidationException;
boolean exists(CriterionType criterionType);
CriterionType findUniqueByName(CriterionType criterionType);
CriterionType findUniqueByName(String name);
void remove(CriterionType criterionType) throws InstanceNotFoundException;
void save(CriterionType entity) throws ValidationException;
}

View file

@ -14,12 +14,14 @@ import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.impl.CriterionDAO;
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.navalplanner.business.resources.services.CriterionService;
import org.navalplanner.business.resources.services.CriterionTypeService;
import org.navalplanner.business.resources.services.ResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@ -32,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
* Implementation of {@link CriterionService} 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)
@ -44,6 +47,9 @@ public class CriterionServiceImpl implements CriterionService {
@Autowired
private ResourceService resourceService;
@Autowired
private CriterionTypeService criterionTypeService;
public boolean exists(Criterion criterion) {
return criterionDAO.exists(criterion.getId())
|| criterionDAO.existsByNameAndType(criterion);
@ -66,7 +72,15 @@ public class CriterionServiceImpl implements CriterionService {
}
@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));
}
criterionDAO.save(entity);
if (criterionDAO.findByNameAndType(entity).size() > 1) {
@ -80,6 +94,16 @@ public class CriterionServiceImpl implements CriterionService {
}
}
private CriterionType saveCriterionType(CriterionType criterionType) throws ValidationException {
if (criterionTypeService.exists(criterionType)) {
criterionType = criterionTypeService.findUniqueByName(criterionType.getName());
} else {
criterionTypeService.save(criterionType);
}
return criterionType;
}
@Override
public Collection<Resource> getResourcesSatisfying(ICriterion criterion) {
List<Resource> resources = resourceService.getResources();

View file

@ -0,0 +1,78 @@
package org.navalplanner.business.resources.services.impl;
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.ICriterionTypeDAO;
import org.navalplanner.business.resources.daos.impl.CriterionTypeDAO;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.services.CriterionTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* Implementation of {@link CriterionTypeService} using {@link CriterionTypeDAO} <br />
* @author Diego Pino García <dpino@igalia.com>
*/
@Transactional
@Component
public class CriterionTypeServiceImpl implements CriterionTypeService {
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@Override
public void createIfNotExists(CriterionType criterionType) throws ValidationException {
if (!exists(criterionType))
save(criterionType);
}
@Override
public boolean exists(CriterionType criterionType) {
return criterionTypeDAO.exists(criterionType.getId())
|| criterionTypeDAO.existsByName(criterionType);
}
@Override
public CriterionType findUniqueByName(CriterionType criterionType) {
return findUniqueByName(criterionType.getName());
}
@Override
public CriterionType findUniqueByName(String name) {
try {
return criterionTypeDAO.findUniqueByName(name);
} catch (InstanceNotFoundException e) {
return null;
}
}
@Override
public void remove(CriterionType criterionType) throws InstanceNotFoundException {
if (criterionType.getId() != null ) {
criterionTypeDAO.remove(criterionType.getId());
} else {
criterionTypeDAO.removeByName(criterionType);
}
}
@Transactional(rollbackFor=ValidationException.class)
@Override
public void save(CriterionType entity) throws ValidationException {
criterionTypeDAO.save(entity);
if (criterionTypeDAO.findByName(entity).size() > 1) {
InvalidValue[] invalidValues = {
new InvalidValue(entity.getName() + " already exists",
CriterionType.class, "name", entity.getName(), entity)
};
throw new ValidationException(invalidValues,
"Couldn't save new criterionType");
}
}
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.navalplanner.business.resources.entities">
<hibernate-mapping default-access="field" package="org.navalplanner.business.resources.entities">
<class name="Resource">
<id access="field" name="id">
<generator class="native"/>
@ -10,7 +10,7 @@
Hibernate infers type="integer".
-->
<version access="field" name="version" type="long"/>
<set access="field" inverse="true" name="criterionSatisfactions" cascade="all-delete-orphan">
<set access="field" cascade="all-delete-orphan" inverse="true" name="criterionSatisfactions">
<key column="resource" not-null="true"/>
<one-to-many class="CriterionSatisfaction"/>
</set>
@ -23,17 +23,18 @@
</joined-subclass>
</class>
<!-- Criterion -->
<class name="Criterion">
<id access="field" name="id">
<generator class="native"/>
</id>
<version access="field" name="version" type="long"/>
<property name="name" access="field"/>
<property name="type" access="field"/>
<property access="field" name="name"/>
<property access="field" name="active"/>
<many-to-one access="field" name="type" column="id_criterion_type" not-null="true" />
</class>
<!-- CriterionSatisfaction -->
<class name="CriterionSatisfaction">
<id access="field" name="id">
<generator class="native"/>
@ -41,7 +42,26 @@
<version access="field" name="version" type="long"/>
<property access="field" name="startDate" not-null="true"/>
<property access="field" name="finishDate"/>
<many-to-one name="criterion" access="field" not-null="true" />
<many-to-one access="field" name="criterion" not-null="true"/>
<many-to-one access="field" column="resource" name="resource" not-null="true"/>
</class>
<!-- CriterionType -->
<class name="CriterionType">
<id name="id">
<generator class="native"/>
</id>
<version name="version" type="long"/>
<property name="name" unique="true"/>
<property name="allowSimultaneousCriterionsPerResource"/>
<property name="allowHierarchy"/>
<property name="allowAdding"/>
<property name="allowEditing"/>
<property name="resource">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">org.navalplanner.business.resources.entities.ResourceEnum</param>
</type>
</property>
</class>
</hibernate-mapping>

View file

@ -26,6 +26,7 @@ import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.orders.entities.OrderLineGroup;
import org.navalplanner.business.orders.services.IOrderService;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.services.CriterionService;
import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest;
import org.springframework.beans.factory.annotation.Autowired;
@ -218,8 +219,8 @@ public class OrderServiceTest {
orderLine.addHoursGroup(hoursGroup);
orderLine.addHoursGroup(hoursGroup2);
Criterion criterion = Criterion.withNameAndType("Test"
+ UUID.randomUUID().toString(), "test");
CriterionType criterionType = new CriterionType("test");
Criterion criterion = new Criterion("Test" + UUID.randomUUID(), criterionType);
criterionService.save(criterion);
hoursGroup.addCriterion(criterion);
@ -248,7 +249,7 @@ public class OrderServiceTest {
Criterion criterion = criterions.iterator().next();
assertThat(criterion.getType(), equalTo("test"));
assertThat(criterion.getType().getName(), equalTo("test"));
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}

View file

@ -14,7 +14,9 @@ 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.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -34,25 +36,51 @@ public class CriterionDAOTest {
@Autowired
private ICriterionDAO criterionDAO;
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@Test
public void testInSpringContainer() {
assertNotNull(criterionDAO);
}
public static Criterion createValidCriterion() {
return createValidCriterion(UUID.randomUUID().toString());
}
public static Criterion createValidCriterion(String name) {
CriterionType criterionType = CriterionTypeDAOTest.createValidCriterionType();
return Criterion.withNameAndType(name, criterionType);
}
private void saveCriterionType(Criterion criterion) {
CriterionType criterionType = criterion.getType();
if (criterionTypeDAO.existsByName(criterionType)) {
try {
criterionType = criterionTypeDAO.findUniqueByName(criterionType);
} catch (InstanceNotFoundException ex) {
}
} else {
criterionTypeDAO.save(criterionType);
}
criterion.setType(criterionType);
}
@Test
public void testSaveCriterions() throws Exception {
Criterion criterion = createValidCriterion();
// A valid CriterionType must exists before saving Criterion
saveCriterionType(criterion);
criterionDAO.save(criterion);
assertTrue(criterionDAO.exists(criterion.getId()));
}
public static Criterion createValidCriterion() {
return Criterion.withNameAndType(UUID.randomUUID().toString(), "pruebaType");
}
@Test
public void testRemove() throws InstanceNotFoundException {
Criterion criterion = createValidCriterion();
saveCriterionType(criterion);
criterionDAO.save(criterion);
criterionDAO.remove(criterion.getId());
assertFalse(criterionDAO.exists(criterion.getId()));
@ -62,7 +90,9 @@ public class CriterionDAOTest {
public void testList() {
int previous = criterionDAO.list(Criterion.class).size();
Criterion criterion1 = createValidCriterion();
saveCriterionType(criterion1);
Criterion criterion2 = createValidCriterion();
saveCriterionType(criterion2);
criterionDAO.save(criterion1);
criterionDAO.save(criterion2);
List<Criterion> list = criterionDAO.list(Criterion.class);

View file

@ -8,9 +8,11 @@ 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.ICriterionTypeDAO;
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.CriterionType;
import org.navalplanner.business.resources.entities.Worker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
@ -42,6 +44,9 @@ public class CriterionSatisfactionDAOTest {
@Autowired
private ICriterionDAO criterionDAO;
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@Autowired
private WorkerDaoHibernate workerDAO;
@ -55,6 +60,7 @@ public class CriterionSatisfactionDAOTest {
private CriterionSatisfaction createValidCriterionSatisfaction(int year) {
Criterion criterion = CriterionDAOTest.createValidCriterion();
saveCriterionType(criterion);
criterionDAO.save(criterion);
Worker worker = new Worker("firstname", "surname", "nif", 4);
workerDAO.save(worker);
@ -63,9 +69,23 @@ public class CriterionSatisfactionDAOTest {
return criterionSatisfaction;
}
private void saveCriterionType(Criterion criterion) {
CriterionType criterionType = criterion.getType();
if (criterionTypeDAO.existsByName(criterionType)) {
try {
criterionType = criterionTypeDAO.findUniqueByName(criterionType);
} catch (InstanceNotFoundException ex) {
}
} else {
criterionTypeDAO.save(criterionType);
}
criterion.setType(criterionType);
}
@Test(expected = DataIntegrityViolationException.class)
public void testNotSaveWithTransientCriterionAndWorker() {
Criterion criterion = CriterionDAOTest.createValidCriterion();
saveCriterionType(criterion);
Worker worker = new Worker("firstname", "surname", "nif", 4);
CriterionSatisfaction criterionSatisfaction = new CriterionSatisfaction(
year(2007), criterion, worker);

View file

@ -0,0 +1,83 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.navalplanner.business.test.resources.daos;
import java.util.List;
import java.util.UUID;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.ResourceEnum;
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.assertTrue;
import static junit.framework.Assert.assertFalse;
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;
/**
*
* @author Diego Pino García <dpino@igalia.com>
*/
/**
* Test cases for CriterionTypeDAO <br />
* @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 CriterionTypeDAOTest {
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
public static final String DEFAULT_CRITERION_TYPE = "TEST_DEFAULT";
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 testSaveCriterionType() throws Exception {
CriterionType criterionType = createValidCriterionType();
criterionTypeDAO.save(criterionType);
assertTrue(criterionTypeDAO.exists(criterionType.getId()));
}
@Test
public void testRemove() throws InstanceNotFoundException {
CriterionType criterionType = createValidCriterionType();
criterionTypeDAO.save(criterionType);
criterionTypeDAO.remove(criterionType.getId());
assertFalse(criterionTypeDAO.exists(criterionType.getId()));
}
@Test
public void testList() {
int previous = criterionTypeDAO.list(CriterionType.class).size();
CriterionType criterion1 = createValidCriterionType();
CriterionType criterion2 = createValidCriterionType();
criterionTypeDAO.save(criterion1);
criterionTypeDAO.save(criterion2);
List<CriterionType> list = criterionTypeDAO.list(CriterionType.class);
assertEquals(previous + 2, list.size());
}
}

View file

@ -132,10 +132,6 @@ public class CriterionTest {
public void testCanBeRelatedTo() throws Exception {
assertTrue(PredefinedCriterionTypes.LOCATION_GROUP
.criterionCanBeRelatedTo(Resource.class));
assertTrue(PredefinedCriterionTypes.LOCATION_GROUP
.criterionCanBeRelatedTo(Worker.class));
assertFalse(PredefinedCriterionTypes.WORK_RELATIONSHIP
.criterionCanBeRelatedTo(Resource.class));
assertTrue(PredefinedCriterionTypes.WORK_RELATIONSHIP
.criterionCanBeRelatedTo(Worker.class));
}

View file

@ -13,6 +13,7 @@ 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.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionOnData;
@ -22,6 +23,7 @@ import org.navalplanner.business.resources.entities.PredefinedCriterionTypes;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.CriterionService;
import org.navalplanner.business.resources.services.CriterionTypeService;
import org.navalplanner.business.resources.services.ResourceService;
import org.navalplanner.business.test.resources.daos.CriterionDAOTest;
import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest;
@ -44,6 +46,7 @@ import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING
/**
* Test cases for {@link CriterionService} <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,
@ -54,6 +57,9 @@ public class CriterionServiceTest {
@Autowired
private CriterionService criterionService;
@Autowired
private CriterionTypeService criterionTypeService;
@Autowired
private ResourceService resourceService;
@ -62,7 +68,7 @@ public class CriterionServiceTest {
@Test(expected = InvalidStateException.class)
public void testCantSaveCriterionWithoutNameAndType() throws Exception {
Criterion criterion = Criterion.withNameAndType("valido", "valido");
Criterion criterion = CriterionDAOTest.createValidCriterion("valido");
criterion.setName("");
criterionService.save(criterion);
sessionFactory.getCurrentSession().flush();
@ -244,7 +250,7 @@ public class CriterionServiceTest {
Criterion criterion = CriterionDAOTest.createValidCriterion();
criterionService.save(criterion);
ICriterionType<?> type = createTypeThatMatches(criterion);
worker1.addSatisfaction(new CriterionWithItsType(type, criterion));
worker1.addSatisfaction(new CriterionWithItsType(criterion.getType(), criterion));
resourceService.saveResource(worker1);
Resource workerReloaded = criterionService
.onTransaction(new OnTransaction<Resource>() {
@ -262,7 +268,7 @@ public class CriterionServiceTest {
}
});
Collection<CriterionSatisfaction> satisfactionsFor = workerReloaded
.getSatisfactionsFor(type);
.getSatisfactionsFor(criterion.getType());
Criterion reloadedCriterion = satisfactionsFor.iterator().next()
.getCriterion();
Assume.assumeTrue(!reloadedCriterion.getClass().equals(

View file

@ -0,0 +1,62 @@
package org.navalplanner.business.test.resources.services;
import java.util.UUID;
import org.hibernate.exception.ConstraintViolationException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.services.CriterionTypeService;
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 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;
/**
* Test cases for {@link CriterionTypeService} <br />
* @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 CriterionTypeServiceTest {
@Autowired
private CriterionTypeService criterionTypeService;
public CriterionType createValidCriterionType(String name) {
return new CriterionType(name);
}
@Test
public void testSaveCriterionType() throws ValidationException {
String unique = UUID.randomUUID().toString();
CriterionType criterionType = createValidCriterionType(unique);
criterionTypeService.save(criterionType);
assertTrue(criterionTypeService.exists(criterionType));
}
@Test
public void testSaveCriterionTypeTwice() throws ValidationException {
String unique = UUID.randomUUID().toString();
CriterionType criterionType = createValidCriterionType(unique);
criterionTypeService.save(criterionType);
criterionTypeService.save(criterionType);
assertTrue(criterionTypeService.exists(criterionType));
}
@Test(expected=ConstraintViolationException.class)
public void testCannotSaveTwoCriterionTypesWithTheSameName() throws ValidationException {
String unique = UUID.randomUUID().toString();
CriterionType criterionType = createValidCriterionType(unique);
criterionTypeService.save(criterionType);
criterionType = createValidCriterionType(unique);
criterionTypeService.save(criterionType);
}
}

View file

@ -14,6 +14,7 @@ import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.orders.entities.OrderLineGroup;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.web.common.Util;
import org.zkoss.zk.ui.Component;
@ -328,8 +329,8 @@ public class OrderElementController extends GenericForwardComposer {
for (HoursGroup hoursGroup : orderElement.getHoursGroups()) {
Set<Criterion> criterions = hoursGroup.getCriterions();
for (Criterion criterion : criterions) {
String type = criterion.getType();
criterionTypes.add(model.getCriterionTypeByName(type));
CriterionType type = criterion.getType();
criterionTypes.add(model.getCriterionTypeByName(type.getName()));
}
}