diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/IntegrationEntity.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/IntegrationEntity.java
new file mode 100644
index 000000000..984ccdd32
--- /dev/null
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/IntegrationEntity.java
@@ -0,0 +1,152 @@
+/*
+ * This file is part of ###PROJECT_NAME###
+ *
+ * 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.business.common;
+
+import java.util.UUID;
+
+import org.apache.commons.lang.StringUtils;
+import org.hibernate.validator.AssertTrue;
+import org.hibernate.validator.NotEmpty;
+import org.navalplanner.business.common.daos.IIntegrationEntityDAO;
+import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
+
+/**
+ * Base class for all entities to be sent/received to/from other applications.
+ * These entities have a "code" attribute, which unlike "id" is unique among
+ * the applications to be integrated ("id" is only unique inside
+ * "navalplanner").
+ *
+ * @author Fernando Bellas Permuy
+ */
+public abstract class IntegrationEntity extends BaseEntity {
+
+ private String code;
+
+ @NotEmpty(message="code not specified")
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ /**
+ * This creation method must be used when we want to create an instance
+ * specifying a specific code (e.g. provided by the end-user or an external
+ * application).
+ */
+ protected static T create(
+ T integrationEntity, String code) {
+
+ BaseEntity.create(integrationEntity);
+ integrationEntity.code = code;
+
+ return integrationEntity;
+
+ }
+
+ /**
+ * This creation method must be used when we want the creation method to
+ * automatically generate a code. This is a Template method which delegates
+ * code generation by calling on generateCode().
+ */
+ protected static T create(
+ T integrationEntity) {
+
+ BaseEntity.create(integrationEntity);
+ integrationEntity.code = generateCode();
+
+ return integrationEntity;
+
+ }
+
+ /**
+ * This method is called by create(IntegrationEntity). It
+ * returns an unique String UUID. The current implementation is good enough
+ * for entities created in test classes. However, concrete classes
+ * interested in automatically generating descriptive identifiers when
+ * calling create(IntegrationEntity), will probably redefine
+ * this method.
+ */
+ protected static String generateCode() {
+ return UUID.randomUUID().toString();
+ }
+
+ /**
+ * It checks if there exists another integration entity of the same type
+ * with the same code. This method is a Template method that calls on
+ * the private method findIntegrationEntityDAO, which in turn
+ * calls on the abstract method getIntegrationEntityDAO().
+ */
+ @AssertTrue(message="code is already being used")
+ public boolean checkConstraintUniqueCode() {
+
+ /* Check if it makes sense to check the constraint .*/
+ if (!iCodeSpecified()) {
+ return true;
+ }
+
+ /* Check the constraint. */
+ IIntegrationEntityDAO extends IntegrationEntity>
+ integrationEntityDAO = findIntegrationEntityDAO();
+
+ if (isNewObject()) {
+ return !integrationEntityDAO.existsByCodeAnotherTransaction(code);
+ } else {
+ try {
+ IntegrationEntity entity =
+ integrationEntityDAO.findByCodeAnotherTransaction(code);
+ return entity.getId().equals(getId());
+ } catch (InstanceNotFoundException e) {
+ return true;
+ }
+ }
+
+ }
+
+ /**
+ * It returns the DAO of this entity.
+ */
+ protected abstract IIntegrationEntityDAO extends IntegrationEntity>
+ getIntegrationEntityDAO();
+
+ private IIntegrationEntityDAO extends IntegrationEntity>
+ findIntegrationEntityDAO() {
+
+ IIntegrationEntityDAO extends IntegrationEntity>
+ integrationEntityDAO = getIntegrationEntityDAO();
+
+ if (!integrationEntityDAO.getEntityClass().equals(this.getClass())) {
+ throw new RuntimeException(this.getClass().getName() + "::" +
+ "getIntegrationEntityDAO returns an incompatible " +
+ "DAO: " + integrationEntityDAO.getClass().getName());
+ } else {
+ return integrationEntityDAO;
+ }
+
+ }
+
+ private boolean iCodeSpecified() {
+ return !StringUtils.isBlank(code);
+ }
+
+}
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/GenericDAOHibernate.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/GenericDAOHibernate.java
index d8c30de54..b65992100 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/GenericDAOHibernate.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/GenericDAOHibernate.java
@@ -79,6 +79,10 @@ public class GenericDAOHibernate getEntityClass() {
+ return entityClass;
+ }
+
/**
* It's necessary to save and validate later.
*
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IGenericDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IGenericDAO.java
index 27b8c1de5..06f52bebb 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IGenericDAO.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IGenericDAO.java
@@ -39,6 +39,8 @@ import org.springframework.dao.OptimisticLockingFailureException;
*/
public interface IGenericDAO {
+ public Class getEntityClass();
+
/**
* It inserts the object passed as a parameter in the ORM session, planning
* it for updating (even though it is not modified before or after the call
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IIntegrationEntityDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IIntegrationEntityDAO.java
new file mode 100644
index 000000000..f6f88ce69
--- /dev/null
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IIntegrationEntityDAO.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of ###PROJECT_NAME###
+ *
+ * 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.business.common.daos;
+
+import org.navalplanner.business.common.IntegrationEntity;
+import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
+
+/**
+ * Common DAO interface for all entities used in application integration. All
+ * DAO interfaces of entities used in application integration must extend from
+ * this interface.
+ *
+ * @author Fernando Bellas Permuy
+ */
+public interface IIntegrationEntityDAO
+ extends IGenericDAO {
+
+ public boolean existsByCode(String code);
+
+ public boolean existsByCodeAnotherTransaction(String code);
+
+ public E findByCode(String code) throws InstanceNotFoundException;
+
+ public E findByCodeAnotherTransaction(String code)
+ throws InstanceNotFoundException;
+
+ public E findExistingEntityByCode(String code);
+
+}
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
new file mode 100644
index 000000000..592d772b8
--- /dev/null
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IntegrationEntityDAO.java
@@ -0,0 +1,92 @@
+/*
+ * This file is part of ###PROJECT_NAME###
+ *
+ * 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.business.common.daos;
+
+import org.hibernate.criterion.Restrictions;
+import org.navalplanner.business.common.IntegrationEntity;
+import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Default implementation of IIntegrationEntityDAO. DAOs of
+ * entities used in application integration may extend from this interface.
+ *
+ * @author Fernando Bellas Permuy
+ */
+public class IntegrationEntityDAO
+ extends GenericDAOHibernate implements IIntegrationEntityDAO {
+
+ @Override
+ public boolean existsByCode(String code) {
+
+ try {
+ findByCode(code);
+ return true;
+ } catch (InstanceNotFoundException e) {
+ return false;
+ }
+
+ }
+
+ @Override
+ @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
+ public boolean existsByCodeAnotherTransaction(String code) {
+ return existsByCode(code);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public E findByCode(String code) throws InstanceNotFoundException {
+
+ E entity = (E) getSession().createCriteria(getEntityClass()).add(
+ Restrictions.eq("code", code).ignoreCase()).uniqueResult();
+
+ if (entity == null) {
+ throw new InstanceNotFoundException(
+ code, getEntityClass().getName());
+ } else {
+ return entity;
+ }
+
+ }
+
+ @Override
+ @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
+ public E findByCodeAnotherTransaction(String code)
+ throws InstanceNotFoundException {
+
+ return findByCode(code);
+
+ }
+
+ @Override
+ public E findExistingEntityByCode(String code) {
+
+ try {
+ return findByCode(code);
+ } catch (InstanceNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+}
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java
index 1e7a73c6f..750bc8e28 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionDAO.java
@@ -27,7 +27,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.Criterion;
import org.navalplanner.business.resources.entities.ICriterionType;
@@ -46,8 +46,8 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Repository
@Scope(BeanDefinition.SCOPE_SINGLETON)
-public class CriterionDAO extends GenericDAOHibernate
- implements ICriterionDAO {
+public class CriterionDAO extends IntegrationEntityDAO
+ implements ICriterionDAO {
private static final Log log = LogFactory.getLog(CriterionDAO.class);
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionTypeDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionTypeDAO.java
index 1ad2b38ca..66fa16edb 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionTypeDAO.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/CriterionTypeDAO.java
@@ -26,7 +26,7 @@ import java.util.List;
import org.apache.commons.lang.Validate;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
-import org.navalplanner.business.common.daos.GenericDAOHibernate;
+import org.navalplanner.business.common.daos.IntegrationEntityDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.ResourceEnum;
@@ -41,8 +41,8 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Component
-public class CriterionTypeDAO extends GenericDAOHibernate
- implements ICriterionTypeDAO {
+public class CriterionTypeDAO extends IntegrationEntityDAO
+ implements ICriterionTypeDAO {
@Override
public List findByName(CriterionType criterionType) {
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java
index ce2447293..0c346fedd 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionDAO.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.Criterion;
import org.navalplanner.business.resources.entities.ICriterionType;
@@ -33,8 +33,9 @@ import org.springframework.transaction.annotation.Transactional;
*
* @author Óscar González Fernández
* @author Diego Pino García
+ * @author Fernando Bellas Permuy
*/
-public interface ICriterionDAO extends IGenericDAO {
+public interface ICriterionDAO extends IIntegrationEntityDAO {
public void removeByNameAndType(Criterion criterion);
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionTypeDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionTypeDAO.java
index a9a1689aa..7664c8cdf 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionTypeDAO.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/daos/ICriterionTypeDAO.java
@@ -23,7 +23,7 @@ package org.navalplanner.business.resources.daos;
import java.util.Collection;
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.CriterionType;
import org.navalplanner.business.resources.entities.ResourceEnum;
@@ -33,7 +33,8 @@ import org.navalplanner.business.resources.entities.ResourceEnum;
* @author Diego Pino Garcia
* @author Fernando Bellas Permuy
*/
-public interface ICriterionTypeDAO extends IGenericDAO {
+public interface ICriterionTypeDAO
+ extends IIntegrationEntityDAO {
CriterionType findUniqueByName(String name)
throws InstanceNotFoundException;
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java
index d6fb55f83..1e56a7d7e 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java
@@ -32,20 +32,22 @@ import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
-import org.navalplanner.business.common.BaseEntity;
+import org.navalplanner.business.common.IntegrationEntity;
+import org.navalplanner.business.common.Registry;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
+import org.navalplanner.business.resources.daos.ICriterionDAO;
/**
* A criterion stored in the database
* @author Óscar González Fernández
* @author Fernando Bellas Permuy
*/
-public class Criterion extends BaseEntity implements ICriterion {
+public class Criterion extends IntegrationEntity implements ICriterion {
- public static Criterion createUnvalidated(String name, CriterionType type,
- Criterion parent, boolean active) {
+ public static Criterion createUnvalidated(String code, String name,
+ CriterionType type, Criterion parent, boolean active) {
- Criterion criterion = create(new Criterion());
+ Criterion criterion = create(new Criterion(), code);
criterion.name = name;
criterion.type = type;
@@ -57,26 +59,19 @@ public class Criterion extends BaseEntity implements ICriterion {
}
public static Criterion create(CriterionType type) {
- Criterion criterion = new Criterion(type);
- criterion.setNewObject(true);
- return criterion;
+ return create(new Criterion(type));
}
public static Criterion create(String name, CriterionType type) {
- Criterion criterion = new Criterion(name, type);
- criterion.setNewObject(true);
- return criterion;
+ return create(new Criterion(name, type));
}
- @NotEmpty(message="criterion name not specified")
private String name;
- @NotNull(message="criterion type not specified")
private CriterionType type;
private Criterion parent = null;
- @Valid
private Set children = new HashSet();
private boolean active = true;
@@ -127,6 +122,7 @@ public class Criterion extends BaseEntity implements ICriterion {
Interval.range(start, end)).result().isEmpty();
}
+ @NotEmpty(message="criterion name not specified")
public String getName() {
return name;
}
@@ -135,6 +131,7 @@ public class Criterion extends BaseEntity implements ICriterion {
this.name = name;
}
+ @NotNull(message="criterion type not specified")
public CriterionType getType() {
return type;
}
@@ -163,6 +160,7 @@ public class Criterion extends BaseEntity implements ICriterion {
this.parent = parent;
}
+ @Valid
public Set getChildren() {
return children;
}
@@ -213,4 +211,9 @@ public class Criterion extends BaseEntity implements ICriterion {
criterionRequirement.setCriterion(this);
this.criterionRequirements.add(criterionRequirement);
}
+
+ @Override
+ protected ICriterionDAO getIntegrationEntityDAO() {
+ return Registry.getCriterionDAO();
+ }
}
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java
index 95113ffea..461dd948e 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java
@@ -28,7 +28,7 @@ import org.apache.commons.lang.builder.EqualsBuilder;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.Valid;
-import org.navalplanner.business.common.BaseEntity;
+import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
@@ -41,22 +41,20 @@ import org.springframework.stereotype.Component;
* @author Fernando Bellas Permuy
*/
@Component
-public class CriterionType extends BaseEntity implements
+public class CriterionType extends IntegrationEntity implements
ICriterionType {
public static CriterionType create() {
- CriterionType criterionType = new CriterionType();
- criterionType.setNewObject(true);
- return criterionType;
+ return create(new CriterionType());
}
- public static CriterionType createUnvalidated(String name,
+ public static CriterionType createUnvalidated(String code, String name,
String description, Boolean allowHierarchy,
Boolean allowSimultaneousCriterionsPerResource, Boolean enabled,
ResourceEnum resource) {
- CriterionType criterionType = create(new CriterionType());
+ CriterionType criterionType = create(new CriterionType(), code);
criterionType.name = name;
criterionType.description = description;
@@ -71,21 +69,18 @@ public class CriterionType extends BaseEntity implements
}
public static CriterionType create(String name,String description) {
- CriterionType criterionType = new CriterionType(name,description);
- criterionType.setNewObject(true);
- return criterionType;
+ return create(new CriterionType(name,description));
}
public static CriterionType create(String name,String description,
boolean allowHierarchy,boolean allowSimultaneousCriterionsPerResource,
boolean enabled,ResourceEnum resource) {
- CriterionType criterionType = new CriterionType(name,description, allowHierarchy,
- allowSimultaneousCriterionsPerResource,enabled,resource);
- criterionType.setNewObject(true);
- return criterionType;
+
+ return create(new CriterionType(name,description, allowHierarchy,
+ allowSimultaneousCriterionsPerResource,enabled,resource));
+
}
- @NotEmpty(message="criterion type name not specified")
private String name;
private String description;
@@ -98,7 +93,6 @@ public class CriterionType extends BaseEntity implements
private ResourceEnum resource = ResourceEnum.getDefault();
- @Valid
private Set criterions = new HashSet();
private int numCriterions;
@@ -146,6 +140,7 @@ public class CriterionType extends BaseEntity implements
}
@Override
+ @NotEmpty(message="criterion type name not specified")
public String getName() {
return name;
}
@@ -154,6 +149,7 @@ public class CriterionType extends BaseEntity implements
this.name = name;
}
+ @Valid
public Set getCriterions() {
return criterions;
}
@@ -378,4 +374,10 @@ public class CriterionType extends BaseEntity implements
return !StringUtils.isBlank(name);
}
+
+ @Override
+ protected ICriterionTypeDAO getIntegrationEntityDAO() {
+ return Registry.getCriterionTypeDAO();
+ }
+
}
diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml
index 4681319ab..cdabb89b8 100644
--- a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml
+++ b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml
@@ -66,6 +66,7 @@
+
@@ -110,6 +111,7 @@
+
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 728497806..c0d90dbbb 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
@@ -35,16 +35,33 @@ import javax.xml.bind.annotation.XmlElement;
*/
public class InstanceConstraintViolationsDTO {
+ public final static String NUM_ITEM_ATTRIBUTE_NAME = "num-item";
+ public final static String CODE_ATTRIBUTE_NAME =
+ IntegrationEntityDTO.CODE_ATTRIBUTE_NAME;
+ public final static String ENTITY_TYPE_ATTRIBUTE_NAME = "entity-type";
+
+ @Deprecated
public final static String INSTANCE_ID_ATTRIBUTE_NAME = "instance-id";
+ @Deprecated
@XmlAttribute(name=INSTANCE_ID_ATTRIBUTE_NAME)
public String instanceId;
+ @XmlAttribute(name=NUM_ITEM_ATTRIBUTE_NAME)
+ public Long numItem;
+
+ @XmlAttribute(name=CODE_ATTRIBUTE_NAME)
+ public String code;
+
+ @XmlAttribute(name=ENTITY_TYPE_ATTRIBUTE_NAME)
+ public String entityType;
+
@XmlElement(name="constraint-violation")
public List constraintViolations;
public InstanceConstraintViolationsDTO() {}
+ @Deprecated
public InstanceConstraintViolationsDTO(String instanceId,
List constraintViolations) {
@@ -53,6 +70,18 @@ public class InstanceConstraintViolationsDTO {
}
+ public InstanceConstraintViolationsDTO(
+ InstanceConstraintViolationsDTOId instanceId,
+ List constraintViolations) {
+
+ this.numItem = instanceId.getNumItem();
+ this.code = instanceId.getCode();
+ this.entityType = instanceId.getEntityType();
+ this.constraintViolations = constraintViolations;
+
+ }
+
+ @Deprecated
public static InstanceConstraintViolationsDTO create(String instanceId,
String message) {
@@ -66,6 +95,19 @@ public class InstanceConstraintViolationsDTO {
}
+ public static InstanceConstraintViolationsDTO create(
+ InstanceConstraintViolationsDTOId instanceId, String message) {
+
+ List constraintViolations =
+ new ArrayList();
+
+ constraintViolations.add(new ConstraintViolationDTO(null, message));
+
+ return new InstanceConstraintViolationsDTO(instanceId,
+ constraintViolations);
+
+ }
+
@Override
public String toString() {
@@ -75,6 +117,12 @@ public class InstanceConstraintViolationsDTO {
printWriter.println("** " + INSTANCE_ID_ATTRIBUTE_NAME + " = " +
instanceId + " **");
+ printWriter.println("** " +
+ NUM_ITEM_ATTRIBUTE_NAME + " = " + numItem + " - " +
+ CODE_ATTRIBUTE_NAME + " = " + code + " - " +
+ ENTITY_TYPE_ATTRIBUTE_NAME + " = " + entityType +
+ " **");
+
for (ConstraintViolationDTO i : constraintViolations) {
printWriter.println(i);
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InstanceConstraintViolationsDTOId.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InstanceConstraintViolationsDTOId.java
new file mode 100644
index 000000000..08ebed23a
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/InstanceConstraintViolationsDTOId.java
@@ -0,0 +1,55 @@
+/*
+ * This file is part of ###PROJECT_NAME###
+ *
+ * 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;
+
+/**
+ * Identifier for an instance causing a list of constraint violations.
+ *
+ * @author Fernando Bellas Permuy
+ */
+public class InstanceConstraintViolationsDTOId {
+
+ private Long numItem;
+ private String code;
+ private String entityType;
+
+ public InstanceConstraintViolationsDTOId(Long numItem, String code,
+ String entityType) {
+
+ this.numItem = numItem;
+ this.code = code;
+ this.entityType = entityType;
+
+ }
+
+ public Long getNumItem() {
+ return numItem;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/IntegrationEntityDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/IntegrationEntityDTO.java
new file mode 100644
index 000000000..b37432465
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/api/IntegrationEntityDTO.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of ###PROJECT_NAME###
+ *
+ * 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.util.UUID;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * DTO for IntegrationEntity. All DTOs corresponding to entities
+ * to be used in application integration must extend from this DTO.
+ *
+ * @author Fernando Bellas Permuy
+ */
+public abstract class IntegrationEntityDTO {
+
+ public final static String CODE_ATTRIBUTE_NAME = "code";
+
+ @XmlAttribute(name=CODE_ATTRIBUTE_NAME)
+ public String code;
+
+ public IntegrationEntityDTO() {}
+
+ public IntegrationEntityDTO(String code) {
+ this.code = code;
+ }
+
+
+ /**
+ * It returns the String to use in
+ * InstanceConstraintViolationsDTOId.entityType.
+ */
+ public abstract String getEntityType();
+
+ /**
+ * This method is useful to implement constructors (in subclasses) that
+ * automatically generate a unique code. Such constructors are useful for
+ * the implementation of test cases that add new instances (such instances
+ * will have a unique code).
+ */
+ protected static String generateCode() {
+ return UUID.randomUUID().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 7640ea454..e432563c4 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
@@ -26,6 +26,7 @@ import java.util.List;
import org.hibernate.validator.InvalidValue;
import org.navalplanner.ws.common.api.ConstraintViolationDTO;
import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO;
+import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTOId;
/**
* Converter for constraint violations.
@@ -58,6 +59,7 @@ public class ConstraintViolationConverter {
}
+ @Deprecated
public final static InstanceConstraintViolationsDTO toDTO(String instanceId,
InvalidValue[] invalidValues) {
@@ -73,4 +75,20 @@ public class ConstraintViolationConverter {
}
+ public final static InstanceConstraintViolationsDTO toDTO(
+ InstanceConstraintViolationsDTOId instanceId,
+ InvalidValue[] invalidValues) {
+
+ List constraintViolationDTOs =
+ new ArrayList();
+
+ for (InvalidValue i : invalidValues) {
+ constraintViolationDTOs.add(toDTO(i));
+ }
+
+ return new InstanceConstraintViolationsDTO(instanceId,
+ constraintViolationDTOs);
+
+ }
+
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/Util.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/Util.java
index 06fbd220e..6b8581e56 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/Util.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/common/impl/Util.java
@@ -25,14 +25,28 @@ import java.io.StringWriter;
import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.jaxrs.client.WebClient;
+import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTOId;
+import org.navalplanner.ws.common.api.IntegrationEntityDTO;
/**
* Utilities class related with web service.
*
* @author Manuel Rego Casasnovas
+ * @author Fernando Bellas Permuy
*/
public class Util {
+ public static InstanceConstraintViolationsDTOId
+ generateInstanceConstraintViolationsDTOId(Long numItem,
+ IntegrationEntityDTO integrationEntityDTO) {
+
+ return new InstanceConstraintViolationsDTOId(numItem,
+ integrationEntityDTO.code,
+ integrationEntityDTO.getEntityType());
+
+ }
+
+ @Deprecated
public static String generateInstanceId(int instanceNumber,
String instanceIdentifier) {
String instanceId = instanceNumber + "";
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionDTO.java
index 798c9866b..56c189fc5 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionDTO.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionDTO.java
@@ -27,12 +27,16 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
+import org.navalplanner.ws.common.api.IntegrationEntityDTO;
+
/**
* DTO for Criterion entity.
*
* @author Fernando Bellas Permuy
*/
-public class CriterionDTO {
+public class CriterionDTO extends IntegrationEntityDTO {
+
+ public final static String ENTITY_TYPE = "criterion";
@XmlAttribute
public String name;
@@ -46,13 +50,31 @@ public class CriterionDTO {
public CriterionDTO() {}
- public CriterionDTO(String name, boolean active,
+ public CriterionDTO(String code, String name, boolean active,
List children) {
+ super(code);
this.name = name;
this.active = active;
this.children = children;
}
+ /**
+ * This constructor automatically generates a unique code. It is intended
+ * to facilitate the implementation of test cases that add new instances
+ * (such instances will have a unique code).
+ */
+ public CriterionDTO(String name, boolean active,
+ List children) {
+
+ this(generateCode(), name, active, children);
+
+ }
+
+ @Override
+ public String getEntityType() {
+ return ENTITY_TYPE;
+ }
+
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionTypeDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionTypeDTO.java
index 2b8e7211f..eed20c505 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionTypeDTO.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/api/CriterionTypeDTO.java
@@ -27,6 +27,7 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
+import org.navalplanner.ws.common.api.IntegrationEntityDTO;
import org.navalplanner.ws.common.api.ResourceEnumDTO;
/**
@@ -34,7 +35,9 @@ import org.navalplanner.ws.common.api.ResourceEnumDTO;
*
* @author Fernando Bellas Permuy
*/
-public class CriterionTypeDTO {
+public class CriterionTypeDTO extends IntegrationEntityDTO {
+
+ public final static String ENTITY_TYPE = "criterion-type";
@XmlAttribute
public String name;
@@ -60,11 +63,12 @@ public class CriterionTypeDTO {
public CriterionTypeDTO() {}
- public CriterionTypeDTO(String name, String description,
+ public CriterionTypeDTO(String code, String name, String description,
boolean allowHierarchy, boolean allowSimultaneousCriterionsPerResource,
boolean enabled, ResourceEnumDTO resource,
List criterions) {
+ super(code);
this.name = name;
this.description = description;
this.allowHierarchy = allowHierarchy;
@@ -76,4 +80,25 @@ public class CriterionTypeDTO {
}
+ /**
+ * This constructor automatically generates a unique code. It is intended
+ * to facilitate the implementation of test cases that add new instances
+ * (such instances will have a unique code).
+ */
+ public CriterionTypeDTO(String name, String description,
+ boolean allowHierarchy, boolean allowSimultaneousCriterionsPerResource,
+ boolean enabled, ResourceEnumDTO resource,
+ List criterions) {
+
+ this(generateCode(), name, description, allowHierarchy,
+ allowSimultaneousCriterionsPerResource, enabled, resource,
+ criterions);
+
+ }
+
+ @Override
+ public String getEntityType() {
+ return ENTITY_TYPE;
+ }
+
}
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 00ef6d99b..f8924edfc 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
@@ -70,6 +70,7 @@ public final class CriterionConverter {
}
return new CriterionTypeDTO(
+ criterionType.getCode(),
criterionType.getName(),
criterionType.getDescription(),
criterionType.allowHierarchy(),
@@ -93,8 +94,8 @@ public final class CriterionConverter {
childrenDTOs = null;
}
- return new CriterionDTO(criterion.getName(), criterion.isActive(),
- childrenDTOs);
+ return new CriterionDTO(criterion.getCode(), criterion.getName(),
+ criterion.isActive(), childrenDTOs);
}
@@ -102,6 +103,7 @@ public final class CriterionConverter {
CriterionTypeDTO criterionTypeDTO) {
CriterionType criterionType = CriterionType.createUnvalidated(
+ StringUtils.trim(criterionTypeDTO.code),
StringUtils.trim(criterionTypeDTO.name),
StringUtils.trim(criterionTypeDTO.description),
criterionTypeDTO.allowHierarchy,
@@ -139,6 +141,7 @@ public final class CriterionConverter {
Criterion criterionParent) {
Criterion criterion = Criterion.createUnvalidated(
+ StringUtils.trim(childDTO.code),
StringUtils.trim(childDTO.name),
criterionType, criterionParent, childDTO.active);
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionServiceREST.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionServiceREST.java
index 808163236..4f5f52a70 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionServiceREST.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/criterion/impl/CriterionServiceREST.java
@@ -76,7 +76,7 @@ public class CriterionServiceREST implements ICriterionService {
List instanceConstraintViolationsList =
new ArrayList();
- int instanceNumber = 1;
+ Long numItem = new Long(1);
Set criterionTypeNames = new HashSet();
/* Process criterion types. */
@@ -98,8 +98,8 @@ public class CriterionServiceREST implements ICriterionService {
instanceConstraintViolationsDTO =
InstanceConstraintViolationsDTO.create(
- Util.generateInstanceId(instanceNumber,
- criterionTypeDTO.name),
+ Util.generateInstanceConstraintViolationsDTOId(numItem,
+ criterionTypeDTO),
_("criterion type name is used by another criterion " +
"type being imported"));
@@ -138,8 +138,8 @@ public class CriterionServiceREST implements ICriterionService {
} catch (ValidationException e) {
instanceConstraintViolationsDTO =
ConstraintViolationConverter.toDTO(
- Util.generateInstanceId(instanceNumber,
- criterionTypeDTO.name),
+ Util.generateInstanceConstraintViolationsDTOId(
+ numItem, criterionTypeDTO),
e.getInvalidValues());
}
@@ -151,7 +151,7 @@ public class CriterionServiceREST implements ICriterionService {
instanceConstraintViolationsDTO);
}
- instanceNumber++;
+ numItem++;
}
diff --git a/scripts/rest-clients/criterion-types-sample.xml b/scripts/rest-clients/criterion-types-sample.xml
index 4006f58f3..b270cf83d 100644
--- a/scripts/rest-clients/criterion-types-sample.xml
+++ b/scripts/rest-clients/criterion-types-sample.xml
@@ -3,87 +3,87 @@
-
-
-
+
+
-
+
-
-
+
+
-
+
-
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
-
+
-
-
+
+
-
-
+
+
-
+
@@ -92,19 +92,19 @@
-
-
+
-
-
+
+