ItEr42S12CUImportacionRecursosProductivosItEr41S15: Detection of resoures with hthe same "logical" name among the resources being imported.
Resources with the same "logical" name (code for machines; first name, surnamne, and nif for workers) among the list of resources *being imported* are detected. This detection must be implemented at the service-level (at the entity-level, @AssertTrue annotations in Machine and Worker detect importation of resources with the same logical name as other resources already existing in the *database*). A test case has been added (furthermore, ResourceServiceTest has been refactorized a little bit).
This commit is contained in:
parent
85dc8d240e
commit
1a12344ce5
7 changed files with 149 additions and 115 deletions
|
|
@ -824,7 +824,7 @@ public abstract class Resource extends BaseEntity{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AssertTrue(message="There are criterion satisfactions referring to " +
|
@AssertTrue(message="there are criterion satisfactions referring to " +
|
||||||
"criterion types not applicable to this resource")
|
"criterion types not applicable to this resource")
|
||||||
public boolean checkConstraintCriterionSatisfactionsWithCorrectType() {
|
public boolean checkConstraintCriterionSatisfactionsWithCorrectType() {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,4 @@ public class MachineDTO extends ResourceDTO {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUserProvidedId() {
|
|
||||||
return "machine" + '-' + code;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,4 @@ public abstract class ResourceDTO {
|
||||||
public List<CriterionSatisfactionDTO> criterionSatisfactions =
|
public List<CriterionSatisfactionDTO> criterionSatisfactions =
|
||||||
new ArrayList<CriterionSatisfactionDTO>();
|
new ArrayList<CriterionSatisfactionDTO>();
|
||||||
|
|
||||||
public abstract String getUserProvidedId();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,4 @@ public class WorkerDTO extends ResourceDTO {
|
||||||
this.nif = nif;
|
this.nif = nif;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUserProvidedId() {
|
|
||||||
|
|
||||||
return "worker" + '-' + firstName + '-' + surname + '-' + nif;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,19 @@
|
||||||
|
|
||||||
package org.navalplanner.ws.resources.impl;
|
package org.navalplanner.ws.resources.impl;
|
||||||
|
|
||||||
|
import static org.navalplanner.web.I18nHelper._;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.navalplanner.business.common.exceptions.CreateUnvalidatedException;
|
import org.navalplanner.business.common.exceptions.CreateUnvalidatedException;
|
||||||
import org.navalplanner.business.common.exceptions.ValidationException;
|
import org.navalplanner.business.common.exceptions.ValidationException;
|
||||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||||
|
|
@ -37,8 +42,10 @@ import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO;
|
||||||
import org.navalplanner.ws.common.impl.ConstraintViolationConverter;
|
import org.navalplanner.ws.common.impl.ConstraintViolationConverter;
|
||||||
import org.navalplanner.ws.common.impl.Util;
|
import org.navalplanner.ws.common.impl.Util;
|
||||||
import org.navalplanner.ws.resources.api.IResourceService;
|
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.ResourceDTO;
|
||||||
import org.navalplanner.ws.resources.api.ResourceListDTO;
|
import org.navalplanner.ws.resources.api.ResourceListDTO;
|
||||||
|
import org.navalplanner.ws.resources.api.WorkerDTO;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
@ -66,6 +73,7 @@ public class ResourceServiceREST implements IResourceService {
|
||||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
|
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
|
||||||
new ArrayList<InstanceConstraintViolationsDTO>();
|
new ArrayList<InstanceConstraintViolationsDTO>();
|
||||||
int instanceNumber = 1;
|
int instanceNumber = 1;
|
||||||
|
Set<String> resourceUserProvidedIds = new HashSet<String>();
|
||||||
|
|
||||||
/* Process resources. */
|
/* Process resources. */
|
||||||
for (ResourceDTO resourceDTO : resources.resources) {
|
for (ResourceDTO resourceDTO : resources.resources) {
|
||||||
|
|
@ -81,7 +89,7 @@ public class ResourceServiceREST implements IResourceService {
|
||||||
instanceConstraintViolationsDTO =
|
instanceConstraintViolationsDTO =
|
||||||
InstanceConstraintViolationsDTO.create(
|
InstanceConstraintViolationsDTO.create(
|
||||||
Util.generateInstanceId(instanceNumber,
|
Util.generateInstanceId(instanceNumber,
|
||||||
resourceDTO.getUserProvidedId()),
|
getUserProvidedId(resourceDTO)),
|
||||||
e.getMessage());
|
e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,20 +97,36 @@ public class ResourceServiceREST implements IResourceService {
|
||||||
if (resource != null) {
|
if (resource != null) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
/*
|
if (resourceUserProvidedIds.contains(
|
||||||
* See CriterionServiceREST::addCriterionTypes for a
|
getUserProvidedId(resourceDTO).toLowerCase())) {
|
||||||
* justification of the explicit use of
|
|
||||||
* BaseEntity::validate.
|
instanceConstraintViolationsDTO =
|
||||||
*
|
InstanceConstraintViolationsDTO.create(
|
||||||
*/
|
Util.generateInstanceId(instanceNumber,
|
||||||
resource.validate();
|
getUserProvidedId(resourceDTO)),
|
||||||
resourceDAO.save(resource);
|
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) {
|
} catch (ValidationException e) {
|
||||||
instanceConstraintViolationsDTO =
|
instanceConstraintViolationsDTO =
|
||||||
ConstraintViolationConverter.toDTO(
|
ConstraintViolationConverter.toDTO(
|
||||||
Util.generateInstanceId(instanceNumber,
|
Util.generateInstanceId(instanceNumber,
|
||||||
resourceDTO.getUserProvidedId()),
|
getUserProvidedId(resourceDTO)),
|
||||||
e.getInvalidValues());
|
e.getInvalidValues());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,4 +146,38 @@ public class ResourceServiceREST implements IResourceService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 manages resource of type: {0}",
|
||||||
|
resourceDTO.getClass().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDuplicatedImportedResourceErrorMessage(
|
||||||
|
ResourceDTO resourceDTO) {
|
||||||
|
|
||||||
|
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 manages resource of type: {0}",
|
||||||
|
resourceDTO.getClass().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,79 @@ public class ResourceServiceTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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. */
|
||||||
|
Worker w1 = Worker.createUnvalidated(getUniqueName(), "surname", "nif");
|
||||||
|
saveResource(w1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a worker DTO with the same first name, surname, and nif as
|
||||||
|
* the previous one.
|
||||||
|
*/
|
||||||
|
WorkerDTO w2 = new WorkerDTO(w1.getFirstName(), w1.getSurname(),
|
||||||
|
w1.getNif());
|
||||||
|
|
||||||
|
/* Test. */
|
||||||
|
assertOneConstraintViolation(
|
||||||
|
resourceService.addResources(createResourceListDTO(w2)));
|
||||||
|
assertTrue(
|
||||||
|
workerDAO.findByFirstNameSecondNameAndNifAnotherTransaction(
|
||||||
|
w2.firstName, w2.surname, w2.nif).size() == 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddResourcesWithDuplicateResourcesBeingImported()
|
||||||
|
throws InstanceNotFoundException {
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Test. */
|
||||||
|
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
|
||||||
|
resourceService.addResources(createResourceListDTO(m1, m2, w1, w2)).
|
||||||
|
instanceConstraintViolationsList;
|
||||||
|
|
||||||
|
assertTrue(instanceConstraintViolationsList.size() == 2);
|
||||||
|
assertTrue(instanceConstraintViolationsList.get(0).
|
||||||
|
constraintViolations.size() == 1);
|
||||||
|
assertTrue(instanceConstraintViolationsList.get(1).
|
||||||
|
constraintViolations.size() == 1);
|
||||||
|
machineDAO.findUniqueByCode(m1.code);
|
||||||
|
assertTrue(
|
||||||
|
workerDAO.findByFirstNameSecondNameAndNif(
|
||||||
|
w1.firstName, w1.surname, w1.nif.trim()).size() == 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@NotTransactional
|
@NotTransactional
|
||||||
public void testAddResourceWithCriterionSatisfactions()
|
public void testAddResourceWithCriterionSatisfactions()
|
||||||
|
|
@ -165,54 +238,6 @@ public class ResourceServiceTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@NotTransactional
|
|
||||||
public void AddResourceWithCriterionSatisfactionsWithIncorrectNames() {
|
|
||||||
|
|
||||||
/* Create a criterion type. */
|
|
||||||
CriterionType ct = createCriterionType();
|
|
||||||
|
|
||||||
/* Create a machine DTO. */
|
|
||||||
MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc");
|
|
||||||
|
|
||||||
/* Test. */
|
|
||||||
machineDTO.criterionSatisfactions.add( // Non-existent criterion type.
|
|
||||||
new CriterionSatisfactionDTO(ct.getName() + 'X' , "c1",
|
|
||||||
Calendar.getInstance().getTime(), null));
|
|
||||||
assertOneConstraintViolation(
|
|
||||||
resourceService.addResources(createResourceListDTO(machineDTO)));
|
|
||||||
assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction(
|
|
||||||
machineDTO.code));
|
|
||||||
|
|
||||||
machineDTO.criterionSatisfactions.clear();
|
|
||||||
machineDTO.criterionSatisfactions.add( // Non-existent criterion.
|
|
||||||
new CriterionSatisfactionDTO(ct.getName() , "c1" + 'X',
|
|
||||||
Calendar.getInstance().getTime(), null));
|
|
||||||
assertOneConstraintViolation(
|
|
||||||
resourceService.addResources(createResourceListDTO(machineDTO)));
|
|
||||||
assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction(
|
|
||||||
machineDTO.code));
|
|
||||||
|
|
||||||
machineDTO.criterionSatisfactions.clear();
|
|
||||||
machineDTO.criterionSatisfactions.add( // Criterion type null.
|
|
||||||
new CriterionSatisfactionDTO(null , "c1",
|
|
||||||
Calendar.getInstance().getTime(), null));
|
|
||||||
assertOneConstraintViolation(
|
|
||||||
resourceService.addResources(createResourceListDTO(machineDTO)));
|
|
||||||
assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction(
|
|
||||||
machineDTO.code));
|
|
||||||
|
|
||||||
machineDTO.criterionSatisfactions.clear();
|
|
||||||
machineDTO.criterionSatisfactions.add( // Criterion null.
|
|
||||||
new CriterionSatisfactionDTO(ct.getName() , null,
|
|
||||||
Calendar.getInstance().getTime(), null));
|
|
||||||
assertOneConstraintViolation(
|
|
||||||
resourceService.addResources(createResourceListDTO(machineDTO)));
|
|
||||||
assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction(
|
|
||||||
machineDTO.code));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@NotTransactional
|
@NotTransactional
|
||||||
public void testAddResourceWithCriterionSatisfactionsWithoutStartDate() {
|
public void testAddResourceWithCriterionSatisfactionsWithoutStartDate() {
|
||||||
|
|
@ -317,49 +342,6 @@ public class ResourceServiceTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@NotTransactional
|
|
||||||
public void createMachineWithExistingCode()
|
|
||||||
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 createWorkerWithExistingFirstNameSurnameAndNif() {
|
|
||||||
|
|
||||||
/* Create a worker. */
|
|
||||||
Worker w1 = Worker.createUnvalidated(getUniqueName(), "surname", "nif");
|
|
||||||
saveResource(w1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a worker DTO with the same first name, surname, and nif as
|
|
||||||
* the previous one.
|
|
||||||
*/
|
|
||||||
WorkerDTO w2 = new WorkerDTO(w1.getFirstName(), w1.getSurname(),
|
|
||||||
w1.getNif());
|
|
||||||
|
|
||||||
/* Test. */
|
|
||||||
assertOneConstraintViolation(
|
|
||||||
resourceService.addResources(createResourceListDTO(w2)));
|
|
||||||
assertTrue(
|
|
||||||
workerDAO.findByFirstNameSecondNameAndNifAnotherTransaction(
|
|
||||||
w2.firstName, w2.surname, w2.nif).size() == 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private CriterionType createCriterionType() {
|
private CriterionType createCriterionType() {
|
||||||
return createCriterionType(ResourceEnum.RESOURCE);
|
return createCriterionType(ResourceEnum.RESOURCE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@
|
||||||
</criterion-satisfaction-list>
|
</criterion-satisfaction-list>
|
||||||
</machine>
|
</machine>
|
||||||
|
|
||||||
|
<!-- Another machine is being imported with the same code. -->
|
||||||
|
<machine code="m1" name="m3-name" description="m3-desc"/>
|
||||||
|
|
||||||
<!-- *** Workers *** -->
|
<!-- *** Workers *** -->
|
||||||
|
|
||||||
<!-- OK -->
|
<!-- OK -->
|
||||||
|
|
@ -94,4 +97,8 @@
|
||||||
</criterion-satisfaction-list>
|
</criterion-satisfaction-list>
|
||||||
</worker>
|
</worker>
|
||||||
|
|
||||||
|
<!-- Another worker is being imported with the same first name, surname,
|
||||||
|
and nif. -->
|
||||||
|
<worker first-name="w1-firstName" surname="w1-surname" nif="w1-nif"/>
|
||||||
|
|
||||||
</resource-list>
|
</resource-list>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue