diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IntegrationEntityDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IntegrationEntityDAO.java index 8317def3c..ffbe0f218 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IntegrationEntityDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IntegrationEntityDAO.java @@ -67,7 +67,7 @@ public class IntegrationEntityDAO } E entity = (E) getSession().createCriteria(getEntityClass()).add( - Restrictions.eq("code", code).ignoreCase()).uniqueResult(); + Restrictions.eq("code", code.trim()).ignoreCase()).uniqueResult(); if (entity == null) { throw new InstanceNotFoundException( diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/ResourcesCostCategoryAssignment.java b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/ResourcesCostCategoryAssignment.java index 334ef67c2..d4915c320 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/ResourcesCostCategoryAssignment.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/ResourcesCostCategoryAssignment.java @@ -20,15 +20,12 @@ package org.navalplanner.business.costcategories.entities; -import static org.navalplanner.business.i18n.I18nHelper._; - import org.apache.commons.lang.StringUtils; import org.hibernate.validator.AssertTrue; import org.hibernate.validator.NotNull; import org.joda.time.LocalDate; import org.navalplanner.business.common.IntegrationEntity; import org.navalplanner.business.common.Registry; -import org.navalplanner.business.common.exceptions.CreateUnvalidatedException; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.costcategories.daos.IResourcesCostCategoryAssignmentDAO; import org.navalplanner.business.resources.entities.Resource; @@ -56,25 +53,16 @@ public class ResourcesCostCategoryAssignment extends IntegrationEntity { return (ResourcesCostCategoryAssignment) create(new ResourcesCostCategoryAssignment()); } + /** + * @throws InstanceNotFoundException if cost category does not exist + */ public static ResourcesCostCategoryAssignment createUnvalidated( String code, String costCategoryName, Resource resource, LocalDate initDate, LocalDate endDate) - throws CreateUnvalidatedException { + throws InstanceNotFoundException { - /* Get CostCategory. */ - if (StringUtils.isBlank(costCategoryName)) { - throw new CreateUnvalidatedException( - _("cost category name not specified")); - } - - CostCategory costCategory = null; - try { - costCategory = Registry.getCostCategoryDAO().findUniqueByName( - StringUtils.trim(costCategoryName)); - } catch (InstanceNotFoundException e) { - throw new CreateUnvalidatedException( - _("{0}: cost category does not exist", costCategoryName)); - } + CostCategory costCategory = Registry.getCostCategoryDAO().findUniqueByName( + StringUtils.trim(costCategoryName)); /* Create instance of ResourcesCostCategoryAssignment. */ ResourcesCostCategoryAssignment assignment = diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IMachineDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IMachineDAO.java index 44469f06e..ff7d93125 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IMachineDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IMachineDAO.java @@ -22,7 +22,7 @@ package org.navalplanner.business.resources.daos; import java.util.List; -import org.navalplanner.business.common.daos.IGenericDAO; +import org.navalplanner.business.common.daos.IIntegrationEntityDAO; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.entities.Machine; @@ -31,8 +31,9 @@ import org.navalplanner.business.resources.entities.Machine; * * @author Diego Pino Garcia * @author Javier Moran Rua + * @author Fernando Bellas Permuy */ -public interface IMachineDAO extends IGenericDAO { +public interface IMachineDAO extends IIntegrationEntityDAO { /** * Returns machines which name/NIF partially matches with name diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IWorkerDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IWorkerDAO.java index 119b8e01d..7e2c3aeab 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IWorkerDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/IWorkerDAO.java @@ -23,7 +23,7 @@ package org.navalplanner.business.resources.daos; import java.util.Date; import java.util.List; -import org.navalplanner.business.common.daos.IGenericDAO; +import org.navalplanner.business.common.daos.IIntegrationEntityDAO; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.reports.dtos.HoursWorkedPerWorkerDTO; import org.navalplanner.business.resources.entities.Worker; @@ -37,7 +37,7 @@ import org.springframework.transaction.annotation.Transactional; * @author Diego Pino Garcia * */ -public interface IWorkerDAO extends IGenericDAO { +public interface IWorkerDAO extends IIntegrationEntityDAO { /** * Returns workers which name/NIF partially matches with name diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/MachineDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/MachineDAO.java index 5d1c9ff45..e8a48394d 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/MachineDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/MachineDAO.java @@ -22,9 +22,8 @@ package org.navalplanner.business.resources.daos; import java.util.List; -import org.hibernate.Criteria; import org.hibernate.criterion.Restrictions; -import org.navalplanner.business.common.daos.GenericDAOHibernate; +import org.navalplanner.business.common.daos.IntegrationEntityDAO; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.entities.Machine; import org.springframework.beans.factory.config.BeanDefinition; @@ -33,15 +32,17 @@ import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; + /** * Hibernate DAO for the Machine entity. * * @author Diego Pino Garcia * @author Javier Moran Rua + * @author Fernando Bellas Permuy */ @Repository @Scope(BeanDefinition.SCOPE_SINGLETON) -public class MachineDAO extends GenericDAOHibernate +public class MachineDAO extends IntegrationEntityDAO implements IMachineDAO { @Override @@ -61,14 +62,9 @@ public class MachineDAO extends GenericDAOHibernate @Override public Machine findUniqueByCode(String code) throws InstanceNotFoundException { - Criteria criteria = getSession().createCriteria(Machine.class); - criteria.add(Restrictions.eq("code", code).ignoreCase()); - List list = criteria.list(); - if (list.size() != 1) { - throw new InstanceNotFoundException(code, Machine.class.getName()); - } - return list.get(0); + return findExistingEntityByCode(code); + } @Override diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/WorkerDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/WorkerDAO.java index 7a2184d91..fe536f197 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/WorkerDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/WorkerDAO.java @@ -26,7 +26,7 @@ import java.util.List; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.criterion.Restrictions; -import org.navalplanner.business.common.daos.GenericDAOHibernate; +import org.navalplanner.business.common.daos.IntegrationEntityDAO; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.reports.dtos.HoursWorkedPerWorkerDTO; import org.navalplanner.business.resources.entities.Worker; @@ -36,6 +36,7 @@ import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; + /** * Hibernate DAO for the Worker entity. * @@ -46,7 +47,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Repository @Scope(BeanDefinition.SCOPE_SINGLETON) -public class WorkerDAO extends GenericDAOHibernate +public class WorkerDAO extends IntegrationEntityDAO implements IWorkerDAO { @Override diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java index 6381764e4..eb61f0efb 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionSatisfaction.java @@ -20,19 +20,15 @@ package org.navalplanner.business.resources.entities; -import static org.navalplanner.business.i18n.I18nHelper._; - import java.util.Comparator; import java.util.Date; -import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang.builder.ToStringBuilder; import org.hibernate.validator.AssertTrue; import org.hibernate.validator.NotNull; import org.navalplanner.business.common.IntegrationEntity; import org.navalplanner.business.common.Registry; -import org.navalplanner.business.common.exceptions.CreateUnvalidatedException; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.daos.ICriterionSatisfactionDAO; import org.navalplanner.business.resources.daos.ICriterionTypeDAO; @@ -75,44 +71,25 @@ public class CriterionSatisfaction extends IntegrationEntity { } + /** + * @throws InstanceNotFoundException if criterion type or criterion does + * not exist + */ public static CriterionSatisfaction createUnvalidated( String code, String criterionTypeName, String criterionName, Resource resource, Date startDate, Date finishDate) - throws CreateUnvalidatedException { + throws InstanceNotFoundException { ICriterionTypeDAO criterionTypeDAO = Registry.getCriterionTypeDAO(); /* Get CriterionType. */ - if (StringUtils.isBlank(criterionTypeName)) { - throw new CreateUnvalidatedException( - _("criterion type name not specified")); - } - - CriterionType criterionType = null; - try { - criterionType = criterionTypeDAO.findUniqueByName( - criterionTypeName); - } catch (InstanceNotFoundException e) { - throw new CreateUnvalidatedException( - _("{0}: criterion type does not exist", criterionTypeName)); - } + CriterionType criterionType = criterionTypeDAO.findUniqueByName( + criterionTypeName); /* Get Criterion. */ - if (StringUtils.isBlank(criterionName)) { - throw new CreateUnvalidatedException( - _("criterion name not specified")); - } - - Criterion criterion = null; - try { - criterion = criterionType.getCriterion( - criterionName); - } catch (InstanceNotFoundException e) { - throw new CreateUnvalidatedException( - _("{0}: criterion is not of type {1}", criterionName, - criterionTypeName)); - } + Criterion criterion = criterionType.getCriterion( + criterionName); /* Create instance of CriterionSatisfaction. */ CriterionSatisfaction criterionSatisfaction = diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InstanceConstraintViolationsDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InstanceConstraintViolationsDTO.java index 92bdb771f..713c402f6 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InstanceConstraintViolationsDTO.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InstanceConstraintViolationsDTO.java @@ -27,7 +27,6 @@ import java.util.List; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; /** * DTO for modeling the list of constraint violations on a given instance. @@ -57,10 +56,12 @@ public class InstanceConstraintViolationsDTO { @XmlAttribute(name=ENTITY_TYPE_ATTRIBUTE_NAME) public String entityType; - @XmlElementWrapper(name="constraint-violations") @XmlElement(name="constraint-violation") public List constraintViolations; + @XmlElement(name="recoverable-error") + public RecoverableErrorDTO recoverableError; + @XmlElement(name="internal-error") public InternalErrorDTO internalError; @@ -93,6 +94,15 @@ public class InstanceConstraintViolationsDTO { } + public InstanceConstraintViolationsDTO( + InstanceConstraintViolationsDTOId instanceId, + RecoverableErrorDTO recoverableError) { + + this(instanceId); + this.recoverableError = recoverableError; + + } + public InstanceConstraintViolationsDTO( InstanceConstraintViolationsDTOId instanceId, InternalErrorDTO internalError) { @@ -144,8 +154,23 @@ public class InstanceConstraintViolationsDTO { ENTITY_TYPE_ATTRIBUTE_NAME + " = " + entityType + " **"); - for (ConstraintViolationDTO i : constraintViolations) { - printWriter.println(i); + if (internalError != null) { + + printWriter.println("Internal error:"); + printWriter.println(internalError); + + } else if (constraintViolations != null) { + + printWriter.println("Constraint violations:"); + for (ConstraintViolationDTO i : constraintViolations) { + printWriter.println(i); + } + + } else if (recoverableError != null) { + + printWriter.println("Recoverable error:"); + printWriter.println(recoverableError); + } printWriter.close(); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InternalErrorDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InternalErrorDTO.java index c3e059602..ceedd5e72 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InternalErrorDTO.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InternalErrorDTO.java @@ -20,23 +20,28 @@ package org.navalplanner.ws.common.api; +import java.io.PrintWriter; +import java.io.StringWriter; + import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** - * DTO for modeling the response to be returned when an internal service error - * occurs. + * DTO for modeling an internal error. * * @author Fernando Bellas Permuy */ @XmlRootElement(name="internal-error") public class InternalErrorDTO { - @XmlAttribute + public final static String MESSAGE_ATTRIBUTE_NAME = "message"; + public final static String STACK_TRACE_ATTRIBUTE_NAME = "stack-trace"; + + @XmlAttribute(name=MESSAGE_ATTRIBUTE_NAME) public String message; - @XmlElement(name="stack-trace") + @XmlElement(name=STACK_TRACE_ATTRIBUTE_NAME) public String stackTrace; public InternalErrorDTO() {} @@ -46,4 +51,18 @@ public class InternalErrorDTO { this.stackTrace = stackTrace; } + @Override + public String toString() { + + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + + printWriter.println(MESSAGE_ATTRIBUTE_NAME + " = " + message); + printWriter.println(STACK_TRACE_ATTRIBUTE_NAME + " = " + stackTrace); + printWriter.close(); + + return stringWriter.toString(); + + } + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/PropertyDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/PropertyDTO.java new file mode 100644 index 000000000..5abdbc0fd --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/PropertyDTO.java @@ -0,0 +1,61 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.ws.common.api; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import javax.xml.bind.annotation.XmlAttribute; + +/** + * DTO for modeling a property, containing a name and a value. + * + * @author Fernando Bellas Permuy + */ +public class PropertyDTO { + + @XmlAttribute + public String name; + + @XmlAttribute + public String value; + + public PropertyDTO() {} + + public PropertyDTO(String name, String value) { + this.name = name; + this.value = value; + } + + @Override + public String toString() { + + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + + printWriter.print(name + " = " + value); + printWriter.close(); + + return stringWriter.toString(); + + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/RecoverableErrorDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/RecoverableErrorDTO.java new file mode 100644 index 000000000..cd9ff6e7f --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/RecoverableErrorDTO.java @@ -0,0 +1,80 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.ws.common.api; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; + +/** + * DTO for modeling a recoverable error. + * + * @author Fernando Bellas Permuy + */ +public class RecoverableErrorDTO { + + public final static String ERROR_CODE_ATTRIBUTE_NAME = "error-code"; + public final static String MESSAGE_ATTRIBUTE_NAME = "message"; + + @XmlAttribute(name=ERROR_CODE_ATTRIBUTE_NAME) + public int errorCode; + + @XmlAttribute(name=MESSAGE_ATTRIBUTE_NAME) + public String message; + + @XmlElement(name="property") + public List properties; + + public RecoverableErrorDTO() {} + + public RecoverableErrorDTO(int errorCode, String message, + List properties) { + + this.errorCode = errorCode; + this.message = message; + this.properties = properties; + + } + + @Override + public String toString() { + + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + + printWriter.println( + ERROR_CODE_ATTRIBUTE_NAME + " = " + errorCode + " - " + + MESSAGE_ATTRIBUTE_NAME + " = " + message); + + for (PropertyDTO p : properties) { + printWriter.println(p); + } + + printWriter.close(); + + return stringWriter.toString(); + + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/ConstraintViolationConverter.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/ConstraintViolationConverter.java index 853d91bd8..a09d3fce0 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/ConstraintViolationConverter.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/ConstraintViolationConverter.java @@ -22,6 +22,7 @@ package org.navalplanner.ws.common.impl; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.hibernate.validator.InvalidValue; import org.navalplanner.business.common.exceptions.ValidationException; @@ -29,6 +30,8 @@ import org.navalplanner.ws.common.api.ConstraintViolationDTO; import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO; import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTOId; import org.navalplanner.ws.common.api.InternalErrorDTO; +import org.navalplanner.ws.common.api.PropertyDTO; +import org.navalplanner.ws.common.api.RecoverableErrorDTO; /** * Converter for constraint violations. @@ -115,6 +118,29 @@ public class ConstraintViolationConverter { } + public final static InstanceConstraintViolationsDTO toDTO( + InstanceConstraintViolationsDTOId instanceId, + RecoverableErrorException recoverableErrorException) { + + List properties = new ArrayList(); + + for (Map.Entry p : + recoverableErrorException.getProperties().entrySet()) { + + properties.add(new PropertyDTO(p.getKey(), p.getValue())); + + } + + RecoverableErrorDTO recoverableErrorDTO = new RecoverableErrorDTO( + recoverableErrorException.getErrorCode().ordinal() + 1, + recoverableErrorException.getMessage(), + properties); + + return new InstanceConstraintViolationsDTO(instanceId, + recoverableErrorDTO); + + } + public final static InstanceConstraintViolationsDTO toDTO( InstanceConstraintViolationsDTOId instanceId, RuntimeException runtimeException) { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/GenericRESTService.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/GenericRESTService.java index 55e5c0c3c..1837c772b 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/GenericRESTService.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/GenericRESTService.java @@ -57,7 +57,8 @@ public abstract class GenericRESTService entityDTOs) { + protected InstanceConstraintViolationsListDTO save( + List entityDTOs) { List instanceConstraintViolationsList = new ArrayList(); @@ -75,6 +76,11 @@ public abstract class GenericRESTService save = new IOnTransaction() { @@ -122,13 +134,22 @@ public abstract class GenericRESTService. + */ + +package org.navalplanner.ws.common.impl; + +import static org.navalplanner.web.I18nHelper._; + +import java.util.HashMap; +import java.util.Map; + +/** + * A recoverable error modeling "instance not found". + * + * @author Fernando Bellas Permuy + */ +@SuppressWarnings("serial") +public class InstanceNotFoundRecoverableErrorException + extends RecoverableErrorException { + + /** + * + * @param type type of the instance not found + * @param value name of the instance not found + */ + public InstanceNotFoundRecoverableErrorException(String type, + String value) { + + super(_("instance not found"), + RecoverableErrorCodeEnum.INSTANCE_NOT_FOUND); + + Map properties = new HashMap(); + properties.put("type", type); + properties.put("value", value); + + setProperties(properties); + + } + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/exceptions/CreateUnvalidatedException.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/RecoverableErrorCodeEnum.java similarity index 72% rename from navalplanner-business/src/main/java/org/navalplanner/business/common/exceptions/CreateUnvalidatedException.java rename to navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/RecoverableErrorCodeEnum.java index b60180b45..96bc94c08 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/exceptions/CreateUnvalidatedException.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/RecoverableErrorCodeEnum.java @@ -18,19 +18,13 @@ * along with this program. If not, see . */ -package org.navalplanner.business.common.exceptions; +package org.navalplanner.ws.common.impl; /** - * An exception representing that a "createUnvalidated" method in an entity - * class could not create an instance. + * An enumeration to specify all types of recoverable errors. * * @author Fernando Bellas Permuy */ -@SuppressWarnings("serial") -public class CreateUnvalidatedException extends Exception { - - public CreateUnvalidatedException(String message) { - super(message); - } - +public enum RecoverableErrorCodeEnum { + INSTANCE_NOT_FOUND } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/RecoverableErrorException.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/RecoverableErrorException.java new file mode 100644 index 000000000..ad968f3bf --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/RecoverableErrorException.java @@ -0,0 +1,56 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.ws.common.impl; + +import java.util.Map; + +/** + * An exception to modeling a recoverable error. + * + * @author Fernando Bellas Permuy + */ +@SuppressWarnings("serial") +public abstract class RecoverableErrorException extends RuntimeException { + + private RecoverableErrorCodeEnum errorCode; + private Map properties; + + protected RecoverableErrorException(String message, + RecoverableErrorCodeEnum errorCode) { + + super(message); + this.errorCode = errorCode; + + } + + public RecoverableErrorCodeEnum getErrorCode() { + return errorCode; + } + + public Map getProperties() { + return properties; + } + + protected void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionConverter.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionConverter.java index 443e7dab2..a1857670b 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionConverter.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionConverter.java @@ -111,7 +111,7 @@ public final class CriterionConverter { } public final static void updateCriterionType(CriterionType criterionType, - CriterionTypeDTO criterionTypeDTO) throws ValidationException { + CriterionTypeDTO criterionTypeDTO) { /* 1: Get criterion wrappers with parent code. */ Set criterionWrappers = diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java index a255570ea..12ce3a7bb 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java @@ -25,20 +25,24 @@ import static org.navalplanner.web.I18nHelper._; import java.util.List; import org.apache.commons.lang.StringUtils; -import org.navalplanner.business.common.exceptions.CreateUnvalidatedException; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.MultipleInstancesException; +import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.business.costcategories.entities.ResourcesCostCategoryAssignment; import org.navalplanner.business.resources.entities.CriterionSatisfaction; +import org.navalplanner.business.resources.entities.CriterionType; import org.navalplanner.business.resources.entities.Machine; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.ws.common.impl.DateConverter; +import org.navalplanner.ws.common.impl.InstanceNotFoundRecoverableErrorException; import org.navalplanner.ws.resources.api.CriterionSatisfactionDTO; import org.navalplanner.ws.resources.api.MachineDTO; import org.navalplanner.ws.resources.api.ResourceDTO; import org.navalplanner.ws.resources.api.ResourcesCostCategoryAssignmentDTO; import org.navalplanner.ws.resources.api.WorkerDTO; +import org.navalplanner.ws.resources.criterion.api.CriterionDTO; +import org.navalplanner.ws.resources.criterion.api.CriterionTypeDTO; /** * Converter from/to resource-related entities to/from DTOs. @@ -49,8 +53,7 @@ public class ResourceConverter { private ResourceConverter() {} - public final static Resource toEntity(ResourceDTO resourceDTO) - throws CreateUnvalidatedException { + public final static Resource toEntity(ResourceDTO resourceDTO) { Resource resource; @@ -96,8 +99,7 @@ public class ResourceConverter { } private static void addCriterionSatisfactions(Resource resource, - List criterionSatisfactions) - throws CreateUnvalidatedException { + List criterionSatisfactions) { for (CriterionSatisfactionDTO criterionSatisfactionDTO : criterionSatisfactions) { @@ -112,30 +114,56 @@ public class ResourceConverter { } private static CriterionSatisfaction toEntity( - CriterionSatisfactionDTO criterionSatisfactionDTO, Resource resource) - throws CreateUnvalidatedException { + CriterionSatisfactionDTO criterionSatisfactionDTO, Resource resource) { - return CriterionSatisfaction.createUnvalidated( - StringUtils.trim(criterionSatisfactionDTO.code), - StringUtils.trim(criterionSatisfactionDTO.criterionTypeName), - StringUtils.trim(criterionSatisfactionDTO.criterionName), - resource, - DateConverter.toDate(criterionSatisfactionDTO.startDate), - DateConverter.toDate(criterionSatisfactionDTO.endDate)); + if (StringUtils.isBlank(criterionSatisfactionDTO.criterionTypeName)) { + throw new ValidationException( + _("criterion type name not specified")); + } + + if (StringUtils.isBlank(criterionSatisfactionDTO.criterionName)) { + throw new ValidationException( + _("criterion name not specified")); + } + + try { + + return CriterionSatisfaction.createUnvalidated( + StringUtils.trim(criterionSatisfactionDTO.code), + StringUtils.trim(criterionSatisfactionDTO.criterionTypeName), + StringUtils.trim(criterionSatisfactionDTO.criterionName), + resource, + DateConverter.toDate(criterionSatisfactionDTO.startDate), + DateConverter.toDate(criterionSatisfactionDTO.endDate)); + + } catch (InstanceNotFoundException e) { + + if (e.getClassName().equals(CriterionType.class.getName())) { + throw new InstanceNotFoundRecoverableErrorException( + CriterionTypeDTO.ENTITY_TYPE, e.getKey().toString()); + } else { + throw new InstanceNotFoundRecoverableErrorException( + CriterionDTO.ENTITY_TYPE, e.getKey().toString()); + } + + } } private static void setResourceCalendar(Resource resource, - String calendarName) throws CreateUnvalidatedException { + String calendarName) { try { resource.setResourceCalendar(calendarName); } catch (InstanceNotFoundException e) { - throw new CreateUnvalidatedException( - _("{0}: calendar not found", calendarName)); + throw new InstanceNotFoundRecoverableErrorException( + "resource-calendar", e.getKey().toString()); + // TODO: literal "resource-calendar" should possibly be + // replaced by ResourceCalendarDTO.ENTITY_TYPE if + // ResourceCalendarDTO is created in the future. } catch (MultipleInstancesException e) { - throw new CreateUnvalidatedException( - _("there exist multiple calendars with name {0}", + throw new ValidationException( + _("there exist multiple resource calendars with name {0}", calendarName)); } @@ -143,8 +171,7 @@ public class ResourceConverter { private static void addResourcesCostCategoryAssignments( Resource resource, List - resourcesCostCategoryAssignments) - throws CreateUnvalidatedException { + resourcesCostCategoryAssignments) { for (ResourcesCostCategoryAssignmentDTO assignmentDTO : resourcesCostCategoryAssignments) { @@ -158,13 +185,25 @@ public class ResourceConverter { } private static ResourcesCostCategoryAssignment toEntity( - ResourcesCostCategoryAssignmentDTO assignmentDTO, Resource resource) - throws CreateUnvalidatedException { + ResourcesCostCategoryAssignmentDTO assignmentDTO, Resource resource) { - return ResourcesCostCategoryAssignment.createUnvalidated( - assignmentDTO.code, assignmentDTO.costCategoryName, resource, - DateConverter.toLocalDate(assignmentDTO.startDate), - DateConverter.toLocalDate(assignmentDTO.endDate)); + if (StringUtils.isBlank(assignmentDTO.costCategoryName)) { + throw new ValidationException( + _("cost category name not specified")); + } + + try { + return ResourcesCostCategoryAssignment.createUnvalidated( + assignmentDTO.code, assignmentDTO.costCategoryName, resource, + DateConverter.toLocalDate(assignmentDTO.startDate), + DateConverter.toLocalDate(assignmentDTO.endDate)); + } catch (InstanceNotFoundException e) { + throw new InstanceNotFoundRecoverableErrorException( + "cost-category", e.getKey().toString()); + // TODO: literal "cost-category" should possibly be replaced by + // CostCategoryDTO.ENTITY_TYPE if CostCategoryDTO is created in the + // future. + } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceServiceREST.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceServiceREST.java index c7609cfa7..2382ae3be 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceServiceREST.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceServiceREST.java @@ -20,35 +20,22 @@ package org.navalplanner.ws.resources.impl; -import static org.navalplanner.web.I18nHelper._; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import org.apache.commons.lang.StringUtils; -import org.navalplanner.business.common.exceptions.CreateUnvalidatedException; +import org.navalplanner.business.common.daos.IIntegrationEntityDAO; import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.business.resources.daos.IResourceDAO; import org.navalplanner.business.resources.entities.Resource; -import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO; import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO; -import org.navalplanner.ws.common.impl.ConstraintViolationConverter; -import org.navalplanner.ws.common.impl.Util; +import org.navalplanner.ws.common.impl.GenericRESTService; import org.navalplanner.ws.resources.api.IResourceService; -import org.navalplanner.ws.resources.api.MachineDTO; import org.navalplanner.ws.resources.api.ResourceDTO; import org.navalplanner.ws.resources.api.ResourceListDTO; -import org.navalplanner.ws.resources.api.WorkerDTO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; /** * REST-based implementation of IResourceService. @@ -58,7 +45,9 @@ import org.springframework.transaction.annotation.Transactional; @Path("/resources/") @Produces("application/xml") @Service("resourceServiceREST") -public class ResourceServiceREST implements IResourceService { +public class ResourceServiceREST + extends GenericRESTService + implements IResourceService { @Autowired private IResourceDAO resourceDAO; @@ -66,117 +55,32 @@ public class ResourceServiceREST implements IResourceService { @Override @POST @Consumes("application/xml") - @Transactional public InstanceConstraintViolationsListDTO addResources( ResourceListDTO resources) { - List instanceConstraintViolationsList = - new ArrayList(); - int instanceNumber = 1; - Set resourceUserProvidedIds = new HashSet(); - - /* Process resources. */ - for (ResourceDTO resourceDTO : resources.resources) { - - InstanceConstraintViolationsDTO instanceConstraintViolationsDTO = - null; - Resource resource = null; - - /* Convert DTO to entity. */ - try { - resource = ResourceConverter.toEntity(resourceDTO); - } catch (CreateUnvalidatedException e) { - instanceConstraintViolationsDTO = - InstanceConstraintViolationsDTO.create( - Util.generateInstanceConstraintViolationsDTOId( - (long) instanceNumber, resourceDTO), - e.getMessage()); - } - - /* Validate resource. */ - if (resource != null) { - try { - - if (resourceUserProvidedIds.contains( - getUserProvidedId(resourceDTO).toLowerCase())) { - - instanceConstraintViolationsDTO = - InstanceConstraintViolationsDTO.create( - Util.generateInstanceConstraintViolationsDTOId( - (long) instanceNumber, resourceDTO), - getDuplicatedImportedResourceErrorMessage( - resourceDTO)); - - } else { - - /* - * See CriterionServiceREST::addCriterionTypes for a - * justification of the explicit use of - * BaseEntity::validate. - * - */ - resource.validate(); - resourceDAO.save(resource); - resourceUserProvidedIds.add( - getUserProvidedId(resourceDTO).toLowerCase()); - - } - - } catch (ValidationException e) { - instanceConstraintViolationsDTO = - ConstraintViolationConverter.toDTO( - Util.generateInstanceConstraintViolationsDTOId( - (long) instanceNumber, resourceDTO), e); - } - } - - /* Add constraint violations (if any). */ - if (instanceConstraintViolationsDTO != null) { - instanceConstraintViolationsList.add( - instanceConstraintViolationsDTO); - } - - instanceNumber++; - - } - - return new InstanceConstraintViolationsListDTO( - instanceConstraintViolationsList); + return save(resources.resources); } - private String getUserProvidedId(ResourceDTO resourceDTO) { - - if (resourceDTO instanceof MachineDTO) { - MachineDTO m = (MachineDTO) resourceDTO; - return "machine" + '-' + StringUtils.trim(m.code); - } else if (resourceDTO instanceof WorkerDTO) { - WorkerDTO w = (WorkerDTO) resourceDTO; - return "worker" + '-' + StringUtils.trim(w.firstName) + - '-' + StringUtils.trim(w.surname) + '-' + - StringUtils.trim(w.nif); - } else { - throw new RuntimeException( - _("Service does not manage resource of type: {0}", - resourceDTO.getClass().getName())); - } - + @Override + protected Resource toEntity(ResourceDTO entityDTO) { + return ResourceConverter.toEntity(entityDTO); } - private String getDuplicatedImportedResourceErrorMessage( - ResourceDTO resourceDTO) { + @Override + protected ResourceDTO toDTO(Resource entity) { + return null; // This service does not provide finder methods. + } - if (resourceDTO instanceof MachineDTO) { - return _("code is used by another machine being imported"); - } else if (resourceDTO instanceof WorkerDTO) { - return _("first name, surname, and nif are used by another " + - "worker being imported"); - } else { - throw new RuntimeException( - _("Service does not manage resource of type: {0}", - resourceDTO.getClass().getName())); - } + @Override + protected IIntegrationEntityDAO getIntegrationEntityDAO() { + return resourceDAO; + } + @Override + protected void updateEntity(Resource entity, ResourceDTO entityDTO) + throws ValidationException { + // FIXME: updated functionality not implemented yet. } } diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/common/Util.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/common/Util.java index 2922c349f..9d016d192 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/common/Util.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/common/Util.java @@ -21,6 +21,7 @@ package org.navalplanner.web.test.ws.common; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.List; @@ -90,6 +91,8 @@ public class Util { assertTrue( instanceConstraintViolationsList.toString(), instanceConstraintViolationsList.size() == 1); + assertNoRecoverableError(instanceConstraintViolationsList.get(0)); + assertNoInternalError(instanceConstraintViolationsList.get(0)); assertNotNull(instanceConstraintViolationsList.get(0). constraintViolations); assertTrue( @@ -115,6 +118,8 @@ public class Util { for (InstanceConstraintViolationsDTO i : instanceConstraintViolationsList) { + assertNoRecoverableError(i); + assertNoInternalError(i); assertNotNull(i.constraintViolations); assertTrue( i.constraintViolations.toString(), @@ -123,4 +128,44 @@ public class Util { } + public static void assertOneRecoverableError( + InstanceConstraintViolationsListDTO + instanceConstraintViolationsListDTO) { + + List instanceConstraintViolationsList = + instanceConstraintViolationsListDTO. + instanceConstraintViolationsList; + + assertNotNull(instanceConstraintViolationsListDTO. + instanceConstraintViolationsList); + assertTrue( + instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + assertNoConstraintViolations(instanceConstraintViolationsList.get(0)); + assertNoInternalError(instanceConstraintViolationsList.get(0)); + assertNotNull(instanceConstraintViolationsList.get(0).recoverableError); + + } + + private static void assertNoConstraintViolations( + InstanceConstraintViolationsDTO i) { + + assertNull(i.toString(), i.constraintViolations); + + } + + private static void assertNoRecoverableError( + InstanceConstraintViolationsDTO i) { + + assertNull(i.toString(), i.recoverableError); + + } + + private static void assertNoInternalError( + InstanceConstraintViolationsDTO i) { + + assertNull(i.toString(), i.internalError); + + } + } diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java index 709796b85..59bad2ac4 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java @@ -26,11 +26,11 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; 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.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_FILE; import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE; import static org.navalplanner.web.test.ws.common.Util.assertNoConstraintViolations; import static org.navalplanner.web.test.ws.common.Util.assertOneConstraintViolation; import static org.navalplanner.web.test.ws.common.Util.assertOneConstraintViolationPerInstance; +import static org.navalplanner.web.test.ws.common.Util.assertOneRecoverableError; import static org.navalplanner.web.test.ws.common.Util.getUniqueName; import java.util.ArrayList; @@ -50,13 +50,11 @@ import org.navalplanner.business.common.IAdHocTransactionService; import org.navalplanner.business.common.IOnTransaction; import org.navalplanner.business.common.daos.IConfigurationDAO; import org.navalplanner.business.common.entities.IConfigurationBootstrap; -import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.costcategories.daos.ICostCategoryDAO; import org.navalplanner.business.costcategories.entities.CostCategory; import org.navalplanner.business.resources.daos.ICriterionTypeDAO; import org.navalplanner.business.resources.daos.IMachineDAO; import org.navalplanner.business.resources.daos.IResourceDAO; -import org.navalplanner.business.resources.daos.IWorkerDAO; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionSatisfaction; import org.navalplanner.business.resources.entities.CriterionType; @@ -73,7 +71,6 @@ import org.navalplanner.ws.resources.api.ResourceListDTO; import org.navalplanner.ws.resources.api.ResourcesCostCategoryAssignmentDTO; import org.navalplanner.ws.resources.api.WorkerDTO; 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; @@ -84,9 +81,8 @@ import org.springframework.transaction.annotation.Transactional; * @author Fernando Bellas Permuy */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, - WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE, - WEBAPP_SPRING_SECURITY_CONFIG_FILE }) +@ContextConfiguration(locations = {BUSINESS_SPRING_CONFIG_FILE, + WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE}) @Transactional public class ResourceServiceTest { @@ -99,9 +95,6 @@ public class ResourceServiceTest { @Autowired private IMachineDAO machineDAO; - @Autowired - private IWorkerDAO workerDAO; - @Autowired private ICriterionTypeDAO criterionTypeDAO; @@ -122,32 +115,40 @@ public class ResourceServiceTest { @Before public void loadConfiguration() { - configurationBootstrap.loadRequiredData(); + + IOnTransaction load = + new IOnTransaction() { + + @Override + public Void execute() { + configurationBootstrap.loadRequiredData(); + return null; + } + }; + + transactionService.runOnAnotherTransaction(load); + } @Test - public void testAddResourcesWithBasicContraintViolations() - throws InstanceNotFoundException { + public void testAddResourcesWithBasicContraintViolations() { /* Create resource DTOs. */ - String m1Code = ' ' + getUniqueName() + ' '; // Blank spaces - // intentionally - // added (OK). - MachineDTO m1 = new MachineDTO(m1Code, "name", "desc"); - MachineDTO m2 = new MachineDTO("", null, ""); // Missing code and name + MachineDTO m1 = new MachineDTO("name", "desc"); + MachineDTO m2 = new MachineDTO(" ", null, ""); // Missing code and name // (description is // optional). - String w1Nif = ' ' + getUniqueName() + ' '; // Blank spaces - // intentionally - // added (OK). - WorkerDTO w1 = new WorkerDTO("w1-first-name", "w1-surname", w1Nif); - WorkerDTO w2 = new WorkerDTO("", null, ""); // Missing first name, - // surname, and nif. + + WorkerDTO w1 = new WorkerDTO(getUniqueName(), "w1-surname", "w1-nif"); + WorkerDTO w2 = new WorkerDTO(null, "", null, ""); // Missing code, first + // name, surname, and + // nif. /* Test. */ List instanceConstraintViolationsList = - resourceService.addResources(createResourceListDTO(m1, m2, w1, w2)). - instanceConstraintViolationsList; + resourceService.addResources( + createResourceListDTO(m1, m2, w1, w2)). + instanceConstraintViolationsList; assertTrue( instanceConstraintViolationsList.toString(), @@ -161,35 +162,13 @@ public class ResourceServiceTest { instanceConstraintViolationsList.get(1). constraintViolations.toString(), instanceConstraintViolationsList.get(1). - constraintViolations.size() == 3); // w2 constraint violations. - machineDAO.findUniqueByCode(m1Code.trim()); - assertTrue( - workerDAO.findByFirstNameSecondNameAndNif( - w1.firstName, w1.surname, w1.nif.trim()).size() == 1); + constraintViolations.size() == 4); // w2 constraint violations. + assertTrue(resourceDAO.existsByCode(m1.code)); + assertTrue(resourceDAO.existsByCode(w1.code)); } @Test - @NotTransactional - public void testAddMachineWithExistingCode() - throws InstanceNotFoundException { - - /* Create a machine. */ - Machine m1 = Machine.createUnvalidated(getUniqueName(), "name", "desc"); - saveResource(m1); - - /* Create a machine DTO with the same code. */ - MachineDTO m2 = new MachineDTO(m1.getCode(), "name", "desc"); - - /* Test. */ - assertOneConstraintViolation( - resourceService.addResources(createResourceListDTO(m2))); - machineDAO.findUniqueByCodeInAnotherTransaction(m1.getCode()); - - } - - @Test - @NotTransactional public void testAddWorkerWithExistingFirstNameSurnameAndNif() { /* Create a worker. */ @@ -207,29 +186,55 @@ public class ResourceServiceTest { /* Test. */ assertOneConstraintViolation( resourceService.addResources(createResourceListDTO(w2))); - assertTrue( - workerDAO.findByFirstNameSecondNameAndNifAnotherTransaction( - w2.firstName, w2.surname, w2.nif).size() == 1); + assertFalse(resourceDAO.existsByCode(w2.code)); } - @Test - public void testAddResourcesWithDuplicateResourcesBeingImported() - throws InstanceNotFoundException { + public void testAddResourceWithCriterionSatisfactions() { - /* Create resource DTOs. */ - MachineDTO m1 = new MachineDTO(getUniqueName(), "m1-name", "m1-desc"); - MachineDTO m2 = new MachineDTO(' ' + m1.code.toUpperCase() + ' ', - "m2-name", "m2-desc"); - WorkerDTO w1 = new WorkerDTO(getUniqueName(), "w1-surname", "w1-nif"); - WorkerDTO w2 = new WorkerDTO(w1.firstName, - ' ' + w1.surname.toUpperCase() + ' ', w1.nif); + /* Create a criterion type. */ + CriterionType ct = createCriterionType(); + + /* Create a resource DTO. */ + MachineDTO m1 = new MachineDTO("name", "desc"); + CriterionSatisfactionDTO cs1m1 = + new CriterionSatisfactionDTO( + ' ' + ct.getName().toUpperCase() + // Upper case and blank + ' ', " C1 ", // spaces intentionally + // added (OK). + getDate(2001, 1, 1), getDate(2001, 2, 1)); + m1.criterionSatisfactions.add(cs1m1); + m1.criterionSatisfactions.add( + new CriterionSatisfactionDTO(ct.getName(), "c2", + getDate(2001, 1, 1), null)); + + MachineDTO m2 = new MachineDTO("name", "desc"); + m2.criterionSatisfactions.add( + new CriterionSatisfactionDTO(cs1m1.code, ct.getName(), "c1", + getDate(2001, 1, 1), null)); // Repeated criterion satisfaction + // code (used by another machine). + m2.criterionSatisfactions.add( + new CriterionSatisfactionDTO(null, ct.getName(), "c2", + getDate(2001, 1, 1), null)); // Missing criterion satisfaction + // code. + + MachineDTO m3 = new MachineDTO("name", "desc"); + CriterionSatisfactionDTO cs1m3 = + new CriterionSatisfactionDTO(ct.getName(), "c1", + getDate(2001, 1, 1), getDate(2001, 2, 1)); + m3.criterionSatisfactions.add(cs1m3); + m3.criterionSatisfactions.add( + new CriterionSatisfactionDTO( + cs1m3.code, // Repeated criterion satisfaction code in this + // machine. + ct.getName(), "c2", + getDate(2001, 1, 1), null)); /* Test. */ List instanceConstraintViolationsList = - resourceService.addResources(createResourceListDTO(m1, m2, w1, w2)). - instanceConstraintViolationsList; + resourceService.addResources(createResourceListDTO(m1, m2, m3)). + instanceConstraintViolationsList; assertTrue( instanceConstraintViolationsList.toString(), @@ -238,49 +243,16 @@ public class ResourceServiceTest { instanceConstraintViolationsList.get(0). constraintViolations.toString(), instanceConstraintViolationsList.get(0). - constraintViolations.size() == 1); + constraintViolations.size() == 2); // m2 constraint violations. assertTrue( instanceConstraintViolationsList.get(1). constraintViolations.toString(), instanceConstraintViolationsList.get(1). - constraintViolations.size() == 1); - machineDAO.findUniqueByCode(m1.code); - assertTrue( - workerDAO.findByFirstNameSecondNameAndNif( - w1.firstName, w1.surname, w1.nif.trim()).size() == 1); + constraintViolations.size() == 1); // m3 constraint violations. + assertFalse(resourceDAO.existsByCode(m2.code)); + assertFalse(resourceDAO.existsByCode(m3.code)); - } - - @Test - @NotTransactional - public void testAddResourceWithCriterionSatisfactions() - throws InstanceNotFoundException { - - /* Create a criterion type. */ - CriterionType ct = createCriterionType(); - - /* Create a resource DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); - machineDTO.criterionSatisfactions.add( - new CriterionSatisfactionDTO( - ' ' + ct.getName().toUpperCase() + // Upper case and blank - ' ', " C1 ", // spaces intentionally - // added (OK). - getDate(2001, 1, 1), getDate(2001, 2, 1))); - machineDTO.criterionSatisfactions.add( - new CriterionSatisfactionDTO(ct.getName(), "c2", - getDate(2001, 1, 1), null)); - - /* Test. */ - List instanceConstraintViolationsList = - resourceService.addResources(createResourceListDTO(machineDTO)). - instanceConstraintViolationsList; - - assertTrue( - instanceConstraintViolationsList.toString(), - instanceConstraintViolationsList.isEmpty()); - - Machine machine = findUniqueMachineByCodeInitialized(machineDTO.code); + Machine machine = machineDAO.findExistingEntityByCode(m1.code); assertTrue(machine.getCriterionSatisfactions().size() == 2); for (CriterionSatisfaction cs : machine.getCriterionSatisfactions()) { @@ -290,17 +262,18 @@ public class ResourceServiceTest { } } + assertFalse(resourceDAO.existsByCode(m2.code)); + } @Test - @NotTransactional public void testAddResourceWithCriterionSatisfactionWithoutStartDate() { /* Create a criterion type. */ CriterionType ct = createCriterionType(); /* Create a machine DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); + MachineDTO machineDTO = new MachineDTO("name", "desc"); machineDTO.criterionSatisfactions.add( new CriterionSatisfactionDTO(ct.getName() , "c1", null, getDate(2001, 1, 1))); // Missing start date. @@ -308,20 +281,18 @@ public class ResourceServiceTest { /* Test. */ assertOneConstraintViolation( resourceService.addResources(createResourceListDTO(machineDTO))); - assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @Test - @NotTransactional public void testAddResourceWithCriterionSatisfactionWithNegativeInterval() { /* Create a criterion type. */ CriterionType ct = createCriterionType(); /* Create a machine DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); + MachineDTO machineDTO = new MachineDTO("name", "desc"); machineDTO.criterionSatisfactions.add( new CriterionSatisfactionDTO(ct.getName() , "c1", getDate(2000, 2, 1), getDate(2000, 1, 1))); @@ -329,13 +300,11 @@ public class ResourceServiceTest { /* Test. */ assertOneConstraintViolation( resourceService.addResources(createResourceListDTO(machineDTO))); - assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @Test - @NotTransactional public void testAddResourceWithOverlappingCriterionSatisfactionsAllowed() { /* Create a criterion type. */ @@ -353,13 +322,11 @@ public class ResourceServiceTest { /* Test. */ assertNoConstraintViolations( resourceService.addResources(createResourceListDTO(machineDTO))); - assertTrue(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); + assertTrue(resourceDAO.existsByCode(machineDTO.code)); } @Test - @NotTransactional public void testAddResourceWithOverlappingCriterionSatisfactions() { /* Create criterion types. */ @@ -395,22 +362,20 @@ public class ResourceServiceTest { MachineDTO m = (MachineDTO) r; assertFalse( "Machine " + m.name + " not expected", - machineDAO.existsMachineWithCodeInAnotherTransaction( - ((MachineDTO) r).code)); + resourceDAO.existsByCode(((MachineDTO) r).code)); } } @Test - @NotTransactional - public void testAddResourcesWithCriterionSatisfactionsWithIncorrectType() { + public void testAddResourcesWithCriterionSatisfactionsWithIncorrectCriterionType() { /* Create two criterion types. */ CriterionType machineCt = createCriterionType(ResourceEnum.MACHINE); CriterionType workerCt = createCriterionType(ResourceEnum.WORKER); /* Create resource DTOs. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); + MachineDTO machineDTO = new MachineDTO("name", "desc"); machineDTO.criterionSatisfactions.add( new CriterionSatisfactionDTO(workerCt.getName() , "c1", getDate(2001, 1, 1), null)); // Incorrect type. @@ -422,158 +387,29 @@ public class ResourceServiceTest { /* Test. */ assertOneConstraintViolation( resourceService.addResources(createResourceListDTO(machineDTO))); - assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); + assertFalse( + resourceDAO.existsByCode(machineDTO.code)); assertOneConstraintViolation( resourceService.addResources(createResourceListDTO(workerDTO))); - assertTrue(workerDAO.findByFirstNameSecondNameAndNifAnotherTransaction( - workerDTO.firstName, workerDTO.surname, workerDTO.nif).size() == 0); + assertFalse(resourceDAO.existsByCode(workerDTO.code)); } @Test - @NotTransactional - public void testAddResourcesWithCriterionSatisfactionsWithIncorrectNames() { + public void testAddResourcesWithCriterionSatisfactionsWithMissingNames() { /* Create a criterion type. */ CriterionType ct = createCriterionType(); /* Create machines DTOs. */ - MachineDTO m1 = new MachineDTO(getUniqueName(), "m1", "desc"); + MachineDTO m1 = new MachineDTO("m1", "desc"); m1.criterionSatisfactions.add( new CriterionSatisfactionDTO("", "X", // Missing criterion type. getDate(2001, 1, 1), null)); - MachineDTO m2 = new MachineDTO(getUniqueName(), "m2", "desc"); + MachineDTO m2 = new MachineDTO("m2", "desc"); m2.criterionSatisfactions.add( new CriterionSatisfactionDTO(ct.getName(), // Missing criterion. null, getDate(2001, 1, 1), null)); - MachineDTO m3 = new MachineDTO(getUniqueName(), "m3", "desc"); - m3.criterionSatisfactions.add( - new CriterionSatisfactionDTO( - ct.getName() + 'X', // Non-existent criterion type. - "c1", getDate(2001, 1, 1), null)); - MachineDTO m4 = new MachineDTO(getUniqueName(), "m4", "desc"); - m4.criterionSatisfactions.add( - new CriterionSatisfactionDTO( - ct.getName(), - "c1" + 'X', // Criterion name is not of ct's type. - getDate(2001, 1, 1), null)); - - /* Test. */ - ResourceListDTO resourceDTOs = createResourceListDTO(m1, m2, m3, m4); - - assertOneConstraintViolationPerInstance( - resourceService.addResources(resourceDTOs), - resourceDTOs.resources.size()); - - for (ResourceDTO r : resourceDTOs.resources) { - MachineDTO m = (MachineDTO) r; - assertFalse( - "Machine " + m.name + " not expected", - machineDAO.existsMachineWithCodeInAnotherTransaction( - ((MachineDTO) r).code)); - } - - } - - @Test - @NotTransactional - public void testAddResourceWithDefaultCalendar() - throws InstanceNotFoundException { - - /* Create a machine DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); - - /* Test. */ - assertNoConstraintViolations(resourceService. - addResources(createResourceListDTO(machineDTO))); - Machine machine = findUniqueMachineByCodeInitialized(machineDTO.code); - assertEquals(getDefaultCalendar().getId(), - machine.getCalendar().getParent().getId()); - - } - - @Test - @NotTransactional - public void testAddResourceWithSpecificCalendar() - throws InstanceNotFoundException { - - /* Create a base calendar. */ - BaseCalendar baseCalendar = createBaseCalendar(); - - /* Create a machine DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); - machineDTO.calendarName = - ' ' + baseCalendar.getName().toUpperCase() + ' '; - - /* Test. */ - assertNoConstraintViolations(resourceService. - addResources(createResourceListDTO(machineDTO))); - Machine machine = findUniqueMachineByCodeInitialized(machineDTO.code); - assertEquals(baseCalendar.getId(), - machine.getCalendar().getParent().getId()); - - } - - @Test - @NotTransactional - public void testAddResourceWithNonExistentCalendar() - throws InstanceNotFoundException { - - /* Create a machine DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); - machineDTO.calendarName = getUniqueName(); - - /* Test. */ - assertOneConstraintViolation(resourceService. - addResources(createResourceListDTO(machineDTO))); - assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); - - } - - @Test - @NotTransactional - public void testAddResourceWithCostAssignments() { - - /* Create a CostCategory. */ - CostCategory costCategory = createCostCategory(); - - /* Create resource DTOs. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); - machineDTO.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - ' ' + costCategory.getName().toUpperCase() + ' ', - getDate(2001, 1, 1), null)); - machineDTO.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - costCategory.getName(), - getDate(2000, 1, 1), getDate(2000, 4, 1))); - - /* Test. */ - assertNoConstraintViolations( - resourceService.addResources(createResourceListDTO(machineDTO))); - assertTrue(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); - - } - - @Test - @NotTransactional - public void testAddResourcesWithCostAssignmentWithIncorrectCategoryNames() { - - /* Create a resource DTOs. */ - MachineDTO m1 = new MachineDTO(getUniqueName(), "m1", "desc"); - m1.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - null, // Cost category not specified. - getDate(2000, 1, 1), null)); - - MachineDTO m2 = new MachineDTO(getUniqueName(), "m2", "desc"); - m2.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - getUniqueName(), // Non-existent cost category. - getDate(2000, 1, 1), null)); /* Test. */ ResourceListDTO resourceDTOs = createResourceListDTO(m1, m2); @@ -586,20 +422,200 @@ public class ResourceServiceTest { MachineDTO m = (MachineDTO) r; assertFalse( "Machine " + m.name + " not expected", - machineDAO.existsMachineWithCodeInAnotherTransaction(m.code)); - }; + resourceDAO.existsByCode(((MachineDTO) r).code)); + } + + } + + @Test + public void testAddResourceWithCriterionSatisfactionsWithNonExistentCriterionType() { + + /* Create a machine DTO. */ + MachineDTO machineDTO = new MachineDTO("name", "desc"); + machineDTO.criterionSatisfactions.add( + new CriterionSatisfactionDTO(getUniqueName() , "c1", + getDate(2000, 1, 1), null)); + + /* Test. */ + assertOneRecoverableError( + resourceService.addResources(createResourceListDTO(machineDTO))); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); + + } + + @Test + public void testAddResourceWithCriterionSatisfactionsWithNonExistentCriterion() { + + /* Create a criterion type. */ + CriterionType ct = createCriterionType(); + + /* Create a machine DTO. */ + MachineDTO machineDTO = new MachineDTO("name", "desc"); + machineDTO.criterionSatisfactions.add( + new CriterionSatisfactionDTO(ct.getName(), getUniqueName(), + getDate(2000, 1, 1), null)); + + /* Test. */ + assertOneRecoverableError( + resourceService.addResources(createResourceListDTO(machineDTO))); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); + + } + + @Test + public void testAddResourceWithDefaultCalendar() { + + /* Create a machine DTO. */ + MachineDTO machineDTO = new MachineDTO("name", "desc"); + + /* Test. */ + assertNoConstraintViolations(resourceService. + addResources(createResourceListDTO(machineDTO))); + Machine machine = machineDAO.findExistingEntityByCode(machineDTO.code); + assertEquals(getDefaultCalendar().getId(), + machine.getCalendar().getParent().getId()); + + } + + @Test + public void testAddResourceWithSpecificCalendar() { + + /* Create a base calendar. */ + BaseCalendar baseCalendar = createBaseCalendar(); + + /* Create a machine DTO. */ + MachineDTO machineDTO = new MachineDTO("name", "desc"); + machineDTO.calendarName = + ' ' + baseCalendar.getName().toUpperCase() + ' '; + + /* Test. */ + assertNoConstraintViolations(resourceService. + addResources(createResourceListDTO(machineDTO))); + Machine machine = machineDAO.findExistingEntityByCode(machineDTO.code); + assertEquals(baseCalendar.getId(), + machine.getCalendar().getParent().getId()); + + } + + @Test + public void testAddResourceWithNonExistentCalendar() { + + /* Create a machine DTO. */ + MachineDTO machineDTO = new MachineDTO("name", "desc"); + machineDTO.calendarName = getUniqueName(); + + /* Test. */ + assertOneRecoverableError(resourceService. + addResources(createResourceListDTO(machineDTO))); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); + + } + + @Test + public void testAddResourceWithCostAssignments() { + + /* Create a CostCategory. */ + CostCategory costCategory = createCostCategory(); + + /* Create resource DTOs. */ + MachineDTO m1 = new MachineDTO("name", "desc"); + ResourcesCostCategoryAssignmentDTO a1m1 = + new ResourcesCostCategoryAssignmentDTO( + ' ' + costCategory.getName().toUpperCase() + ' ', + getDate(2001, 1, 1), null); + m1.resourcesCostCategoryAssignments.add(a1m1); + m1.resourcesCostCategoryAssignments.add( + new ResourcesCostCategoryAssignmentDTO( + costCategory.getName(), + getDate(2000, 1, 1), getDate(2000, 4, 1))); + + MachineDTO m2 = new MachineDTO("name", "desc"); + m2.resourcesCostCategoryAssignments.add( + new ResourcesCostCategoryAssignmentDTO(a1m1.code, + costCategory.getName().toUpperCase(), + getDate(2001, 1, 1), null)); // Repeated assignment code + // (used by another machine). + m2.resourcesCostCategoryAssignments.add( + new ResourcesCostCategoryAssignmentDTO(null, + costCategory.getName().toUpperCase(), + getDate(2000, 1, 1), getDate(2000, 4, 1))); // Missing + // assignment code. + + MachineDTO m3 = new MachineDTO("name", "desc"); + ResourcesCostCategoryAssignmentDTO a1m3 = + new ResourcesCostCategoryAssignmentDTO(costCategory.getName(), + getDate(2001, 1, 1), null); + m3.resourcesCostCategoryAssignments.add(a1m3); + m3.resourcesCostCategoryAssignments.add( + new ResourcesCostCategoryAssignmentDTO( + a1m3.code, // Repeated assignment code in this machine. + costCategory.getName(), + getDate(2000, 1, 1), getDate(2000, 4, 1))); + + /* Test. */ + List instanceConstraintViolationsList = + resourceService.addResources(createResourceListDTO(m1, m2, m3)). + instanceConstraintViolationsList; + + assertTrue( + instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 2); + assertTrue( + instanceConstraintViolationsList.get(0). + constraintViolations.toString(), + instanceConstraintViolationsList.get(0). + constraintViolations.size() == 2); // m2 constraint violations. + assertTrue( + instanceConstraintViolationsList.get(1). + constraintViolations.toString(), + instanceConstraintViolationsList.get(1). + constraintViolations.size() == 1); // m3 constraint violations. + + assertTrue(resourceDAO.existsByCode(m1.code)); + assertFalse(resourceDAO.existsByCode(m2.code)); + + } + + @Test + public void testAddResourcesWithCostAssignmentWithMissingCostCategoryName() { + + /* Create a resource DTO. */ + MachineDTO machineDTO = new MachineDTO("name", "desc"); + machineDTO.resourcesCostCategoryAssignments.add( + new ResourcesCostCategoryAssignmentDTO( + "", null, getDate(2000, 1, 1), null)); + + /* Test. */ + assertOneConstraintViolation( + resourceService.addResources(createResourceListDTO(machineDTO))); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); + + } + + @Test + public void testAddResourcesWithCostAssignmentWithNonExistentCostCategory() { + + /* Create a resource DTO. */ + MachineDTO machineDTO = new MachineDTO("name", "desc"); + machineDTO.resourcesCostCategoryAssignments.add( + new ResourcesCostCategoryAssignmentDTO( + getUniqueName(), getDate(2000, 1, 1), null)); + + /* Test. */ + assertOneRecoverableError( + resourceService.addResources(createResourceListDTO(machineDTO))); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @Test - @NotTransactional public void testAddResourceWithCostAssignmentWithoutStartDate() { /* Create a CostCategory. */ CostCategory costCategory = createCostCategory(); /* Create a resource DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); + MachineDTO machineDTO = new MachineDTO("name", "desc"); machineDTO.resourcesCostCategoryAssignments.add( new ResourcesCostCategoryAssignmentDTO( costCategory.getName(), null, // Start date not specified. @@ -608,20 +624,18 @@ public class ResourceServiceTest { /* Test. */ assertOneConstraintViolation( resourceService.addResources(createResourceListDTO(machineDTO))); - assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @Test - @NotTransactional public void testAddResourceWithCostAssignmentWithNegativeInterval() { /* Create a CostCategory. */ CostCategory costCategory = createCostCategory(); /* Create a resource DTO. */ - MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc"); + MachineDTO machineDTO = new MachineDTO("name", "desc"); machineDTO.resourcesCostCategoryAssignments.add( new ResourcesCostCategoryAssignmentDTO( costCategory.getName(), @@ -630,13 +644,11 @@ public class ResourceServiceTest { /* Test. */ assertOneConstraintViolation( resourceService.addResources(createResourceListDTO(machineDTO))); - assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction( - machineDTO.code)); + assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @Test - @NotTransactional public void testAddResourcesWithOverlappingInCostAssignments() { /* Create a CostCategory. */ @@ -703,8 +715,7 @@ public class ResourceServiceTest { MachineDTO m = (MachineDTO) r; assertFalse( "Machine " + m.name + " not expected", - machineDAO.existsMachineWithCodeInAnotherTransaction( - ((MachineDTO) r).code)); + resourceDAO.existsByCode(((MachineDTO) r).code)); } } @@ -742,45 +753,7 @@ public class ResourceServiceTest { } }; - return transactionService.runOnTransaction(createCriterionType); - - } - - private Machine findUniqueMachineByCodeInitialized(final String code) - throws InstanceNotFoundException { - - IOnTransaction find = new IOnTransaction() { - - @Override - public Machine execute() { - try { - return (Machine) initializeResource( - machineDAO.findUniqueByCode(code)); - } catch (InstanceNotFoundException e) { - return null; - } - } - }; - - Machine machine = transactionService.runOnTransaction(find); - - if (machine == null) { - throw new InstanceNotFoundException(code, Machine.class.getName()); - } else { - return machine; - } - - } - - private Resource initializeResource(Resource resource) { - - for (CriterionSatisfaction cs : resource.getCriterionSatisfactions()) { - cs.getCriterion().getType().getName(); - } - - resource.getCalendar().getParent(); - - return resource; + return transactionService.runOnAnotherTransaction(createCriterionType); } @@ -795,7 +768,7 @@ public class ResourceServiceTest { } }; - transactionService.runOnTransaction(save); + transactionService.runOnAnotherTransaction(save); } @@ -809,7 +782,7 @@ public class ResourceServiceTest { } }; - return transactionService.runOnTransaction(find); + return transactionService.runOnAnotherTransaction(find); } @@ -827,7 +800,7 @@ public class ResourceServiceTest { } }; - return transactionService.runOnTransaction(create); + return transactionService.runOnAnotherTransaction(create); } @@ -858,7 +831,7 @@ public class ResourceServiceTest { } }; - return transactionService.runOnTransaction(create); + return transactionService.runOnAnotherTransaction(create); } @@ -870,8 +843,7 @@ public class ResourceServiceTest { String criterionName2, XMLGregorianCalendar startDate2, XMLGregorianCalendar endDate2) { - MachineDTO machineDTO = new MachineDTO(getUniqueName(), machineName, - "desc"); + MachineDTO machineDTO = new MachineDTO(machineName, "desc"); machineDTO.criterionSatisfactions.add( new CriterionSatisfactionDTO(criterionTypeName, criterionName1, @@ -889,8 +861,7 @@ public class ResourceServiceTest { XMLGregorianCalendar startDate1, XMLGregorianCalendar endDate1, XMLGregorianCalendar startDate2, XMLGregorianCalendar endDate2) { - MachineDTO machineDTO = new MachineDTO(getUniqueName(), machineName, - "desc"); + MachineDTO machineDTO = new MachineDTO(machineName, "desc"); machineDTO.resourcesCostCategoryAssignments.add( new ResourcesCostCategoryAssignmentDTO( diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java index 4f6041350..34056c363 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java @@ -47,7 +47,6 @@ import org.navalplanner.ws.resources.criterion.api.CriterionTypeDTO; import org.navalplanner.ws.resources.criterion.api.CriterionTypeListDTO; import org.navalplanner.ws.resources.criterion.api.ICriterionService; 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; @@ -59,7 +58,7 @@ import org.springframework.transaction.annotation.Transactional; */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, - WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE }) + WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE }) @Transactional public class CriterionServiceTest { @@ -70,7 +69,6 @@ public class CriterionServiceTest { private ICriterionTypeDAO criterionTypeDAO; @Test - @NotTransactional public void testAddAndGetCriterionTypes() { /* Build criterion type "ct1" (5 constraint violations). */ @@ -100,8 +98,7 @@ public class CriterionServiceTest { ct1Criterions.add(ct1c3); ct1Criterions.add(ct1c4); ct1Criterions.add(ct1c5); - String ct1Name = null; - CriterionTypeDTO ct1 = new CriterionTypeDTO(ct1Name, "desc", + CriterionTypeDTO ct1 = new CriterionTypeDTO(null, "desc", false, true, true, ResourceEnumDTO.RESOURCE, // Missing criterion ct1Criterions); // type name. @@ -118,8 +115,7 @@ public class CriterionServiceTest { List ct2Criterions = new ArrayList(); ct2Criterions.add(ct2c1); ct2Criterions.add(ct2c2); - String ct2Name = getUniqueName(); - CriterionTypeDTO ct2 = new CriterionTypeDTO(ct2Name, "desc", + CriterionTypeDTO ct2 = new CriterionTypeDTO(getUniqueName(), "desc", true, true, false, ResourceEnumDTO.RESOURCE, ct2Criterions); /* Build criterion type "ct3" (OK). */ @@ -134,14 +130,13 @@ public class CriterionServiceTest { List ct3Criterions = new ArrayList(); ct3Criterions.add(ct3c1); ct3Criterions.add(ct3c2); - String ct3Name = getUniqueName(); - CriterionTypeDTO ct3 = new CriterionTypeDTO(ct3Name, "desc", + CriterionTypeDTO ct3 = new CriterionTypeDTO(getUniqueName(), "desc", true, true, true, ResourceEnumDTO.RESOURCE, ct3Criterions); /* Build criterion type "ct4" (1 constraint violation). */ CriterionTypeDTO ct4 = new CriterionTypeDTO( // Repeated criterion - ' ' + ct3Name.toUpperCase() + ' ', // type name. + ' ' + ct3.name.toUpperCase() + ' ', // type name. "desc", true, true, true, ResourceEnumDTO.RESOURCE, new ArrayList()); @@ -154,9 +149,19 @@ public class CriterionServiceTest { CriterionTypeDTO ct5 = new CriterionTypeDTO(getUniqueName(), "desc", true, true, true, ResourceEnumDTO.RESOURCE, ct5Criterions); + /* Build criterion type "ct6" (2 constraint violations). */ + CriterionDTO ct6c1 = new CriterionDTO(null, // Missing criterion code. + "c1", true, new ArrayList()); + List ct6Criterions = new ArrayList(); + ct6Criterions.add(ct6c1); + CriterionTypeDTO ct6 = + new CriterionTypeDTO(null, getUniqueName(), // Missing criterion + // type code. + "desc", true, true, true, ResourceEnumDTO.RESOURCE, ct6Criterions); + /* Criterion type list. */ CriterionTypeListDTO criterionTypes = - createCriterionTypeListDTO(ct1, ct2, ct3, ct4, ct5); + createCriterionTypeListDTO(ct1, ct2, ct3, ct4, ct5, ct6); List instanceConstraintViolationsList = criterionService.addCriterionTypes(criterionTypes). @@ -164,40 +169,47 @@ public class CriterionServiceTest { assertTrue( instanceConstraintViolationsList.toString(), - instanceConstraintViolationsList.size() == 4); + instanceConstraintViolationsList.size() == 5); assertTrue( instanceConstraintViolationsList.get(0). constraintViolations.toString(), instanceConstraintViolationsList.get(0). - constraintViolations.size() == 5); + constraintViolations.size() == 5); // ct1 constraint violations. assertTrue( instanceConstraintViolationsList.get(1). constraintViolations.toString(), instanceConstraintViolationsList.get(1). - constraintViolations.size() == 2); + constraintViolations.size() == 2); // ct2 constraint violations. assertTrue( instanceConstraintViolationsList.get(2). constraintViolations.toString(), instanceConstraintViolationsList.get(2). - constraintViolations.size() == 1); + constraintViolations.size() == 1); // ct4 constraint violations. assertTrue( instanceConstraintViolationsList.get(3). constraintViolations.toString(), instanceConstraintViolationsList.get(3). - constraintViolations.size() == 1); + constraintViolations.size() == 1); // ct5 constraint violations. + assertTrue( + instanceConstraintViolationsList.get(4). + constraintViolations.toString(), + instanceConstraintViolationsList.get(4). + constraintViolations.size() == 2); // ct6 constraint violations. /* Find criterion types. */ List returnedCriterionTypes = criterionService.getCriterionTypes().criterionTypes; - assertFalse(containsCriterionType(returnedCriterionTypes, ct1Name)); - assertFalse(containsCriterionType(returnedCriterionTypes, ct2Name)); - assertTrue(containsCriterionType(returnedCriterionTypes, ct3Name)); + /* Test. */ + assertFalse(criterionTypeDAO.existsByCode(ct2.code)); + assertTrue(criterionTypeDAO.existsByCode(ct3.code)); + assertFalse(criterionTypeDAO.existsByCode(ct4.code)); + + assertTrue(containsCriterionType(returnedCriterionTypes, ct3.code)); } @Test - @Transactional public void testUpdateCriterionType() throws InstanceNotFoundException { /* Build criterion type with criteria: c1, c2->c2-1. */ @@ -286,10 +298,10 @@ public class CriterionServiceTest { } private boolean containsCriterionType( - List criterionTypes, String criterionTypeName) { + List criterionTypes, String code) { for (CriterionTypeDTO c : criterionTypes) { - if (c.name.equals(criterionTypeName)) { + if (c.code.equals(code)) { return true; } } diff --git a/scripts/rest-clients/resources-sample.xml b/scripts/rest-clients/resources-sample.xml index ef71f7cd7..fc7a00274 100644 --- a/scripts/rest-clients/resources-sample.xml +++ b/scripts/rest-clients/resources-sample.xml @@ -24,35 +24,51 @@ - - - - - - - + - + + + + + + + + + + + + + @@ -106,7 +122,8 @@ - + + + @@ -290,8 +316,22 @@ - + + + + + + + + + + +